text: purge the SDF renderer, RIP
@ -2123,56 +2123,6 @@ int main(int argc, char * argv[]) {
|
||||
TRACE("pex bound? %d", server);
|
||||
yg->server = server;
|
||||
|
||||
TRACE("Loading fonts...");
|
||||
{
|
||||
#define FONT_COUNT 8
|
||||
sprite_t _font_data[FONT_COUNT];
|
||||
|
||||
load_sprite(&_font_data[0], "/usr/share/fonts/sdf_thin.sdf");
|
||||
load_sprite(&_font_data[1], "/usr/share/fonts/sdf_bold.sdf");
|
||||
load_sprite(&_font_data[2], "/usr/share/fonts/sdf_mono.sdf");
|
||||
load_sprite(&_font_data[3], "/usr/share/fonts/sdf_mono_bold.sdf");
|
||||
load_sprite(&_font_data[4], "/usr/share/fonts/sdf_mono_oblique.sdf");
|
||||
load_sprite(&_font_data[5], "/usr/share/fonts/sdf_mono_bold_oblique.sdf");
|
||||
load_sprite(&_font_data[6], "/usr/share/fonts/sdf_oblique.sdf");
|
||||
load_sprite(&_font_data[7], "/usr/share/fonts/sdf_bold_oblique.sdf");
|
||||
|
||||
TRACE(" Data loaded...");
|
||||
|
||||
size_t font_data_size = sizeof(unsigned int) * (1 + FONT_COUNT * 3);
|
||||
for (int i = 0; i < FONT_COUNT; ++i) {
|
||||
font_data_size += 4 * _font_data[i].width * _font_data[i].height;
|
||||
}
|
||||
|
||||
TRACE(" Size calculated: %d", font_data_size);
|
||||
|
||||
char tmp[100];
|
||||
sprintf(tmp, "sys.%s.fonts", yg->server_ident);
|
||||
size_t s = font_data_size;
|
||||
char * font = shm_obtain(tmp, &s);
|
||||
assert((s >= font_data_size) && "Font server failure.");
|
||||
|
||||
uint32_t * data = (uint32_t *)font;
|
||||
data[0] = FONT_COUNT;
|
||||
|
||||
data[1] = _font_data[0].width;
|
||||
data[2] = _font_data[0].height;
|
||||
data[3] = (FONT_COUNT * 3 + 1) * sizeof(unsigned int);
|
||||
memcpy(&font[data[3]], _font_data[0].bitmap, _font_data[0].width * _font_data[0].height * 4);
|
||||
free(_font_data[0].bitmap);
|
||||
|
||||
for (int i = 1; i < FONT_COUNT; ++i) {
|
||||
TRACE(" Loaded %d font(s)... %d %d %d", i, data[(i - 1) * 3 + 2], data[(i - 1) * 3 + 1], data[(i - 1) * 3 + 3]);
|
||||
data[i * 3 + 1] = _font_data[i].width;
|
||||
data[i * 3 + 2] = _font_data[i].height;
|
||||
data[i * 3 + 3] = data[(i - 1) * 3 + 3] + data[(i - 1) * 3 + 2] * data[(i - 1) * 3 + 1] * 4;
|
||||
memcpy(&font[data[i * 3 + 3]], _font_data[i].bitmap, _font_data[i].width * _font_data[i].height * 4);
|
||||
free(_font_data[i].bitmap);
|
||||
}
|
||||
|
||||
TRACE("Done loading fonts.");
|
||||
}
|
||||
|
||||
TRACE("Loading sprites...");
|
||||
#define MOUSE_DIR "/usr/share/cursor/"
|
||||
load_sprite(&yg->mouse_sprite, MOUSE_DIR "normal.png");
|
||||
|
@ -24,7 +24,7 @@
|
||||
#include <toaru/yutani.h>
|
||||
#include <toaru/auth.h>
|
||||
#include <toaru/confreader.h>
|
||||
#include <toaru/sdf.h>
|
||||
#include <toaru/text.h>
|
||||
|
||||
#include <toaru/trace.h>
|
||||
#define TRACE_APP_NAME "glogin-provider"
|
||||
@ -57,6 +57,8 @@ static int BOX_COLOR_B=0;
|
||||
static int BOX_COLOR_A=127;
|
||||
static char * WALLPAPER = "/usr/share/wallpaper.jpg";
|
||||
static char * LOGO = "/usr/share/logo_login.png";
|
||||
static struct TT_Font * tt_font_thin = NULL;
|
||||
static struct TT_Font * tt_font_bold = NULL;
|
||||
|
||||
#define TEXTBOX_INTERIOR_LEFT 4
|
||||
#define EXTRA_TEXT_OFFSET 15
|
||||
@ -145,15 +147,16 @@ void draw_text_box(gfx_context_t * ctx, struct text_box * tb) {
|
||||
} else if (tb->is_password) {
|
||||
strcpy(password_circles, "");
|
||||
for (unsigned int i = 0; i < strlen(tb->buffer); ++i) {
|
||||
strcat(password_circles, "\007");
|
||||
strcat(password_circles, "●");
|
||||
}
|
||||
text = password_circles;
|
||||
}
|
||||
|
||||
draw_sdf_string(ctx, x + TEXTBOX_INTERIOR_LEFT, y + text_offset - 12, text, 15, color, SDF_FONT_THIN);
|
||||
tt_set_size(tt_font_thin, 13);
|
||||
tt_draw_string(ctx, tt_font_thin, x + TEXTBOX_INTERIOR_LEFT, y + text_offset + 1, text, color);
|
||||
|
||||
if (tb->is_focused) {
|
||||
int width = draw_sdf_string_width(text, 15, SDF_FONT_THIN) + 2;
|
||||
int width = tt_string_width(tt_font_thin, text);
|
||||
draw_line(ctx, x + TEXTBOX_INTERIOR_LEFT + width, x + TEXTBOX_INTERIOR_LEFT + width, y + 2, y + text_offset + 1, tb->text_color);
|
||||
}
|
||||
|
||||
@ -168,10 +171,8 @@ void draw_login_container(gfx_context_t * ctx, struct login_container * lc) {
|
||||
/* Draw labels */
|
||||
if (lc->show_error) {
|
||||
char * error_message = "Incorrect username or password.";
|
||||
|
||||
//set_font_size(11);
|
||||
//draw_string(ctx, lc->x + (lc->width - draw_string_width(error_message)) / 2, lc->y + 6 + EXTRA_TEXT_OFFSET, rgb(240, 20, 20), error_message);
|
||||
draw_sdf_string(ctx, lc->x + (lc->width - draw_sdf_string_width(error_message, 14, SDF_FONT_THIN)) / 2, lc->y + 6 + EXTRA_TEXT_OFFSET - 14, error_message, 14, rgb(240,20,20), SDF_FONT_THIN);
|
||||
tt_set_size(tt_font_thin, 13);
|
||||
tt_draw_string(ctx, tt_font_thin, lc->x + (lc->width - tt_string_width(tt_font_thin, error_message)) / 2, lc->y + 6 + EXTRA_TEXT_OFFSET - 1, error_message, rgb(240,20,20));
|
||||
}
|
||||
|
||||
draw_text_box(ctx, lc->username_box);
|
||||
@ -201,19 +202,6 @@ static void get_updated_hostname_with_time_info(char hostname[]) {
|
||||
sprintf(hostname, "%s // %s", _hostname, _date);
|
||||
}
|
||||
|
||||
static void draw_sdf_string_shadow(gfx_context_t * ctx, char * string, int font_size, int left, int top, uint32_t text_color, uint32_t shadow_color, int blur, int font) {
|
||||
int w = draw_sdf_string_width(string, font_size, font);
|
||||
sprite_t * _tmp_s = create_sprite(w + blur * 2, font_size + blur * 2, ALPHA_EMBEDDED);
|
||||
gfx_context_t * _tmp = init_graphics_sprite(_tmp_s);
|
||||
draw_fill(_tmp, rgba(0,0,0,0));
|
||||
draw_sdf_string(_tmp, blur, blur, string, font_size, shadow_color, font);
|
||||
blur_context_box(_tmp, blur);
|
||||
free(_tmp);
|
||||
draw_sprite(ctx, _tmp_s, left - blur, top - blur);
|
||||
sprite_free(_tmp_s);
|
||||
draw_sdf_string(ctx, left, top, string, 14, text_color, font);
|
||||
}
|
||||
|
||||
int main (int argc, char ** argv) {
|
||||
if (getuid() != 0) {
|
||||
return 1;
|
||||
@ -279,6 +267,8 @@ int main (int argc, char ** argv) {
|
||||
yutani_flip(y, wina);
|
||||
TRACE("... done.");
|
||||
|
||||
tt_font_thin = tt_font_from_file("/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf");
|
||||
tt_font_bold = tt_font_from_file("/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf");
|
||||
|
||||
redo_everything:
|
||||
win_width = width;
|
||||
@ -402,8 +392,8 @@ redo_everything:
|
||||
|
||||
int focus = 0;
|
||||
|
||||
//set_font_size(11);
|
||||
int hostname_label_left = width - 10 - draw_sdf_string_width(hostname, 14, SDF_FONT_BOLD);
|
||||
tt_set_size(tt_font_thin, 13);
|
||||
int hostname_label_left = width - 10 - tt_string_width(tt_font_thin, hostname);
|
||||
int kernel_v_label_left = 10;
|
||||
|
||||
struct text_box username_box = { (BOX_WIDTH - 170) / 2, 30, 170, 20, rgb(0,0,0), NULL, 0, 0, 0, username, "Username" };
|
||||
@ -427,8 +417,8 @@ redo_everything:
|
||||
memcpy(ctx->backbuffer, foo, sizeof(uint32_t) * width * height);
|
||||
draw_sprite(ctx, &logo, center_x(logo.width), center_y(logo.height) - LOGO_FINAL_OFFSET);
|
||||
|
||||
draw_sdf_string_shadow(ctx, hostname, 14, hostname_label_left, height - 22, rgb(255,255,255), rgb(0,0,0), 4, SDF_FONT_BOLD);
|
||||
draw_sdf_string_shadow(ctx, kernel_v, 14, kernel_v_label_left, height - 22, rgb(255,255,255), rgb(0,0,0), 4, SDF_FONT_BOLD);
|
||||
tt_draw_string_shadow(ctx, tt_font_bold, hostname, 12, hostname_label_left, height - 22, rgb(255,255,255), rgb(0,0,0), 4);
|
||||
tt_draw_string_shadow(ctx, tt_font_bold, kernel_v, 12, kernel_v_label_left, height - 22, rgb(255,255,255), rgb(0,0,0), 4);
|
||||
|
||||
if (focus == USERNAME_BOX) {
|
||||
username_box.is_focused = 1;
|
||||
|
27
apps/gsudo.c
@ -19,16 +19,16 @@
|
||||
#include <toaru/auth.h>
|
||||
#include <toaru/yutani.h>
|
||||
#include <toaru/graphics.h>
|
||||
#include <toaru/sdf.h>
|
||||
#include <toaru/text.h>
|
||||
#include <toaru/button.h>
|
||||
|
||||
#define main __main_unused
|
||||
#include "sudo.c"
|
||||
#undef main
|
||||
|
||||
#define FONT_SIZE_TITLE 20
|
||||
#define FONT_SIZE_MAIN 16
|
||||
#define FONT_SIZE_PASSWD 25
|
||||
#define FONT_SIZE_TITLE 18
|
||||
#define FONT_SIZE_MAIN 13
|
||||
#define FONT_SIZE_PASSWD 22
|
||||
#define FONT_COLOR (rgb(0,0,0))
|
||||
#define FONT_RED (rgb(250,0,0))
|
||||
#define BUTTON_HEIGHT 28
|
||||
@ -38,6 +38,7 @@
|
||||
static yutani_t * yctx;
|
||||
static gfx_context_t * ctx;
|
||||
static yutani_window_t * window;
|
||||
static struct TT_Font * tt_font_thin;
|
||||
|
||||
struct TTKButton _button_cancel = {
|
||||
0, 0, BUTTON_WIDTH, BUTTON_HEIGHT, "Cancel", 0
|
||||
@ -85,17 +86,19 @@ static void redraw(char * username, char * password, int fails, char * argv[]) {
|
||||
draw_rounded_rectangle(myctx, 10, 10, prompt->width - 20, prompt->height - 20, 10, rgb(239,238,232));
|
||||
|
||||
/* Draw prompt messages */
|
||||
draw_sdf_string(myctx, 30, 30, "Authentication Required", FONT_SIZE_TITLE, FONT_COLOR, SDF_FONT_THIN);
|
||||
draw_sdf_string(myctx, 30, 54, "Authentication is required to run the application", FONT_SIZE_MAIN, FONT_COLOR, SDF_FONT_THIN);
|
||||
draw_sdf_string(myctx, 30, 72, argv[1], FONT_SIZE_MAIN, FONT_COLOR, SDF_FONT_THIN);
|
||||
tt_set_size(tt_font_thin, FONT_SIZE_TITLE);
|
||||
tt_draw_string(myctx, tt_font_thin, 30, 30 + FONT_SIZE_TITLE, "Authentication Required", FONT_COLOR);
|
||||
tt_set_size(tt_font_thin, FONT_SIZE_MAIN);
|
||||
tt_draw_string(myctx, tt_font_thin, 30, 54 + FONT_SIZE_MAIN, "Authentication is required to run the application", FONT_COLOR);
|
||||
tt_draw_string(myctx, tt_font_thin, 30, 72 + FONT_SIZE_MAIN, argv[1], FONT_COLOR);
|
||||
|
||||
char prompt_message[512];
|
||||
sprintf(prompt_message, "Enter password for '%s'", username);
|
||||
draw_sdf_string(myctx, 30, 100, prompt_message, FONT_SIZE_MAIN, FONT_COLOR, SDF_FONT_THIN);
|
||||
tt_draw_string(myctx, tt_font_thin, 30, 100 + FONT_SIZE_MAIN, prompt_message, FONT_COLOR);
|
||||
|
||||
if (fails) {
|
||||
sprintf(prompt_message, "Try again. %d failures.", fails);
|
||||
draw_sdf_string(myctx, 30, 146, prompt_message, FONT_SIZE_MAIN, FONT_RED, SDF_FONT_THIN);
|
||||
tt_draw_string(myctx, tt_font_thin, 30, 146 + FONT_SIZE_MAIN, prompt_message, FONT_RED);
|
||||
}
|
||||
|
||||
struct gradient_definition edge = {30, 114, rgb(0,120,220), rgb(0,120,220)};
|
||||
@ -105,9 +108,10 @@ static void redraw(char * username, char * password, int fails, char * argv[]) {
|
||||
char password_circles[512] = {0};;
|
||||
strcpy(password_circles, "");
|
||||
for (unsigned int i = 0; i < strlen(password) && i < 512/4; ++i) {
|
||||
strcat(password_circles, "\007");
|
||||
strcat(password_circles, "●");
|
||||
}
|
||||
draw_sdf_string(myctx, 33, 118, password_circles, FONT_SIZE_PASSWD, FONT_COLOR, SDF_FONT_THIN);
|
||||
tt_set_size(tt_font_thin, FONT_SIZE_PASSWD);
|
||||
tt_draw_string(myctx, tt_font_thin, 33, 118 + FONT_SIZE_PASSWD, password_circles, FONT_COLOR);
|
||||
|
||||
draw_fill(ctx, rgba(0,0,0,200));
|
||||
draw_sprite(ctx, prompt, (ctx->width - prompt->width) / 2, (ctx->height - prompt->height) / 2);
|
||||
@ -226,6 +230,7 @@ int main(int argc, char ** argv) {
|
||||
window = yutani_window_create(yctx, width, height);
|
||||
yutani_window_move(yctx, window, 0, 0);
|
||||
yutani_window_advertise(yctx, window, "gsudo");
|
||||
tt_font_thin = tt_font_from_file("/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf");
|
||||
|
||||
ctx = init_graphics_yutani_double_buffer(window);
|
||||
|
||||
|
@ -18,7 +18,7 @@
|
||||
#include <toaru/graphics.h>
|
||||
#include <toaru/decorations.h>
|
||||
#include <toaru/menu.h>
|
||||
#include <toaru/sdf.h>
|
||||
#include <toaru/text.h>
|
||||
#include <toaru/markup.h>
|
||||
|
||||
#define APPLICATION_TITLE "Help Browser"
|
||||
@ -47,6 +47,11 @@ static int cursor_x = 0;
|
||||
static list_t * state = NULL;
|
||||
static int current_state = 0;
|
||||
|
||||
static struct TT_Font * tt_font_thin = NULL;
|
||||
static struct TT_Font * tt_font_bold = NULL;
|
||||
static struct TT_Font * tt_font_oblique = NULL;
|
||||
static struct TT_Font * tt_font_bold_oblique = NULL;
|
||||
|
||||
struct Char {
|
||||
char c; /* TODO: unicode */
|
||||
char state;
|
||||
@ -55,23 +60,23 @@ struct Char {
|
||||
//static list_t * lines = NULL;
|
||||
static list_t * buffer = NULL;
|
||||
|
||||
static int state_to_font(int current_state) {
|
||||
static struct TT_Font * state_to_font(int current_state) {
|
||||
if (current_state & (1 << 0)) {
|
||||
if (current_state & (1 << 1)) {
|
||||
return SDF_FONT_BOLD_OBLIQUE;
|
||||
return tt_font_bold_oblique;
|
||||
}
|
||||
return SDF_FONT_BOLD;
|
||||
return tt_font_bold;
|
||||
} else if (current_state & (1 << 1)) {
|
||||
return SDF_FONT_OBLIQUE;
|
||||
return tt_font_oblique;
|
||||
}
|
||||
return SDF_FONT_THIN;
|
||||
return tt_font_thin;
|
||||
}
|
||||
|
||||
static int current_size(void) {
|
||||
if (current_state & (1 << 2)) {
|
||||
return 24;
|
||||
return 22;
|
||||
}
|
||||
return 16;
|
||||
return 13;
|
||||
}
|
||||
|
||||
static int buffer_width(list_t * buffer) {
|
||||
@ -81,7 +86,8 @@ static int buffer_width(list_t * buffer) {
|
||||
|
||||
char tmp[2] = {c->c, '\0'};
|
||||
|
||||
out += draw_sdf_string_width(tmp, current_size(), state_to_font(c->state));
|
||||
tt_set_size(state_to_font(c->state), current_size());
|
||||
out += tt_string_width(state_to_font(c->state), tmp);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
@ -92,7 +98,8 @@ static int draw_buffer(list_t * buffer) {
|
||||
node_t * node = list_dequeue(buffer);
|
||||
struct Char * c = node->value;
|
||||
char tmp[2] = { c->c, '\0' };
|
||||
x += draw_sdf_string(nctx, cursor_x + x, cursor_y, tmp, current_size(), 0xFF000000, state_to_font(c->state));
|
||||
tt_set_size(state_to_font(c->state), current_size());
|
||||
x += tt_draw_string(nctx, state_to_font(c->state), cursor_x + x, cursor_y + current_size(), tmp, 0xFF000000);
|
||||
free(c);
|
||||
free(node);
|
||||
}
|
||||
@ -342,6 +349,11 @@ int main(int argc, char * argv[]) {
|
||||
yutani_window_move(yctx, main_window, yctx->display_width / 2 - main_window->width / 2, yctx->display_height / 2 - main_window->height / 2);
|
||||
ctx = init_graphics_yutani_double_buffer(main_window);
|
||||
|
||||
tt_font_thin = tt_font_from_file("/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf");
|
||||
tt_font_bold = tt_font_from_file("/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf");
|
||||
tt_font_oblique = tt_font_from_file("/usr/share/fonts/truetype/dejavu/DejaVuSans-Oblique.ttf");
|
||||
tt_font_bold_oblique = tt_font_from_file("/usr/share/fonts/truetype/dejavu/DejaVuSans-BoldOblique.ttf");
|
||||
|
||||
yutani_window_advertise_icon(yctx, main_window, APPLICATION_TITLE, "help");
|
||||
|
||||
menu_bar.entries = menu_entries;
|
||||
|
@ -16,7 +16,7 @@
|
||||
#include <toaru/graphics.h>
|
||||
#include <toaru/decorations.h>
|
||||
#include <toaru/menu.h>
|
||||
#include <toaru/sdf.h>
|
||||
#include <toaru/text.h>
|
||||
#include <toaru/confreader.h>
|
||||
#include <toaru/icon_cache.h>
|
||||
|
||||
@ -39,6 +39,9 @@ static int hilighted_offset = -1; /* Which file is hovered by the mouse */
|
||||
static uint64_t last_click = 0; /* For double click */
|
||||
static int last_click_offset = -1; /* So that clicking two different things quickly doesn't count as a double click */
|
||||
|
||||
struct TT_Font * tt_font_thin = NULL;
|
||||
struct TT_Font * tt_font_bold = NULL;
|
||||
|
||||
struct Package {
|
||||
char name[256];
|
||||
char friendly_name[256];
|
||||
@ -130,10 +133,12 @@ static void draw_package(struct Package * package, int index) {
|
||||
|
||||
char tmp[2048];
|
||||
sprintf(tmp, "%s - %s", package->friendly_name, package->version);
|
||||
draw_sdf_string(contents, 64, offset_y + 4, tmp, 20, text_color, SDF_FONT_BOLD);
|
||||
tt_set_size(tt_font_bold, 18);
|
||||
tt_draw_string(contents, tt_font_bold, 64, offset_y + 4 + 18, tmp, text_color);
|
||||
sprintf(tmp, "%s - %s", package->name, package->description);
|
||||
int x = draw_sdf_string(contents, 65, offset_y + 24, package->name, 16, rgb(150,150,150), SDF_FONT_THIN);
|
||||
draw_sdf_string(contents, 64 + x + 4, offset_y + 24, package->description, 16, text_color, SDF_FONT_THIN);
|
||||
tt_set_size(tt_font_thin, 13);
|
||||
int x = tt_draw_string(contents, tt_font_thin, 65, offset_y + 24 + 13, package->name, rgb(150,150,150));
|
||||
tt_draw_string(contents, tt_font_thin, 64 + x + 4, offset_y + 24 + 13, package->description, text_color);
|
||||
|
||||
}
|
||||
|
||||
@ -457,6 +462,9 @@ int main(int argc, char * argv[]) {
|
||||
yutani_window_move(yctx, main_window, yctx->display_width / 2 - main_window->width / 2, yctx->display_height / 2 - main_window->height / 2);
|
||||
ctx = init_graphics_yutani_double_buffer(main_window);
|
||||
|
||||
tt_font_thin = tt_font_from_file("/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf");
|
||||
tt_font_bold = tt_font_from_file("/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf");
|
||||
|
||||
yutani_window_advertise_icon(yctx, main_window, APPLICATION_TITLE, "package");
|
||||
|
||||
menu_bar.entries = menu_entries;
|
||||
|
@ -47,7 +47,6 @@
|
||||
#include <toaru/spinlock.h>
|
||||
#include <toaru/list.h>
|
||||
#include <toaru/menu.h>
|
||||
#include <toaru/sdf.h>
|
||||
#include <toaru/text.h>
|
||||
|
||||
/* 16- and 256-color palette */
|
||||
@ -84,7 +83,7 @@ static int scale_fonts = 0; /* Whether fonts should be scaled */
|
||||
static float font_scaling = 1.0; /* How much they should be scaled by */
|
||||
static uint16_t term_width = 0; /* Width of the terminal (in cells) */
|
||||
static uint16_t term_height = 0; /* Height of the terminal (in cells) */
|
||||
static uint16_t font_size = 16; /* Font size according to SDF library */
|
||||
static uint16_t font_size = 16; /* Font size according to tt library */
|
||||
static uint16_t char_width = 9; /* Width of a cell in pixels */
|
||||
static uint16_t char_height = 17; /* Height of a cell in pixels */
|
||||
static uint16_t char_offset = 0; /* Offset of the font within the cell */
|
||||
@ -2128,7 +2127,7 @@ static void _menu_action_hide_borders(struct MenuEntry * self) {
|
||||
reinit();
|
||||
}
|
||||
|
||||
static void _menu_action_toggle_sdf(struct MenuEntry * self) {
|
||||
static void _menu_action_toggle_tt(struct MenuEntry * self) {
|
||||
_use_aa = !(_use_aa);
|
||||
menu_update_title(self, _use_aa ? "Bitmap font" : "Anti-aliased font");
|
||||
reinit();
|
||||
@ -2323,7 +2322,7 @@ int main(int argc, char ** argv) {
|
||||
_menu_toggle_borders_bar = menu_create_normal(NULL, NULL, _no_frame ? "Show borders" : "Hide borders", _menu_action_hide_borders);
|
||||
menu_insert(m, _menu_toggle_borders_bar);
|
||||
menu_insert(m, menu_create_submenu(NULL,"zoom","Set zoom..."));
|
||||
menu_insert(m, menu_create_normal(NULL, NULL, _use_aa ? "Bitmap font" : "Anti-aliased font", _menu_action_toggle_sdf));
|
||||
menu_insert(m, menu_create_normal(NULL, NULL, _use_aa ? "Bitmap font" : "Anti-aliased font", _menu_action_toggle_tt));
|
||||
menu_insert(m, menu_create_normal(NULL, NULL, _free_size ? "Snap to Cell Size" : "Freely Resize", _menu_action_toggle_free_size));
|
||||
menu_insert(m, menu_create_separator());
|
||||
menu_insert(m, menu_create_normal(NULL, NULL, "Redraw", _menu_action_redraw));
|
||||
|
@ -10,7 +10,7 @@
|
||||
#include <toaru/yutani.h>
|
||||
#include <toaru/graphics.h>
|
||||
#include <toaru/decorations.h>
|
||||
#include <toaru/sdf.h>
|
||||
#include <toaru/text.h>
|
||||
#include <toaru/menu.h>
|
||||
#include <toaru/button.h>
|
||||
#include <toaru/list.h>
|
||||
@ -25,6 +25,7 @@ static yutani_t * yctx;
|
||||
static yutani_window_t * window = NULL;
|
||||
static gfx_context_t * ctx = NULL;
|
||||
static sprite_t wallpaper = { 0 };
|
||||
static struct TT_Font * tt_font = NULL;
|
||||
|
||||
static int32_t width = 640;
|
||||
static int32_t height = 300;
|
||||
@ -70,10 +71,11 @@ static void redraw(void) {
|
||||
}
|
||||
|
||||
/* Draws the path for the selected wallpaper in white, centered, with a drop shadow */
|
||||
int str_width = draw_sdf_string_width(wallpaper_path, 16, SDF_FONT_THIN);
|
||||
tt_set_size(tt_font, 13);
|
||||
int str_width = tt_string_width(tt_font, wallpaper_path);
|
||||
int center_x_text = (window->width - bounds.width - str_width) / 2;
|
||||
draw_sdf_string_stroke(ctx, center_x_text + 1, bounds.top_height + 10 + 1, wallpaper_path, 16, rgba(0,0,0,120), SDF_FONT_THIN, 1.7, 0.5);
|
||||
draw_sdf_string(ctx, center_x_text, bounds.top_height + 10, wallpaper_path, 16, rgb(255,255,255), SDF_FONT_THIN);
|
||||
tt_draw_string_shadow(ctx, tt_font, wallpaper_path, 13, center_x_text + 1, bounds.top_height + 10 + 1, rgba(0,0,0,0), rgb(0,0,0), 4);
|
||||
tt_draw_string_shadow(ctx, tt_font, wallpaper_path, 13, center_x_text + 1, bounds.top_height + 10 + 1, rgb(255,255,255), rgb(0,0,0), 4);
|
||||
|
||||
/* Draw the buttons */
|
||||
ttk_button_draw(ctx, &_set);
|
||||
@ -292,6 +294,8 @@ int main(int argc, char * argv[]) {
|
||||
req_center_x = yctx->display_width / 2;
|
||||
req_center_y = yctx->display_height / 2;
|
||||
|
||||
tt_font = tt_font_from_file("/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf");
|
||||
|
||||
get_default_wallpaper();
|
||||
read_wallpapers();
|
||||
|
||||
|
@ -1,24 +0,0 @@
|
||||
#pragma once
|
||||
#include <_cheader.h>
|
||||
#include <stdint.h>
|
||||
#include <toaru/graphics.h>
|
||||
|
||||
_Begin_C_Header
|
||||
|
||||
enum sdf_font {
|
||||
SDF_FONT_THIN,
|
||||
SDF_FONT_BOLD,
|
||||
SDF_FONT_MONO,
|
||||
SDF_FONT_MONO_BOLD,
|
||||
SDF_FONT_MONO_OBLIQUE,
|
||||
SDF_FONT_MONO_BOLD_OBLIQUE,
|
||||
SDF_FONT_OBLIQUE,
|
||||
SDF_FONT_BOLD_OBLIQUE,
|
||||
};
|
||||
|
||||
extern int draw_sdf_string(gfx_context_t * ctx, int32_t x, int32_t y, const char * str, int size, uint32_t color, int font);
|
||||
extern int draw_sdf_string_width(const char * str, int size, int font);
|
||||
extern int draw_sdf_string_gamma(gfx_context_t * ctx, int32_t x, int32_t y, const char * str, int size, uint32_t color, int font, double _gamma);
|
||||
extern int draw_sdf_string_stroke(gfx_context_t * ctx, int32_t x, int32_t y, const char * str, int size, uint32_t color, int font, double _gamma, double stroke);
|
||||
|
||||
_End_C_Header
|
@ -1,92 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <_cheader.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include <toaru/hashmap.h>
|
||||
#include <toaru/graphics.h>
|
||||
|
||||
_Begin_C_Header
|
||||
|
||||
struct TR_Font {
|
||||
int typeface; /* Should probably be more flexible than int, but tough luck for now. */
|
||||
int size;
|
||||
uint32_t color;
|
||||
/* TODO shadow - we had built-in support for this in the old setup, not sure I want to do it here */
|
||||
};
|
||||
|
||||
/* TODO This should probably all use wchar_t, but the font library needs to support that as well. */
|
||||
|
||||
extern int tr_font_get_width(struct TR_Font * font, char * string);
|
||||
extern int tr_font_write(struct TR_Font * font, gfx_context_t * ctx, int x, int y, char * string);
|
||||
|
||||
struct TR_TextUnit {
|
||||
char * string;
|
||||
int unit_type;
|
||||
int width; /* calculated on creation */
|
||||
|
||||
struct TR_Font * font; /* not a pointer */
|
||||
hashmap_t * extra; /* extra properties in hashmap if present */
|
||||
list_t * tag_group; /* tag group membership if present */
|
||||
};
|
||||
|
||||
extern void tr_textunit_set_tag_group(struct TR_TextUnit * self, list_t * tag_group);
|
||||
extern void tr_textunit_set_font(struct TR_TextUnit * self, struct TR_Font * font);
|
||||
extern void tr_textunit_set_extra(struct TR_TextUnit * self, char * key, void * data);
|
||||
|
||||
struct TR_TextRegion {
|
||||
int x;
|
||||
int y;
|
||||
|
||||
int width;
|
||||
int height;
|
||||
|
||||
struct TR_Font * font;
|
||||
|
||||
char * text;
|
||||
list_t * lines;
|
||||
int align;
|
||||
int valign;
|
||||
int line_height; /* TODO should be property of lines */
|
||||
|
||||
struct TR_TextUnit * text_units; /* array */
|
||||
int scroll;
|
||||
char * ellipsis; /* blank by default */
|
||||
bool one_line; /* False by default */
|
||||
|
||||
char * base_dir; /* Used for links and images */
|
||||
bool break_all; /* False by default */
|
||||
char * title; /* blank by default */
|
||||
int max_lines; /* 0 is None */
|
||||
};
|
||||
|
||||
struct TR_Offset {
|
||||
struct TR_TextUnit * unit;
|
||||
int line;
|
||||
int left;
|
||||
int right;
|
||||
int index;
|
||||
};
|
||||
|
||||
extern void tr_textregion_set_alignment(struct TR_TextRegion * self, int align);
|
||||
extern void tr_textregion_set_valignment(struct TR_TextRegion * self, int align);
|
||||
extern void tr_textregion_set_max_lines(struct TR_TextRegion * self, int max_lines);
|
||||
extern int tr_textregion_get_visible_lines(struct TR_TextRegion * self); /* height / line_height */
|
||||
extern void tr_textregion_reflow(struct TR_TextRegion * self);
|
||||
extern list_t * tr_textregion_units_from_text(struct TR_TextRegion * self, char * text, struct TR_Font * font, bool whitespace);
|
||||
|
||||
extern void tr_textregion_set_one_line(struct TR_TextRegion * self, bool one_line);
|
||||
extern void tr_textregion_set_ellipsis(struct TR_TextRegion * self, char * ellipsis);
|
||||
extern void tr_textregion_set_text(struct TR_TextRegion* self, char * text);
|
||||
extern void tr_textregion_set_font(struct TR_TextRegion* self, struct TR_Font * font);
|
||||
extern void tr_textregion_set_line_height(struct TR_TextRegion * self, int line_height);
|
||||
extern void tr_textregion_resize(struct TR_TextRegion * self, int width, int height);
|
||||
extern void tr_textregion_move(struct TR_TextRegion * self, int x, int y);
|
||||
|
||||
extern void tr_textregion_get_offset_at_index(struct TR_TextRegion* self, int index, struct TR_Offset * out);
|
||||
extern void tr_textregion_pick(struct TR_TextRegion * self, int x, int y, struct TR_Offset * out);
|
||||
extern struct TR_TextUnit * tr_textregion_click(struct TR_TextRegion * self, int x, int y);
|
||||
extern void tr_textregion_draw(struct TR_TextRegion * self, gfx_context_t * ctx);
|
||||
|
||||
_End_C_Header
|
Before Width: | Height: | Size: 106 KiB |
Before Width: | Height: | Size: 118 KiB |
Before Width: | Height: | Size: 94 KiB |
Before Width: | Height: | Size: 97 KiB |
Before Width: | Height: | Size: 108 KiB |
Before Width: | Height: | Size: 106 KiB |
Before Width: | Height: | Size: 113 KiB |
Before Width: | Height: | Size: 101 KiB |
@ -62,18 +62,10 @@ Replacement for `readline`. Mostly deprecated in favor of `rline_exp`.
|
||||
|
||||
Replacement for `readline`, with support for syntax highlighting.
|
||||
|
||||
## `toaru_sdf`
|
||||
|
||||
Signed Distance Field text rendering library.
|
||||
|
||||
## `toaru_termemu`
|
||||
|
||||
Terminal ANSI escape processor.
|
||||
|
||||
## `toaru_textregion`
|
||||
|
||||
WIP library for providing multiline wrapping label widgets with rich text support.
|
||||
|
||||
## `toaru_tree`
|
||||
|
||||
Generic tree implementation. Also used by the kernel.
|
||||
|
@ -13,8 +13,8 @@
|
||||
#include <toaru/graphics.h>
|
||||
#include <toaru/yutani.h>
|
||||
#include <toaru/decorations.h>
|
||||
#include <toaru/sdf.h>
|
||||
#include <toaru/menu.h>
|
||||
#include <toaru/text.h>
|
||||
|
||||
#define TEXT_OFFSET_X 10
|
||||
#define TEXT_OFFSET_Y 3
|
||||
@ -37,6 +37,8 @@ static int close_enough(struct yutani_msg_window_mouse_event * me) {
|
||||
sqrt(pow(me->new_x - me->old_x, 2.0) + pow(me->new_y - me->old_y, 2.0)) < 10.0);
|
||||
}
|
||||
|
||||
static struct TT_Font * tt_font = NULL;
|
||||
|
||||
static void render_decorations_simple(yutani_window_t * window, gfx_context_t * ctx, char * title, int decors_active) {
|
||||
|
||||
uint32_t color = BORDERCOLOR;
|
||||
@ -56,13 +58,10 @@ static void render_decorations_simple(yutani_window_t * window, gfx_context_t *
|
||||
}
|
||||
}
|
||||
|
||||
if (decors_active == DECOR_INACTIVE) {
|
||||
draw_sdf_string(ctx, TEXT_OFFSET_X, TEXT_OFFSET_Y, title, 14, TEXTCOLOR_INACTIVE, SDF_FONT_THIN);
|
||||
draw_sdf_string(ctx, window->width - 20, TEXT_OFFSET_Y, "x", 14, TEXTCOLOR_INACTIVE, SDF_FONT_THIN);
|
||||
} else {
|
||||
draw_sdf_string(ctx, TEXT_OFFSET_X, TEXT_OFFSET_Y, title, 14, TEXTCOLOR, SDF_FONT_THIN);
|
||||
draw_sdf_string(ctx, window->width - 20, TEXT_OFFSET_Y, "x", 14, TEXTCOLOR, SDF_FONT_THIN);
|
||||
}
|
||||
tt_set_size(tt_font, 12);
|
||||
uint32_t textcolor = (decors_active == DECOR_INACTIVE) ? TEXTCOLOR_INACTIVE : TEXTCOLOR;
|
||||
tt_draw_string(ctx, tt_font, TEXT_OFFSET_X, TEXT_OFFSET_Y + 12, title, textcolor);
|
||||
tt_draw_string(ctx, tt_font, window->width - 20, TEXT_OFFSET_Y + 12, "x", textcolor);
|
||||
|
||||
for (uint32_t i = 0; i < window->width; ++i) {
|
||||
GFX(ctx, i, 0) = color;
|
||||
@ -96,6 +95,7 @@ static void initialize_simple() {
|
||||
decor_render_decorations = render_decorations_simple;
|
||||
decor_check_button_press = check_button_press_simple;
|
||||
decor_get_bounds = get_bounds_simple;
|
||||
tt_font = tt_font_from_file("/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf");
|
||||
}
|
||||
|
||||
void render_decorations(yutani_window_t * window, gfx_context_t * ctx, char * title) {
|
||||
|
@ -2,7 +2,6 @@
|
||||
#include <assert.h>
|
||||
#include <toaru/yutani.h>
|
||||
#include <toaru/decorations.h>
|
||||
#include <toaru/sdf.h>
|
||||
#include <toaru/menu.h>
|
||||
#include <kuroko/kuroko.h>
|
||||
#include <kuroko/vm.h>
|
||||
@ -925,7 +924,7 @@ static KrkValue _font_draw_string(int argc, KrkValue argv[], int hasKw) {
|
||||
int32_t x = AS_INTEGER(argv[3]);
|
||||
int32_t y = AS_INTEGER(argv[4]);
|
||||
|
||||
return INTEGER_VAL(draw_sdf_string_stroke(ctx,x,y,str,self->fontSize,self->fontColor,self->fontType,self->fontGamma,self->fontStroke));
|
||||
return INTEGER_VAL(-1);
|
||||
}
|
||||
|
||||
static KrkValue _font_width(int argc, KrkValue argv[], int hasKw) {
|
||||
@ -934,7 +933,7 @@ static KrkValue _font_width(int argc, KrkValue argv[], int hasKw) {
|
||||
return krk_runtimeError(vm.exceptions->typeError, "expected str");
|
||||
|
||||
const char * str = AS_CSTRING(argv[1]);
|
||||
return INTEGER_VAL(draw_sdf_string_width(str, self->fontSize, self->fontType));
|
||||
return INTEGER_VAL(-1);
|
||||
}
|
||||
|
||||
static void _MenuBar_gcsweep(KrkInstance * _self) {
|
||||
@ -1346,16 +1345,6 @@ KrkValue krk_module_onload__yutani(void) {
|
||||
"Font.width(string)\n"
|
||||
" Calculate the rendered width of the given string when drawn with this font.";
|
||||
krk_defineNative(&YutaniFont->methods, "size", _font_size)->flags |= KRK_NATIVE_FLAGS_IS_DYNAMIC_PROPERTY;
|
||||
/* Some static values */
|
||||
#define ATTACH_FONT(name) krk_attachNamedValue(&YutaniFont->methods, #name, INTEGER_VAL(SDF_ ## name))
|
||||
ATTACH_FONT(FONT_THIN);
|
||||
ATTACH_FONT(FONT_BOLD);
|
||||
ATTACH_FONT(FONT_MONO);
|
||||
ATTACH_FONT(FONT_MONO_BOLD);
|
||||
ATTACH_FONT(FONT_MONO_OBLIQUE);
|
||||
ATTACH_FONT(FONT_MONO_BOLD_OBLIQUE);
|
||||
ATTACH_FONT(FONT_OBLIQUE);
|
||||
ATTACH_FONT(FONT_BOLD_OBLIQUE);
|
||||
krk_finalizeClass(YutaniFont);
|
||||
|
||||
MenuBarClass = krk_createClass(module, "MenuBar", NULL);
|
||||
|
267
lib/sdf.c
@ -1,267 +0,0 @@
|
||||
/* vim: tabstop=4 shiftwidth=4 noexpandtab
|
||||
* This file is part of ToaruOS and is released under the terms
|
||||
* of the NCSA / University of Illinois License - see LICENSE.md
|
||||
* Copyright (C) 2018 K. Lange
|
||||
*
|
||||
* Signed Distance Field text rasterization library
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/shm.h>
|
||||
|
||||
#include <toaru/graphics.h>
|
||||
#include <toaru/hashmap.h>
|
||||
#include <toaru/sdf.h>
|
||||
#include <toaru/spinlock.h>
|
||||
#include <toaru/decodeutf8.h>
|
||||
|
||||
#include "apps/ununicode.h"
|
||||
|
||||
#define BASE_WIDTH 50
|
||||
#define BASE_HEIGHT 50
|
||||
|
||||
static sprite_t _font_data_thin;
|
||||
static sprite_t _font_data_bold;
|
||||
static sprite_t _font_data_oblique;
|
||||
static sprite_t _font_data_bold_oblique;
|
||||
static sprite_t _font_data_mono;
|
||||
static sprite_t _font_data_mono_bold;
|
||||
static sprite_t _font_data_mono_oblique;
|
||||
static sprite_t _font_data_mono_bold_oblique;
|
||||
|
||||
static hashmap_t * _font_cache;
|
||||
|
||||
static volatile int _sdf_lock = 0;
|
||||
static double gamma = 1.7;
|
||||
|
||||
struct CharData{
|
||||
char code;
|
||||
size_t width_bold;
|
||||
size_t width_thin;
|
||||
size_t width_mono;
|
||||
} _char_data[256];
|
||||
|
||||
static int loaded = 0;
|
||||
|
||||
static int offset(int ch) {
|
||||
/* Calculate offset into table above */
|
||||
return ch;
|
||||
}
|
||||
|
||||
static char * _font_data = NULL;
|
||||
static size_t _font_data_size = 0;
|
||||
|
||||
static void load_font(sprite_t * sprite, int font) {
|
||||
uint32_t * _font_data_i = (uint32_t*)_font_data;
|
||||
|
||||
sprite->width = _font_data_i[font * 3 + 1];
|
||||
sprite->height = _font_data_i[font * 3 + 2];
|
||||
|
||||
int offset = _font_data_i[font * 3 + 3];
|
||||
sprite->bitmap = (uint32_t *)&_font_data[offset];
|
||||
sprite->alpha = 0;
|
||||
sprite->masks = NULL;
|
||||
sprite->blank = 0;
|
||||
}
|
||||
|
||||
__attribute__((constructor))
|
||||
static void _init_sdf(void) {
|
||||
/* Load the font. */
|
||||
_font_cache = hashmap_create_int(10);
|
||||
{
|
||||
char tmp[100];
|
||||
char * display = getenv("DISPLAY");
|
||||
if (!display) display = "compositor";
|
||||
sprintf(tmp, "sys.%s.fonts", display);
|
||||
_font_data = shm_obtain(tmp, &_font_data_size);
|
||||
}
|
||||
|
||||
if (!_font_data_size) return;
|
||||
|
||||
load_font(&_font_data_thin, SDF_FONT_THIN);
|
||||
load_font(&_font_data_bold, SDF_FONT_BOLD);
|
||||
load_font(&_font_data_oblique, SDF_FONT_OBLIQUE);
|
||||
load_font(&_font_data_bold_oblique, SDF_FONT_BOLD_OBLIQUE);
|
||||
load_font(&_font_data_mono, SDF_FONT_MONO);
|
||||
load_font(&_font_data_mono_bold, SDF_FONT_MONO_BOLD);
|
||||
load_font(&_font_data_mono_oblique, SDF_FONT_MONO_OBLIQUE);
|
||||
load_font(&_font_data_mono_bold_oblique, SDF_FONT_MONO_BOLD_OBLIQUE);
|
||||
|
||||
FILE * fi = fopen("/etc/sdf.conf", "r");
|
||||
char tmp[1024];
|
||||
char * s = tmp;
|
||||
for (int i = 0; i < 256; ++i) {
|
||||
_char_data[i].code = i;
|
||||
_char_data[i].width_bold = 25;
|
||||
_char_data[i].width_thin = 20;
|
||||
_char_data[i].width_mono = 25;
|
||||
}
|
||||
while ((s = fgets(tmp, 1024, fi))) {
|
||||
if (strlen(s) < 1) continue;
|
||||
int i = offset(*s);
|
||||
s++; s++;
|
||||
char t = *s;
|
||||
s++; s++;
|
||||
int o = atoi(s);
|
||||
if (t == 'b') {
|
||||
_char_data[i].width_bold = o;
|
||||
} else if (t == 't') {
|
||||
_char_data[i].width_thin = o;
|
||||
} else if (t == 'm') {
|
||||
_char_data[i].width_mono = o;
|
||||
}
|
||||
}
|
||||
fclose(fi);
|
||||
loaded = 1;
|
||||
}
|
||||
|
||||
static sprite_t * _select_font(int font) {
|
||||
switch (font) {
|
||||
case SDF_FONT_BOLD:
|
||||
return &_font_data_bold;
|
||||
case SDF_FONT_MONO:
|
||||
return &_font_data_mono;
|
||||
case SDF_FONT_MONO_BOLD:
|
||||
return &_font_data_mono_bold;
|
||||
case SDF_FONT_MONO_OBLIQUE:
|
||||
return &_font_data_mono_oblique;
|
||||
case SDF_FONT_MONO_BOLD_OBLIQUE:
|
||||
return &_font_data_mono_bold_oblique;
|
||||
case SDF_FONT_OBLIQUE:
|
||||
return &_font_data_oblique;
|
||||
case SDF_FONT_BOLD_OBLIQUE:
|
||||
return &_font_data_bold_oblique;
|
||||
case SDF_FONT_THIN:
|
||||
default:
|
||||
return &_font_data_thin;
|
||||
}
|
||||
}
|
||||
|
||||
static int _select_width(int _ch, int font) {
|
||||
int ch = (_ch >= 0 && _ch <= 128) ? _ch : (int)ununicode(_ch);
|
||||
switch (font) {
|
||||
case SDF_FONT_BOLD:
|
||||
case SDF_FONT_BOLD_OBLIQUE:
|
||||
return _char_data[ch].width_bold;
|
||||
case SDF_FONT_MONO:
|
||||
case SDF_FONT_MONO_BOLD:
|
||||
case SDF_FONT_MONO_OBLIQUE:
|
||||
case SDF_FONT_MONO_BOLD_OBLIQUE:
|
||||
return _char_data[ch].width_mono;
|
||||
case SDF_FONT_OBLIQUE:
|
||||
case SDF_FONT_THIN:
|
||||
default:
|
||||
return _char_data[ch].width_thin;
|
||||
}
|
||||
}
|
||||
|
||||
static int draw_sdf_character(gfx_context_t * ctx, int32_t x, int32_t y, int _ch, int size, uint32_t color, sprite_t * tmp, int font, sprite_t * _font_data, double buffer) {
|
||||
int ch = (_ch >= 0 && _ch <= 128) ? _ch : (int)ununicode(_ch);
|
||||
|
||||
double scale = (double)size / 50.0;
|
||||
int width = _select_width(ch, font) * scale;
|
||||
int fx = ((BASE_WIDTH * ch) % _font_data->width) * scale;
|
||||
int fy = (((BASE_WIDTH * ch) / _font_data->width) * BASE_HEIGHT) * scale;
|
||||
|
||||
int height = BASE_HEIGHT * ((double)size / 50.0);
|
||||
|
||||
|
||||
/* ignore size */
|
||||
for (int j = 0; j < height; ++j) {
|
||||
if (y + j < 0) continue;
|
||||
if (y + j >= ctx->height) continue;
|
||||
if (fy+j >= tmp->height) continue;
|
||||
for (int i = 0; i < size; ++i) {
|
||||
/* TODO needs to do bilinear filter */
|
||||
if (fx+i >= tmp->width) continue;
|
||||
if (x + i < 0) continue;
|
||||
if (x + i >= ctx->width) continue;
|
||||
uint32_t c = SPRITE((tmp), fx+i, fy+j);
|
||||
double dist = (double)_RED(c) / 255.0;
|
||||
double edge0 = buffer - gamma * 1.4142 / (double)size;
|
||||
double edge1 = buffer + gamma * 1.4142 / (double)size;
|
||||
double a = (dist - edge0) / (edge1 - edge0);
|
||||
if (a < 0.0) a = 0.0;
|
||||
if (a > 1.0) a = 1.0;
|
||||
a = a * a * (3 - 2 * a);
|
||||
uint32_t f_color = premultiply((color & 0xFFFFFF) | ((uint32_t)(255 * a) << 24));
|
||||
f_color = (f_color & 0xFFFFFF) | ((uint32_t)(a * _ALP(color)) << 24);
|
||||
GFX(ctx,x+i,y+j) = alpha_blend_rgba(GFX(ctx,x+i,y+j), f_color);
|
||||
}
|
||||
}
|
||||
|
||||
return width;
|
||||
|
||||
}
|
||||
|
||||
int draw_sdf_string_stroke(gfx_context_t * ctx, int32_t x, int32_t y, const char * str, int size, uint32_t color, int font, double _gamma, double stroke) {
|
||||
|
||||
sprite_t * _font_data = _select_font(font);
|
||||
|
||||
if (!loaded) return 0;
|
||||
|
||||
double scale = (double)size / 50.0;
|
||||
int scale_height = scale * _font_data->height;
|
||||
|
||||
sprite_t * tmp;
|
||||
spin_lock(&_sdf_lock);
|
||||
if (!hashmap_has(_font_cache, (void *)(uintptr_t)(scale_height | (font << 16)))) {
|
||||
tmp = create_sprite(scale * _font_data->width, scale * _font_data->height, ALPHA_OPAQUE);
|
||||
gfx_context_t * t = init_graphics_sprite(tmp);
|
||||
draw_sprite_scaled(t, _font_data, 0, 0, tmp->width, tmp->height);
|
||||
free(t);
|
||||
hashmap_set(_font_cache, (void *)(uintptr_t)(scale_height | (font << 16)), tmp);
|
||||
} else {
|
||||
tmp = hashmap_get(_font_cache, (void *)(uintptr_t)(scale_height | (font << 16)));
|
||||
}
|
||||
|
||||
uint32_t state = 0;
|
||||
uint32_t c = 0;
|
||||
int32_t out_width = 0;
|
||||
gamma = _gamma;
|
||||
while (*str) {
|
||||
if (!decode(&state, &c, (unsigned char)*str)) {
|
||||
int w = draw_sdf_character(ctx,x,y,c,size,color,tmp,font,_font_data, stroke);
|
||||
out_width += w;
|
||||
x += w;
|
||||
}
|
||||
str++;
|
||||
}
|
||||
spin_unlock(&_sdf_lock);
|
||||
|
||||
return out_width;
|
||||
}
|
||||
|
||||
int draw_sdf_string_gamma(gfx_context_t * ctx, int32_t x, int32_t y, const char * str, int size, uint32_t color, int font, double _gamma) {
|
||||
return draw_sdf_string_stroke(ctx,x,y,str,size,color,font,gamma,0.75);
|
||||
}
|
||||
|
||||
int draw_sdf_string(gfx_context_t * ctx, int32_t x, int32_t y, const char * str, int size, uint32_t color, int font) {
|
||||
return draw_sdf_string_stroke(ctx,x,y,str,size,color,font,1.7, 0.75);
|
||||
}
|
||||
|
||||
static int char_width(int ch, int font) {
|
||||
return _select_width(ch, font);
|
||||
}
|
||||
|
||||
|
||||
int draw_sdf_string_width(const char * str, int size, int font) {
|
||||
double scale = (double)size / 50.0;
|
||||
|
||||
uint32_t state = 0;
|
||||
uint32_t c = 0;
|
||||
|
||||
int32_t out_width = 0;
|
||||
while (*str) {
|
||||
if (!decode(&state, &c, (unsigned char)*str)) {
|
||||
int w = char_width(c,font) * scale;
|
||||
out_width += w;
|
||||
} else if (state == UTF8_REJECT) {
|
||||
state = 0;
|
||||
}
|
||||
str++;
|
||||
}
|
||||
|
||||
return out_width;
|
||||
}
|
@ -1,85 +0,0 @@
|
||||
/* vim: tabstop=4 shiftwidth=4 noexpandtab
|
||||
* This file is part of ToaruOS and is released under the terms
|
||||
* of the NCSA / University of Illinois License - see LICENSE.md
|
||||
* Copyright (C) 2018 K. Lange
|
||||
*
|
||||
* TODO: This is a work in progress
|
||||
*
|
||||
* Port of the original ToaruOS Python text_region library to C.
|
||||
*
|
||||
* Allows for the display of rich text with multiple varied formats,
|
||||
* as well as carat positioning, reflow, links, images, and so on.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <toaru/textregion.h>
|
||||
#include <toaru/sdf.h>
|
||||
|
||||
int tr_font_get_width(struct TR_Font * font, char * string) {
|
||||
return draw_sdf_string_width(string, font->size, font->typeface);
|
||||
}
|
||||
|
||||
int tr_font_write(struct TR_Font * font, gfx_context_t * ctx, int x, int y, char * string) {
|
||||
return draw_sdf_string(ctx, x, y, string, font->size, font->color, font->typeface);
|
||||
}
|
||||
|
||||
void tr_textunit_set_tag_group(struct TR_TextUnit * self, list_t * tag_group) {
|
||||
if (!self->tag_group) {
|
||||
self->tag_group = tag_group;
|
||||
list_insert(tag_group, self);
|
||||
} else {
|
||||
/* Already in a tag group, this is wrong */
|
||||
}
|
||||
}
|
||||
|
||||
void tr_textunit_set_font(struct TR_TextUnit * self, struct TR_Font * font) {
|
||||
self->font = font;
|
||||
self->width = tr_font_get_width(font, self->string);
|
||||
}
|
||||
|
||||
void tr_textunit_set_extra(struct TR_TextUnit * self, char * key, void * data) {
|
||||
if (!self->extra) {
|
||||
self->extra = hashmap_create(10);
|
||||
}
|
||||
hashmap_set(self->extra, key, data);
|
||||
}
|
||||
|
||||
void tr_textregion_set_alignment(struct TR_TextRegion * self, int align) {
|
||||
self->align = align;
|
||||
}
|
||||
|
||||
void tr_textregion_set_valignment(struct TR_TextRegion * self, int align) {
|
||||
self->valign = align;
|
||||
}
|
||||
|
||||
void tr_textregion_set_max_lines(struct TR_TextRegion * self, int max_lines) {
|
||||
self->max_lines = max_lines;
|
||||
tr_textregion_reflow(self);
|
||||
}
|
||||
|
||||
int tr_textregion_get_visible_lines(struct TR_TextRegion * self) {
|
||||
return self->height / self->line_height;
|
||||
}
|
||||
|
||||
void tr_textregion_reflow(struct TR_TextRegion * self) {
|
||||
if (self->lines) {
|
||||
fprintf(stderr, "Need to clean out lines\n");
|
||||
#if 0
|
||||
list_destroy(self->lines);
|
||||
list_free(self->lines);
|
||||
free(self->lines);
|
||||
#endif
|
||||
}
|
||||
|
||||
#if 0
|
||||
self->lines = list_create();
|
||||
|
||||
int current_width = 0;
|
||||
list_t * current_units = list_create();
|
||||
struct TR_TextUnit * leftover = NULL;
|
||||
|
||||
int i = 0;
|
||||
while (i < self->text_units
|
||||
#endif
|
||||
|
||||
}
|
@ -25,13 +25,11 @@ class Classifier:
|
||||
'<toaru/markup.h>': (None, '-ltoaru_markup', ['<toaru/hashmap.h>']),
|
||||
'<toaru/json.h>': (None, '-ltoaru_json', ['<toaru/hashmap.h>']),
|
||||
'<toaru/yutani.h>': (None, '-ltoaru_yutani', ['<toaru/kbd.h>', '<toaru/list.h>', '<toaru/pex.h>', '<toaru/graphics.h>', '<toaru/hashmap.h>']),
|
||||
'<toaru/decorations.h>': (None, '-ltoaru_decorations', ['<toaru/menu.h>', '<toaru/sdf.h>', '<toaru/graphics.h>', '<toaru/yutani.h>']),
|
||||
'<toaru/decorations.h>': (None, '-ltoaru_decorations', ['<toaru/menu.h>', '<toaru/text.h>', '<toaru/graphics.h>', '<toaru/yutani.h>']),
|
||||
'<toaru/termemu.h>': (None, '-ltoaru_termemu', ['<toaru/graphics.h>']),
|
||||
'<toaru/sdf.h>': (None, '-ltoaru_sdf', ['<toaru/graphics.h>', '<toaru/hashmap.h>']),
|
||||
'<toaru/icon_cache.h>': (None, '-ltoaru_icon_cache', ['<toaru/graphics.h>', '<toaru/hashmap.h>']),
|
||||
'<toaru/menu.h>': (None, '-ltoaru_menu', ['<toaru/sdf.h>', '<toaru/yutani.h>', '<toaru/icon_cache.h>', '<toaru/graphics.h>', '<toaru/hashmap.h>']),
|
||||
'<toaru/textregion.h>': (None, '-ltoaru_textregion', ['<toaru/sdf.h>', '<toaru/yutani.h>','<toaru/graphics.h>', '<toaru/hashmap.h>']),
|
||||
'<toaru/button.h>': (None, '-ltoaru_button', ['<toaru/graphics.h>','<toaru/sdf.h>', '<toaru/icon_cache.h>']),
|
||||
'<toaru/menu.h>': (None, '-ltoaru_menu', ['<toaru/yutani.h>', '<toaru/icon_cache.h>', '<toaru/graphics.h>', '<toaru/hashmap.h>']),
|
||||
'<toaru/button.h>': (None, '-ltoaru_button', ['<toaru/graphics.h>','<toaru/text.h>', '<toaru/icon_cache.h>']),
|
||||
'<toaru/text.h>': (None, '-ltoaru_text', ['<toaru/graphics.h>', '<toaru/hashmap.h>']),
|
||||
# Kuroko
|
||||
'<kuroko/kuroko.h>': ('../../../kuroko/src', '-lkuroko', []),
|
||||
|