Implement rending of visual select chars on macOS
This commit is contained in:
parent
9517c3500d
commit
c241524663
@ -496,12 +496,7 @@ ensure_render_space(size_t width, size_t height, size_t num_glyphs) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
render_glyphs(CTFontRef font, unsigned int width, unsigned int height, unsigned int baseline, unsigned int num_glyphs) {
|
setup_ctx_for_alpha_mask(CGContextRef render_ctx) {
|
||||||
memset(buffers.render_buf, 0, width * height);
|
|
||||||
CGColorSpaceRef gray_color_space = CGColorSpaceCreateDeviceGray();
|
|
||||||
if (gray_color_space == NULL) fatal("Out of memory");
|
|
||||||
CGContextRef render_ctx = CGBitmapContextCreate(buffers.render_buf, width, height, 8, width, gray_color_space, (kCGBitmapAlphaInfoMask & kCGImageAlphaNone));
|
|
||||||
if (render_ctx == NULL) fatal("Out of memory");
|
|
||||||
CGContextSetShouldAntialias(render_ctx, true);
|
CGContextSetShouldAntialias(render_ctx, true);
|
||||||
CGContextSetShouldSmoothFonts(render_ctx, true);
|
CGContextSetShouldSmoothFonts(render_ctx, true);
|
||||||
CGContextSetGrayFillColor(render_ctx, 1, 1); // white glyphs
|
CGContextSetGrayFillColor(render_ctx, 1, 1); // white glyphs
|
||||||
@ -509,10 +504,20 @@ render_glyphs(CTFontRef font, unsigned int width, unsigned int height, unsigned
|
|||||||
CGContextSetLineWidth(render_ctx, OPT(macos_thicken_font));
|
CGContextSetLineWidth(render_ctx, OPT(macos_thicken_font));
|
||||||
CGContextSetTextDrawingMode(render_ctx, kCGTextFillStroke);
|
CGContextSetTextDrawingMode(render_ctx, kCGTextFillStroke);
|
||||||
CGContextSetTextMatrix(render_ctx, CGAffineTransformIdentity);
|
CGContextSetTextMatrix(render_ctx, CGAffineTransformIdentity);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
render_glyphs(CTFontRef font, unsigned int width, unsigned int height, unsigned int baseline, unsigned int num_glyphs) {
|
||||||
|
memset(buffers.render_buf, 0, width * height);
|
||||||
|
CGColorSpaceRef gray_color_space = CGColorSpaceCreateDeviceGray();
|
||||||
|
if (gray_color_space == NULL) fatal("Out of memory");
|
||||||
|
CGContextRef render_ctx = CGBitmapContextCreate(buffers.render_buf, width, height, 8, width, gray_color_space, (kCGBitmapAlphaInfoMask & kCGImageAlphaNone));
|
||||||
|
CGColorSpaceRelease(gray_color_space);
|
||||||
|
if (render_ctx == NULL) fatal("Out of memory");
|
||||||
|
setup_ctx_for_alpha_mask(render_ctx);
|
||||||
CGContextSetTextPosition(render_ctx, 0, height - baseline);
|
CGContextSetTextPosition(render_ctx, 0, height - baseline);
|
||||||
CTFontDrawGlyphs(font, buffers.glyphs, buffers.positions, num_glyphs, render_ctx);
|
CTFontDrawGlyphs(font, buffers.glyphs, buffers.positions, num_glyphs, render_ctx);
|
||||||
CGContextRelease(render_ctx);
|
CGContextRelease(render_ctx);
|
||||||
CGColorSpaceRelease(gray_color_space);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
StringCanvas
|
StringCanvas
|
||||||
@ -575,9 +580,8 @@ cocoa_render_line_of_text(const char *text, const color_type fg, const color_typ
|
|||||||
CGContextSetShouldSmoothFonts(ctx, true); // sub-pixel antialias
|
CGContextSetShouldSmoothFonts(ctx, true); // sub-pixel antialias
|
||||||
CGContextSetRGBFillColor(ctx, ((bg >> 16) & 0xff) / 255.f, ((bg >> 8) & 0xff) / 255.f, (bg & 0xff) / 255.f, 1.f);
|
CGContextSetRGBFillColor(ctx, ((bg >> 16) & 0xff) / 255.f, ((bg >> 8) & 0xff) / 255.f, (bg & 0xff) / 255.f, 1.f);
|
||||||
CGContextFillRect(ctx, CGRectMake(0.0, 0.0, width, height));
|
CGContextFillRect(ctx, CGRectMake(0.0, 0.0, width, height));
|
||||||
CGAffineTransform transform = CGAffineTransformIdentity;
|
|
||||||
CGContextSetTextDrawingMode(ctx, kCGTextFill);
|
CGContextSetTextDrawingMode(ctx, kCGTextFill);
|
||||||
CGContextSetTextMatrix(ctx, transform);
|
CGContextSetTextMatrix(ctx, CGAffineTransformIdentity);
|
||||||
CGContextSetRGBFillColor(ctx, ((fg >> 16) & 0xff) / 255.f, ((fg >> 8) & 0xff) / 255.f, (fg & 0xff) / 255.f, 1.f);
|
CGContextSetRGBFillColor(ctx, ((fg >> 16) & 0xff) / 255.f, ((fg >> 8) & 0xff) / 255.f, (fg & 0xff) / 255.f, 1.f);
|
||||||
CGContextSetRGBStrokeColor(ctx, ((fg >> 16) & 0xff) / 255.f, ((fg >> 8) & 0xff) / 255.f, (fg & 0xff) / 255.f, 1.f);
|
CGContextSetRGBStrokeColor(ctx, ((fg >> 16) & 0xff) / 255.f, ((fg >> 8) & 0xff) / 255.f, (fg & 0xff) / 255.f, 1.f);
|
||||||
|
|
||||||
@ -595,6 +599,34 @@ cocoa_render_line_of_text(const char *text, const color_type fg, const color_typ
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint8_t*
|
||||||
|
render_single_ascii_char_as_mask(const char ch, size_t *result_width, size_t *result_height) {
|
||||||
|
if (!ensure_ui_font(*result_height)) { PyErr_SetString(PyExc_RuntimeError, "failed to create UI font"); return NULL; }
|
||||||
|
unichar chars = ch;
|
||||||
|
CGSize local_advances[1];
|
||||||
|
CTFontGetGlyphsForCharacters(window_title_font, &chars, buffers.glyphs, 1);
|
||||||
|
CTFontGetAdvancesForGlyphs(window_title_font, kCTFontOrientationDefault, buffers.glyphs, local_advances, 1);
|
||||||
|
CGRect bounding_box = CTFontGetBoundingRectsForGlyphs(window_title_font, kCTFontOrientationDefault, buffers.glyphs, buffers.boxes, 1);
|
||||||
|
|
||||||
|
size_t width = (size_t)ceilf(bounding_box.size.width);
|
||||||
|
size_t height = (size_t)ceilf(bounding_box.size.height);
|
||||||
|
uint8_t *canvas = calloc(width, height);
|
||||||
|
if (!canvas) { PyErr_NoMemory(); return NULL; }
|
||||||
|
CGColorSpaceRef gray_color_space = CGColorSpaceCreateDeviceGray();
|
||||||
|
if (gray_color_space == NULL) { PyErr_NoMemory(); free(canvas); return NULL; }
|
||||||
|
CGContextRef render_ctx = CGBitmapContextCreate(canvas, width, height, 8, width, gray_color_space, (kCGBitmapAlphaInfoMask & kCGImageAlphaNone));
|
||||||
|
CGColorSpaceRelease(gray_color_space);
|
||||||
|
if (render_ctx == NULL) { PyErr_NoMemory(); free(canvas); return NULL; }
|
||||||
|
setup_ctx_for_alpha_mask(render_ctx);
|
||||||
|
/* printf("origin.y: %f descent: %f ascent: %f height: %zu size.height: %f\n", bounding_box.origin.y, CTFontGetDescent(window_title_font), CTFontGetAscent(window_title_font), height, bounding_box.size.height); */
|
||||||
|
CGContextSetTextPosition(render_ctx, 0, -bounding_box.origin.y);
|
||||||
|
CTFontDrawGlyphs(window_title_font, buffers.glyphs, buffers.positions, 1, render_ctx);
|
||||||
|
CGContextRelease(render_ctx);
|
||||||
|
*result_width = width; *result_height = height;
|
||||||
|
return canvas;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
do_render(CTFontRef ct_font, bool bold, bool italic, hb_glyph_info_t *info, hb_glyph_position_t *hb_positions, unsigned int num_glyphs, pixel *canvas, unsigned int cell_width, unsigned int cell_height, unsigned int num_cells, unsigned int baseline, bool *was_colored, bool allow_resize, FONTS_DATA_HANDLE fg, bool center_glyph) {
|
do_render(CTFontRef ct_font, bool bold, bool italic, hb_glyph_info_t *info, hb_glyph_position_t *hb_positions, unsigned int num_glyphs, pixel *canvas, unsigned int cell_width, unsigned int cell_height, unsigned int num_cells, unsigned int baseline, bool *was_colored, bool allow_resize, FONTS_DATA_HANDLE fg, bool center_glyph) {
|
||||||
unsigned int canvas_width = cell_width * num_cells;
|
unsigned int canvas_width = cell_width * num_cells;
|
||||||
|
|||||||
10
kitty/glfw.c
10
kitty/glfw.c
@ -418,6 +418,16 @@ bool
|
|||||||
draw_window_title(OSWindow *window UNUSED, const char *text, color_type fg, color_type bg, uint8_t *output_buf, size_t width, size_t height) {
|
draw_window_title(OSWindow *window UNUSED, const char *text, color_type fg, color_type bg, uint8_t *output_buf, size_t width, size_t height) {
|
||||||
return cocoa_render_line_of_text(text, fg, bg, output_buf, width, height);
|
return cocoa_render_line_of_text(text, fg, bg, output_buf, width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern uint8_t* render_single_ascii_char_as_mask(const char ch, size_t *result_width, size_t *result_height);
|
||||||
|
|
||||||
|
uint8_t*
|
||||||
|
draw_single_ascii_char(const char ch, size_t *result_width, size_t *result_height) {
|
||||||
|
uint8_t *ans = render_single_ascii_char_as_mask(ch, result_width, result_height);
|
||||||
|
if (PyErr_Occurred()) PyErr_Print();
|
||||||
|
return ans;
|
||||||
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
static FreeTypeRenderCtx csd_title_render_ctx = NULL;
|
static FreeTypeRenderCtx csd_title_render_ctx = NULL;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user