Initial code to show window size in cells while resizing
This commit is contained in:
parent
bb97c589c1
commit
11522ccc92
11 changed files with 101 additions and 19 deletions
|
|
@ -1076,7 +1076,7 @@ render_line(FONTS_DATA_HANDLE fg_, Line *line) {
|
|||
StringCanvas
|
||||
render_simple_text(FONTS_DATA_HANDLE fg_, const char *text) {
|
||||
FontGroup *fg = (FontGroup*)fg_;
|
||||
if (fg->fonts_count) return render_simple_text_impl(fg->fonts[0].face, text);
|
||||
if (fg->fonts_count && fg->medium_font_idx) return render_simple_text_impl(fg->fonts[fg->medium_font_idx].face, text);
|
||||
StringCanvas ans = {0};
|
||||
return ans;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@ void render_line(FONTS_DATA_HANDLE, Line *line);
|
|||
void sprite_tracker_set_limits(size_t max_texture_size, size_t max_array_len);
|
||||
typedef void (*free_extra_data_func)(void*);
|
||||
StringCanvas render_simple_text_impl(PyObject *s, const char *text);
|
||||
StringCanvas render_simple_text(FONTS_DATA_HANDLE fg_, const char *text);
|
||||
|
||||
static inline void
|
||||
right_shift_canvas(pixel *canvas, size_t width, size_t height, size_t amt) {
|
||||
|
|
|
|||
|
|
@ -579,14 +579,14 @@ StringCanvas
|
|||
render_simple_text_impl(PyObject *s, const char *text) {
|
||||
Face *self = (Face*)s;
|
||||
StringCanvas ans = {0};
|
||||
size_t num_chars = strnlen(text, 20);
|
||||
size_t num_chars = strnlen(text, 32);
|
||||
int max_char_width = font_units_to_pixels_x(self, self->face->max_advance_width);
|
||||
size_t canvas_width = max_char_width * (num_chars*2);
|
||||
size_t canvas_height = font_units_to_pixels_y(self, self->face->height) + 8;
|
||||
unsigned char *canvas = calloc(1, canvas_width * canvas_height);
|
||||
if (!canvas) return ans;
|
||||
size_t pen_x = 0;
|
||||
for (size_t n = 0; n < num_chars; n++ ) {
|
||||
for (size_t n = 0; n < num_chars; n++) {
|
||||
FT_UInt glyph_index = FT_Get_Char_Index(self->face, text[n]);
|
||||
int error = FT_Load_Glyph(self->face, glyph_index, FT_LOAD_DEFAULT);
|
||||
if (error) continue;
|
||||
|
|
|
|||
13
kitty/glfw.c
13
kitty/glfw.c
|
|
@ -58,6 +58,17 @@ update_os_window_viewport(OSWindow *window, bool notify_boss) {
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
draw_resizing_window(OSWindow *w, unsigned int width, unsigned int height) {
|
||||
char text[32] = {0};
|
||||
blank_os_window(w);
|
||||
snprintf(text, sizeof(text), "%u x %u cells", width / w->fonts_data->cell_width, height / w->fonts_data->cell_height);
|
||||
StringCanvas rendered = render_simple_text(w->fonts_data, text);
|
||||
if (rendered.canvas) {
|
||||
draw_centered_alpha_mask(w->gvao_idx, width, height, rendered.width, rendered.height, rendered.canvas);
|
||||
free(rendered.canvas);
|
||||
}
|
||||
}
|
||||
|
||||
// callbacks {{{
|
||||
|
||||
|
|
@ -153,7 +164,7 @@ framebuffer_size_callback(GLFWwindow *w, int width, int height) {
|
|||
// you get partially rendered windows.
|
||||
make_os_window_context_current(window);
|
||||
update_surface_size(width, height, window->offscreen_texture_id);
|
||||
blank_os_window(window);
|
||||
draw_resizing_window(window, MAX(0, width), MAX(0, height));
|
||||
swap_window_buffers(window);
|
||||
request_tick_callback();
|
||||
} else log_error("Ignoring resize request for tiny size: %dx%d", width, height);
|
||||
|
|
|
|||
|
|
@ -522,6 +522,24 @@ cmp_by_zindex_and_image(const void *a_, const void *b_) {
|
|||
return ans;
|
||||
}
|
||||
|
||||
static inline void
|
||||
set_vertex_data(ImageRenderData *rd, const ImageRef *ref, const ImageRect *source_rect) {
|
||||
#define R(n, a, b) rd->vertices[n*4] = ref->src_rect.a; rd->vertices[n*4 + 1] = ref->src_rect.b; rd->vertices[n*4 + 2] = source_rect->a; rd->vertices[n*4 + 3] = source_rect->b;
|
||||
R(0, right, top); R(1, right, bottom); R(2, left, bottom); R(3, left, top);
|
||||
#undef R
|
||||
}
|
||||
|
||||
void
|
||||
gpu_data_for_centered_image(ImageRenderData *ans, unsigned int screen_width_px, unsigned int screen_height_px, unsigned int width, unsigned int height) {
|
||||
static const ImageRef source_rect = { .src_rect = { .left=0, .top=0, .bottom=1, .right=1 }};
|
||||
const ImageRef *ref = &source_rect;
|
||||
float width_frac = width / (float)screen_width_px, height_frac = height / (float)screen_height_px;
|
||||
float hmargin = MAX(0, 2 - width_frac) / 2;
|
||||
float vmargin = MAX(0, 2 - height_frac) / 2;
|
||||
const ImageRect r = { .left = -1 + hmargin, .right = -1 + hmargin + width_frac, .top = -1 + vmargin, .bottom = -1 + vmargin + height_frac };
|
||||
set_vertex_data(ans, ref, &r);
|
||||
}
|
||||
|
||||
bool
|
||||
grman_update_layers(GraphicsManager *self, unsigned int scrolled_by, float screen_left, float screen_top, float dx, float dy, unsigned int num_cols, unsigned int num_rows, CellPixelSize cell) {
|
||||
if (self->last_scrolled_by != scrolled_by) self->layers_dirty = true;
|
||||
|
|
@ -553,9 +571,7 @@ grman_update_layers(GraphicsManager *self, unsigned int scrolled_by, float scree
|
|||
if (ref->z_index < 0) self->num_of_negative_refs++; else self->num_of_positive_refs++;
|
||||
ensure_space_for(self, render_data, ImageRenderData, self->count + 1, capacity, 64, true);
|
||||
ImageRenderData *rd = self->render_data + self->count;
|
||||
#define R(n, a, b) rd->vertices[n*4] = ref->src_rect.a; rd->vertices[n*4 + 1] = ref->src_rect.b; rd->vertices[n*4 + 2] = r.a; rd->vertices[n*4 + 3] = r.b;
|
||||
R(0, right, top); R(1, right, bottom); R(2, left, bottom); R(3, left, top);
|
||||
#undef R
|
||||
set_vertex_data(rd, ref, &r);
|
||||
self->count++;
|
||||
rd->z_index = ref->z_index; rd->image_id = img->internal_id;
|
||||
rd->texture_id = img->texture_id;
|
||||
|
|
|
|||
|
|
@ -89,3 +89,4 @@ bool grman_update_layers(GraphicsManager *self, unsigned int scrolled_by, float
|
|||
void grman_scroll_images(GraphicsManager *self, const ScrollData*, CellPixelSize fg);
|
||||
void grman_resize(GraphicsManager*, index_type, index_type, index_type, index_type);
|
||||
void grman_rescale(GraphicsManager *self, CellPixelSize fg);
|
||||
void gpu_data_for_centered_image(ImageRenderData *ans, unsigned int screen_width_px, unsigned int screen_height_px, unsigned int width, unsigned int height);
|
||||
|
|
|
|||
|
|
@ -2,15 +2,38 @@
|
|||
#define ALPHA_TYPE
|
||||
|
||||
uniform sampler2D image;
|
||||
#ifdef ALPHA_MASK
|
||||
uniform uint fg;
|
||||
#else
|
||||
uniform float inactive_text_alpha;
|
||||
#endif
|
||||
|
||||
in vec2 texcoord;
|
||||
out vec4 color;
|
||||
|
||||
#ifdef ALPHA_MASK
|
||||
const uint BYTE_MASK = uint(0xFF);
|
||||
|
||||
vec3 color_to_vec(uint c) {
|
||||
uint r, g, b;
|
||||
r = (c >> 16) & BYTE_MASK;
|
||||
g = (c >> 8) & BYTE_MASK;
|
||||
b = c & BYTE_MASK;
|
||||
return vec3(float(r) / 255.0, float(g) / 255.0, float(b) / 255.0);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
void main() {
|
||||
#ifdef ALPHA_MASK
|
||||
color = texture(image, texcoord);
|
||||
vec3 fg_col = color_to_vec(fg);
|
||||
color = vec4(color.r * fg_col.r, color.r * fg_col.g, color.r * fg_col.b, 1.0);
|
||||
#else
|
||||
color = texture(image, texcoord);
|
||||
color.a *= inactive_text_alpha;
|
||||
#ifdef PREMULT
|
||||
color = vec4(color.rgb * color.a, color.a);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
#include "fonts.h"
|
||||
#include "gl.h"
|
||||
|
||||
enum { CELL_PROGRAM, CELL_BG_PROGRAM, CELL_SPECIAL_PROGRAM, CELL_FG_PROGRAM, BORDERS_PROGRAM, GRAPHICS_PROGRAM, GRAPHICS_PREMULT_PROGRAM, BLIT_PROGRAM, NUM_PROGRAMS };
|
||||
enum { CELL_PROGRAM, CELL_BG_PROGRAM, CELL_SPECIAL_PROGRAM, CELL_FG_PROGRAM, BORDERS_PROGRAM, GRAPHICS_PROGRAM, GRAPHICS_PREMULT_PROGRAM, GRAPHICS_ALPHA_MASK_PROGRAM, BLIT_PROGRAM, NUM_PROGRAMS };
|
||||
enum { SPRITE_MAP_UNIT, GRAPHICS_UNIT, BLIT_UNIT };
|
||||
|
||||
// Sprites {{{
|
||||
|
|
@ -210,7 +210,8 @@ create_graphics_vao() {
|
|||
|
||||
struct CellUniformData {
|
||||
bool constants_set;
|
||||
GLint gploc, gpploc, cploc, cfploc;
|
||||
bool alpha_mask_fg_set;
|
||||
GLint gploc, gpploc, cploc, cfploc, fg_loc;
|
||||
GLfloat prev_inactive_text_alpha;
|
||||
};
|
||||
|
||||
|
|
@ -323,6 +324,27 @@ draw_graphics(int program, ssize_t vao_idx, ssize_t gvao_idx, ImageRenderData *d
|
|||
bind_vertex_array(vao_idx);
|
||||
}
|
||||
|
||||
void
|
||||
draw_centered_alpha_mask(ssize_t gvao_idx, size_t screen_width, size_t screen_height, size_t width, size_t height, uint8_t *canvas) {
|
||||
static ImageRenderData data = {.group_count=1};
|
||||
gpu_data_for_centered_image(&data, screen_width, screen_height, width, height);
|
||||
if (!data.texture_id) { glGenTextures(1, &data.texture_id); }
|
||||
glBindTexture(GL_TEXTURE_2D, data.texture_id);
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, width, height, 0, GL_RED, GL_UNSIGNED_BYTE, canvas);
|
||||
bind_program(GRAPHICS_ALPHA_MASK_PROGRAM);
|
||||
if (!cell_uniform_data.alpha_mask_fg_set) {
|
||||
cell_uniform_data.alpha_mask_fg_set = true;
|
||||
glUniform1i(glGetUniformLocation(program_id(GRAPHICS_ALPHA_MASK_PROGRAM), "image"), GRAPHICS_UNIT);
|
||||
glUniform1ui(glGetUniformLocation(program_id(GRAPHICS_ALPHA_MASK_PROGRAM), "fg"), OPT(foreground));
|
||||
}
|
||||
draw_graphics(GRAPHICS_ALPHA_MASK_PROGRAM, 0, gvao_idx, &data, 0, 1);
|
||||
}
|
||||
|
||||
#define BLEND_ONTO_OPAQUE glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // blending onto opaque colors
|
||||
#define BLEND_PREMULT glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); // blending of pre-multiplied colors
|
||||
|
||||
|
|
@ -414,7 +436,8 @@ set_cell_uniforms(float current_inactive_text_alpha) {
|
|||
cell_uniform_data.cploc = glGetUniformLocation(program_id(CELL_PROGRAM), "inactive_text_alpha");
|
||||
cell_uniform_data.cfploc = glGetUniformLocation(program_id(CELL_FG_PROGRAM), "inactive_text_alpha");
|
||||
#define S(prog, name, val, type) { bind_program(prog); glUniform##type(glGetUniformLocation(program_id(prog), #name), val); }
|
||||
S(GRAPHICS_PROGRAM, image, GRAPHICS_UNIT, 1i); S(GRAPHICS_PREMULT_PROGRAM, image, GRAPHICS_UNIT, 1i);
|
||||
S(GRAPHICS_PROGRAM, image, GRAPHICS_UNIT, 1i);
|
||||
S(GRAPHICS_PREMULT_PROGRAM, image, GRAPHICS_UNIT, 1i);
|
||||
S(CELL_PROGRAM, sprites, SPRITE_MAP_UNIT, 1i); S(CELL_FG_PROGRAM, sprites, SPRITE_MAP_UNIT, 1i);
|
||||
S(CELL_PROGRAM, dim_opacity, OPT(dim_opacity), 1f); S(CELL_FG_PROGRAM, dim_opacity, OPT(dim_opacity), 1f);
|
||||
#undef S
|
||||
|
|
@ -632,7 +655,7 @@ static PyMethodDef module_methods[] = {
|
|||
bool
|
||||
init_shaders(PyObject *module) {
|
||||
#define C(x) if (PyModule_AddIntConstant(module, #x, x) != 0) { PyErr_NoMemory(); return false; }
|
||||
C(CELL_PROGRAM); C(CELL_BG_PROGRAM); C(CELL_SPECIAL_PROGRAM); C(CELL_FG_PROGRAM); C(BORDERS_PROGRAM); C(GRAPHICS_PROGRAM); C(GRAPHICS_PREMULT_PROGRAM); C(BLIT_PROGRAM);
|
||||
C(CELL_PROGRAM); C(CELL_BG_PROGRAM); C(CELL_SPECIAL_PROGRAM); C(CELL_FG_PROGRAM); C(BORDERS_PROGRAM); C(GRAPHICS_PROGRAM); C(GRAPHICS_PREMULT_PROGRAM); C(GRAPHICS_ALPHA_MASK_PROGRAM); C(BLIT_PROGRAM);
|
||||
C(GLSL_VERSION);
|
||||
C(GL_VERSION);
|
||||
C(GL_VENDOR);
|
||||
|
|
|
|||
|
|
@ -81,6 +81,7 @@ add_os_window() {
|
|||
memset(ans, 0, sizeof(OSWindow));
|
||||
ans->id = ++global_state.os_window_id_counter;
|
||||
ans->tab_bar_render_data.vao_idx = create_cell_vao();
|
||||
ans->gvao_idx = create_graphics_vao();
|
||||
ans->background_opacity = OPT(background_opacity);
|
||||
ans->font_sz_in_pts = global_state.font_sz_in_pts;
|
||||
END_WITH_OS_WINDOW_REFS
|
||||
|
|
@ -180,6 +181,7 @@ destroy_os_window_item(OSWindow *w) {
|
|||
Py_CLEAR(w->window_title); Py_CLEAR(w->tab_bar_render_data.screen);
|
||||
if (w->offscreen_texture_id) free_texture(&w->offscreen_texture_id);
|
||||
remove_vao(w->tab_bar_render_data.vao_idx);
|
||||
remove_vao(w->gvao_idx);
|
||||
free(w->tabs); w->tabs = NULL;
|
||||
}
|
||||
|
||||
|
|
@ -384,6 +386,7 @@ PYWRAP1(set_options) {
|
|||
S(click_interval, PyFloat_AsDouble);
|
||||
S(url_color, color_as_int);
|
||||
S(background, color_as_int);
|
||||
S(foreground, color_as_int);
|
||||
S(active_border_color, color_as_int);
|
||||
S(inactive_border_color, color_as_int);
|
||||
S(bell_border_color, color_as_int);
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ typedef struct {
|
|||
unsigned int url_style;
|
||||
unsigned int scrollback_pager_history_size;
|
||||
char_type select_by_word_characters[256]; size_t select_by_word_characters_count;
|
||||
color_type url_color, background, active_border_color, inactive_border_color, bell_border_color;
|
||||
color_type url_color, background, foreground, active_border_color, inactive_border_color, bell_border_color;
|
||||
double repaint_delay, input_delay;
|
||||
bool focus_follows_mouse, hide_window_decorations;
|
||||
bool macos_hide_from_tasks, macos_quit_when_last_window_closed, macos_window_resizable, macos_traditional_fullscreen, macos_show_window_title_in_menubar;
|
||||
|
|
@ -144,6 +144,7 @@ typedef struct {
|
|||
double pending_scroll_pixels;
|
||||
enum RENDER_STATE render_state;
|
||||
id_type last_focused_counter;
|
||||
ssize_t gvao_idx;
|
||||
} OSWindow;
|
||||
|
||||
|
||||
|
|
@ -205,6 +206,7 @@ ssize_t create_graphics_vao();
|
|||
ssize_t create_border_vao();
|
||||
bool send_cell_data_to_gpu(ssize_t, ssize_t, float, float, float, float, Screen *, OSWindow *);
|
||||
void draw_cells(ssize_t, ssize_t, float, float, float, float, Screen *, OSWindow *, bool, bool);
|
||||
void draw_centered_alpha_mask(ssize_t gvao_idx, size_t screen_width, size_t screen_height, size_t width, size_t height, uint8_t *canvas);
|
||||
void update_surface_size(int, int, uint32_t);
|
||||
void free_texture(uint32_t*);
|
||||
void send_image_to_gpu(uint32_t*, const void*, int32_t, int32_t, bool, bool);
|
||||
|
|
|
|||
|
|
@ -16,14 +16,15 @@
|
|||
)
|
||||
from .fast_data_types import (
|
||||
BLIT_PROGRAM, CELL_BG_PROGRAM, CELL_FG_PROGRAM, CELL_PROGRAM,
|
||||
CELL_SPECIAL_PROGRAM, CSI, DCS, DECORATION, DIM, GRAPHICS_PREMULT_PROGRAM,
|
||||
GRAPHICS_PROGRAM, OSC, REVERSE, SCROLL_FULL, SCROLL_LINE, SCROLL_PAGE,
|
||||
STRIKETHROUGH, Screen, add_window, cell_size_for_window, compile_program,
|
||||
get_clipboard_string, init_cell_program,
|
||||
set_clipboard_string, set_titlebar_color, set_window_render_data,
|
||||
update_window_title, update_window_visibility, viewport_for_window
|
||||
CELL_SPECIAL_PROGRAM, CSI, DCS, DECORATION, DIM,
|
||||
GRAPHICS_ALPHA_MASK_PROGRAM, GRAPHICS_PREMULT_PROGRAM, GRAPHICS_PROGRAM,
|
||||
OSC, REVERSE, SCROLL_FULL, SCROLL_LINE, SCROLL_PAGE, STRIKETHROUGH, Screen,
|
||||
add_window, cell_size_for_window, compile_program, get_clipboard_string,
|
||||
init_cell_program, set_clipboard_string, set_titlebar_color,
|
||||
set_window_render_data, update_window_title, update_window_visibility,
|
||||
viewport_for_window
|
||||
)
|
||||
from .keys import keyboard_mode_name, extended_key_event, defines
|
||||
from .keys import defines, extended_key_event, keyboard_mode_name
|
||||
from .rgb import to_color
|
||||
from .terminfo import get_capabilities
|
||||
from .utils import (
|
||||
|
|
@ -87,6 +88,7 @@ def color_as_vec3(x):
|
|||
for which, p in {
|
||||
'SIMPLE': GRAPHICS_PROGRAM,
|
||||
'PREMULT': GRAPHICS_PREMULT_PROGRAM,
|
||||
'ALPHA_MASK': GRAPHICS_ALPHA_MASK_PROGRAM,
|
||||
}.items():
|
||||
ff = f.replace('ALPHA_TYPE', which)
|
||||
compile_program(p, v, ff)
|
||||
|
|
|
|||
Loading…
Reference in a new issue