Implement rendering of titles in CSD
This commit is contained in:
parent
e92ed67021
commit
5d496216e0
7 changed files with 34 additions and 9 deletions
2
glfw/glfw3.h
vendored
2
glfw/glfw3.h
vendored
|
|
@ -1683,7 +1683,7 @@ typedef void (* GLFWjoystickfun)(int,int);
|
|||
|
||||
typedef void (* GLFWuserdatafun)(unsigned long long, void*);
|
||||
typedef void (* GLFWtickcallback)(void*);
|
||||
typedef void (* GLFWdrawtextfun)(const char *text, uint32_t fg, uint32_t bg, uint8_t *output_buf, size_t width, size_t height, float x_offset, float y_offset);
|
||||
typedef bool (* GLFWdrawtextfun)(GLFWwindow *window, const char *text, uint32_t fg, uint32_t bg, uint8_t *output_buf, size_t width, size_t height, float x_offset, float y_offset);
|
||||
|
||||
/*! @brief Video mode type.
|
||||
*
|
||||
|
|
|
|||
3
glfw/wl_client_side_decorations.c
vendored
3
glfw/wl_client_side_decorations.c
vendored
|
|
@ -50,6 +50,9 @@ alloc_buffer_pair(_GLFWWaylandBufferPair *pair, struct wl_shm_pool *pool, uint8_
|
|||
static void
|
||||
render_title_bar(_GLFWwindow *window, bool to_front_buffer) {
|
||||
uint8_t *output = to_front_buffer ? decs.top.buffer.data.front : decs.top.buffer.data.back;
|
||||
if (window->wl.title && window->wl.title[0] && _glfw.callbacks.draw_text) {
|
||||
if (_glfw.callbacks.draw_text((GLFWwindow*)window, window->wl.title, 0, bg_color, output, decs.top.buffer.width, decs.top.buffer.height, 10, 0)) return;
|
||||
}
|
||||
for (uint32_t *px = (uint32_t*)output, *end = (uint32_t*)(output + decs.top.buffer.size_in_bytes); px < end; px++) {
|
||||
*px = bg_color;
|
||||
}
|
||||
|
|
|
|||
5
glfw/wl_window.c
vendored
5
glfw/wl_window.c
vendored
|
|
@ -817,7 +817,10 @@ void _glfwPlatformDestroyWindow(_GLFWwindow* window)
|
|||
|
||||
void _glfwPlatformSetWindowTitle(_GLFWwindow* window, const char* title)
|
||||
{
|
||||
if (window->wl.title) free(window->wl.title);
|
||||
if (window->wl.title) {
|
||||
if (title && strcmp(title, window->wl.title) == 0) return;
|
||||
free(window->wl.title);
|
||||
} else if (!title) return;
|
||||
// Wayland cannot handle requests larger than ~8200 bytes. Sending
|
||||
// one causes an abort(). Since titles this large are meaningless anyway
|
||||
// ensure they do not happen.
|
||||
|
|
|
|||
|
|
@ -99,7 +99,7 @@ load_font(FontConfigFace *info, Face *ans) {
|
|||
|
||||
static bool
|
||||
ensure_state(void) {
|
||||
if (main_face.freetype && main_face.hb) return false;
|
||||
if (main_face.freetype && main_face.hb) return true;
|
||||
if (!information_for_font_family(main_face_family.name, main_face_family.bold, main_face_family.italic, &main_face_information)) return false;
|
||||
if (!load_font(&main_face_information, &main_face)) return false;
|
||||
hb_buffer = hb_buffer_create();
|
||||
|
|
@ -147,6 +147,7 @@ typedef struct RenderState {
|
|||
Face *current_face;
|
||||
float x, y;
|
||||
Region src, dest;
|
||||
unsigned sz_px;
|
||||
} RenderState;
|
||||
|
||||
static void
|
||||
|
|
@ -227,7 +228,7 @@ render_run(RenderState *rs) {
|
|||
}
|
||||
FT_Face face = rs->current_face->freetype;
|
||||
bool has_color = FT_HAS_COLOR(face);
|
||||
FT_UInt pixel_size = 3 * rs->output_height / 4;
|
||||
FT_UInt pixel_size = rs->sz_px;
|
||||
set_pixel_size(rs->current_face, pixel_size, has_color);
|
||||
hb_shape(rs->current_face->hb, hb_buffer, NULL, 0);
|
||||
unsigned int len = hb_buffer_get_length(hb_buffer);
|
||||
|
|
@ -327,7 +328,7 @@ process_codepoint(RenderState *rs, char_type codep, char_type next_codep) {
|
|||
}
|
||||
|
||||
bool
|
||||
render_single_line(const char *text, pixel fg, pixel bg, uint8_t *output_buf, size_t width, size_t height, float x_offset, float y_offset) {
|
||||
render_single_line(const char *text, unsigned sz_px, pixel fg, pixel bg, uint8_t *output_buf, size_t width, size_t height, float x_offset, float y_offset) {
|
||||
if (!ensure_state()) return false;
|
||||
bool has_text = text && text[0];
|
||||
pixel pbg = premult_pixel(bg, ((bg >> 24) & 0xff));
|
||||
|
|
@ -343,7 +344,7 @@ render_single_line(const char *text, pixel fg, pixel bg, uint8_t *output_buf, si
|
|||
text_len = decode_utf8_string(text, text_len, unicode);
|
||||
RenderState rs = {
|
||||
.current_face = &main_face, .fg = fg, .bg = bg, .output_width = width, .output_height = height,
|
||||
.output = (pixel*)output_buf, .x = x_offset, .y = y_offset
|
||||
.output = (pixel*)output_buf, .x = x_offset, .y = y_offset, .sz_px = sz_px
|
||||
};
|
||||
|
||||
for (size_t i = 0; i < text_len && rs.x < rs.output_width; i++) {
|
||||
|
|
@ -376,7 +377,7 @@ render_line(PyObject *self UNUSED, PyObject *args, PyObject *kw) {
|
|||
PyObject *ans = PyBytes_FromStringAndSize(NULL, width * height * 4);
|
||||
if (!ans) return NULL;
|
||||
uint8_t *buffer = (u_int8_t*) PyBytes_AS_STRING(ans);
|
||||
if (!render_single_line(text, 0, 0xffffffff, buffer, width, height, x_offset, y_offset)) {
|
||||
if (!render_single_line(text, 3 * height / 4, 0, 0xffffffff, buffer, width, height, x_offset, y_offset)) {
|
||||
Py_CLEAR(ans);
|
||||
if (!PyErr_Occurred()) PyErr_SetString(PyExc_RuntimeError, "Unknown error while rendering text");
|
||||
ans = NULL;
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@
|
|||
#include "data-types.h"
|
||||
#include <hb-ft.h>
|
||||
|
||||
bool render_single_line(const char *text, uint32_t fg, uint32_t bg, uint8_t *output_buf, size_t width, size_t height, float x_offset, float y_offset);
|
||||
bool render_single_line(const char *text, unsigned sz_px, uint32_t fg, uint32_t bg, uint8_t *output_buf, size_t width, size_t height, float x_offset, float y_offset);
|
||||
|
||||
typedef struct FontConfigFace {
|
||||
char *path;
|
||||
|
|
|
|||
2
kitty/glfw-wrapper.h
generated
2
kitty/glfw-wrapper.h
generated
|
|
@ -1421,7 +1421,7 @@ typedef void (* GLFWjoystickfun)(int,int);
|
|||
|
||||
typedef void (* GLFWuserdatafun)(unsigned long long, void*);
|
||||
typedef void (* GLFWtickcallback)(void*);
|
||||
typedef void (* GLFWdrawtextfun)(const char *text, uint32_t fg, uint32_t bg, uint8_t *output_buf, size_t width, size_t height, float x_offset, float y_offset);
|
||||
typedef bool (* GLFWdrawtextfun)(GLFWwindow *window, const char *text, uint32_t fg, uint32_t bg, uint8_t *output_buf, size_t width, size_t height, float x_offset, float y_offset);
|
||||
|
||||
/*! @brief Video mode type.
|
||||
*
|
||||
|
|
|
|||
18
kitty/glfw.c
18
kitty/glfw.c
|
|
@ -10,6 +10,9 @@
|
|||
#include "charsets.h"
|
||||
#include <structmember.h>
|
||||
#include "glfw-wrapper.h"
|
||||
#ifndef __APPLE__
|
||||
#include "freetype_render_ui_text.h"
|
||||
#endif
|
||||
extern bool cocoa_make_window_resizable(void *w, bool);
|
||||
extern void cocoa_focus_window(void *w);
|
||||
extern long cocoa_window_number(void *w);
|
||||
|
|
@ -381,12 +384,25 @@ application_close_requested_callback(int flags) {
|
|||
}
|
||||
}
|
||||
|
||||
static inline void get_window_dpi(GLFWwindow *w, double *x, double *y);
|
||||
|
||||
#ifdef __APPLE__
|
||||
static bool
|
||||
apple_file_open_callback(const char* filepath) {
|
||||
set_cocoa_pending_action(OPEN_FILE, filepath);
|
||||
return true;
|
||||
}
|
||||
#else
|
||||
|
||||
static bool
|
||||
draw_text_callback(GLFWwindow *window, const char *text, uint32_t fg, uint32_t bg, uint8_t *output_buf, size_t width, size_t height, float x_offset, float y_offset) {
|
||||
if (!set_callback_window(window)) return false;
|
||||
double xdpi, ydpi;
|
||||
get_window_dpi(window, &xdpi, &ydpi);
|
||||
unsigned px_sz = (unsigned)(global_state.callback_os_window->font_sz_in_pts * ydpi / 72.);
|
||||
px_sz = MIN(px_sz, 3 * height / 4);
|
||||
return render_single_line(text, px_sz, fg, bg, output_buf, width, height, x_offset, y_offset);
|
||||
}
|
||||
#endif
|
||||
// }}}
|
||||
|
||||
|
|
@ -855,6 +871,8 @@ glfw_init(PyObject UNUSED *self, PyObject *args) {
|
|||
if (ans == Py_True) {
|
||||
#ifdef __APPLE__
|
||||
glfwSetCocoaFileOpenCallback(apple_file_open_callback);
|
||||
#else
|
||||
glfwSetDrawTextFunction(draw_text_callback);
|
||||
#endif
|
||||
OSWindow w = {0};
|
||||
set_os_window_dpi(&w);
|
||||
|
|
|
|||
Loading…
Reference in a new issue