Merge branch 'strikethrough-info-from-font' of https://github.com/trygveaa/kitty
This commit is contained in:
@@ -312,7 +312,7 @@ harfbuzz_font_for_face(PyObject* s) {
|
||||
}
|
||||
|
||||
void
|
||||
cell_metrics(PyObject *s, unsigned int* cell_width, unsigned int* cell_height, unsigned int* baseline, unsigned int* underline_position, unsigned int* underline_thickness) {
|
||||
cell_metrics(PyObject *s, unsigned int* cell_width, unsigned int* cell_height, unsigned int* baseline, unsigned int* underline_position, unsigned int* underline_thickness, unsigned int* strikethrough_position, unsigned int* strikethrough_thickness) {
|
||||
// See https://developer.apple.com/library/content/documentation/StringsTextFonts/Conceptual/TextAndWebiPhoneOS/TypoFeatures/TextSystemFeatures.html
|
||||
CTFace *self = (CTFace*)s;
|
||||
#define count (128 - 32)
|
||||
@@ -332,6 +332,8 @@ cell_metrics(PyObject *s, unsigned int* cell_width, unsigned int* cell_height, u
|
||||
*underline_position = (unsigned int)floor(self->ascent - self->underline_position + 0.5);
|
||||
*underline_thickness = (unsigned int)ceil(MAX(0.1, self->underline_thickness));
|
||||
*baseline = (unsigned int)self->ascent;
|
||||
*strikethrough_position = (unsigned int)floor(*baseline * 0.65);
|
||||
*strikethrough_thickness = *underline_thickness;
|
||||
// float line_height = MAX(1, floor(self->ascent + self->descent + MAX(0, self->leading) + 0.5));
|
||||
// Let CoreText's layout engine calculate the line height. Slower, but hopefully more accurate.
|
||||
#define W "AQWMH_gyl "
|
||||
|
||||
@@ -902,7 +902,7 @@ def set_font_data(
|
||||
box_drawing_func: Callable[[int, int, int, float],
|
||||
Tuple[int, Union[bytearray, bytes, Array]]],
|
||||
prerender_func: Callable[
|
||||
[int, int, int, int, int, float, float, float, float],
|
||||
[int, int, int, int, int, int, int, float, float, float, float],
|
||||
Tuple[Union[Array, int], ...]],
|
||||
descriptor_for_idx: Callable[[int], Tuple[FontObject, bool, bool]],
|
||||
bold: int, italic: int, bold_italic: int, num_symbol_fonts: int,
|
||||
|
||||
@@ -85,7 +85,7 @@ typedef struct {
|
||||
typedef struct {
|
||||
FONTS_DATA_HEAD
|
||||
id_type id;
|
||||
unsigned int baseline, underline_position, underline_thickness;
|
||||
unsigned int baseline, underline_position, underline_thickness, strikethrough_position, strikethrough_thickness;
|
||||
size_t fonts_capacity, fonts_count, fallback_fonts_count;
|
||||
ssize_t medium_font_idx, bold_font_idx, italic_font_idx, bi_font_idx, first_symbol_font_idx, first_fallback_font_idx;
|
||||
Font *fonts;
|
||||
@@ -422,8 +422,8 @@ python_send_to_gpu(FONTS_DATA_HANDLE fg, unsigned int x, unsigned int y, unsigne
|
||||
|
||||
static inline void
|
||||
calc_cell_metrics(FontGroup *fg) {
|
||||
unsigned int cell_height, cell_width, baseline, underline_position, underline_thickness;
|
||||
cell_metrics(fg->fonts[fg->medium_font_idx].face, &cell_width, &cell_height, &baseline, &underline_position, &underline_thickness);
|
||||
unsigned int cell_height, cell_width, baseline, underline_position, underline_thickness, strikethrough_position, strikethrough_thickness;
|
||||
cell_metrics(fg->fonts[fg->medium_font_idx].face, &cell_width, &cell_height, &baseline, &underline_position, &underline_thickness, &strikethrough_position, &strikethrough_thickness);
|
||||
if (!cell_width) fatal("Failed to calculate cell width for the specified font");
|
||||
unsigned int before_cell_height = cell_height;
|
||||
int cw = cell_width, ch = cell_height;
|
||||
@@ -455,7 +455,7 @@ calc_cell_metrics(FontGroup *fg) {
|
||||
}
|
||||
sprite_tracker_set_layout(&fg->sprite_tracker, cell_width, cell_height);
|
||||
fg->cell_width = cell_width; fg->cell_height = cell_height;
|
||||
fg->baseline = baseline; fg->underline_position = underline_position; fg->underline_thickness = underline_thickness;
|
||||
fg->baseline = baseline; fg->underline_position = underline_position; fg->underline_thickness = underline_thickness, fg->strikethrough_position = strikethrough_position, fg->strikethrough_thickness = strikethrough_thickness;
|
||||
free(fg->canvas);
|
||||
fg->canvas = calloc(CELLS_IN_CANVAS * fg->cell_width * fg->cell_height, sizeof(pixel));
|
||||
if (!fg->canvas) fatal("Out of memory allocating canvas for font group");
|
||||
@@ -1243,7 +1243,7 @@ send_prerendered_sprites(FontGroup *fg) {
|
||||
current_send_sprite_to_gpu((FONTS_DATA_HANDLE)fg, x, y, z, fg->canvas);
|
||||
do_increment(fg, &error);
|
||||
if (error != 0) { sprite_map_set_error(error); PyErr_Print(); fatal("Failed"); }
|
||||
PyObject *args = PyObject_CallFunction(prerender_function, "IIIIIffdd", fg->cell_width, fg->cell_height, fg->baseline, fg->underline_position, fg->underline_thickness, OPT(cursor_beam_thickness), OPT(cursor_underline_thickness), fg->logical_dpi_x, fg->logical_dpi_y);
|
||||
PyObject *args = PyObject_CallFunction(prerender_function, "IIIIIIIffdd", fg->cell_width, fg->cell_height, fg->baseline, fg->underline_position, fg->underline_thickness, fg->strikethrough_position, fg->strikethrough_thickness, OPT(cursor_beam_thickness), OPT(cursor_underline_thickness), fg->logical_dpi_x, fg->logical_dpi_y);
|
||||
if (args == NULL) { PyErr_Print(); fatal("Failed to pre-render cells"); }
|
||||
for (ssize_t i = 0; i < PyTuple_GET_SIZE(args) - 1; i++) {
|
||||
x = fg->sprite_tracker.x; y = fg->sprite_tracker.y; z = fg->sprite_tracker.z;
|
||||
|
||||
@@ -25,7 +25,7 @@ int get_glyph_width(PyObject *, glyph_index);
|
||||
bool is_glyph_empty(PyObject *, glyph_index);
|
||||
hb_font_t* harfbuzz_font_for_face(PyObject*);
|
||||
bool set_size_for_face(PyObject*, unsigned int, bool, FONTS_DATA_HANDLE);
|
||||
void cell_metrics(PyObject*, unsigned int*, unsigned int*, unsigned int*, unsigned int*, unsigned int*);
|
||||
void cell_metrics(PyObject*, unsigned int*, unsigned int*, unsigned int*, unsigned int*, unsigned int*, unsigned int*, unsigned int*);
|
||||
bool render_glyphs_in_cells(PyObject *f, bool bold, bool italic, hb_glyph_info_t *info, hb_glyph_position_t *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, FONTS_DATA_HANDLE, bool center_glyph);
|
||||
PyObject* create_fallback_face(PyObject *base_face, CPUCell* cell, bool bold, bool italic, bool emoji_presentation, FONTS_DATA_HANDLE fg);
|
||||
PyObject* specialize_font_descriptor(PyObject *base_descriptor, FONTS_DATA_HANDLE);
|
||||
|
||||
@@ -191,7 +191,9 @@ def render_special(
|
||||
cell_width: int = 0, cell_height: int = 0,
|
||||
baseline: int = 0,
|
||||
underline_position: int = 0,
|
||||
underline_thickness: int = 0
|
||||
underline_thickness: int = 0,
|
||||
strikethrough_position: int = 0,
|
||||
strikethrough_thickness: int = 0
|
||||
) -> ctypes.Array:
|
||||
underline_position = min(underline_position, cell_height - underline_thickness)
|
||||
CharTexture = ctypes.c_ubyte * (cell_width * cell_height)
|
||||
@@ -216,8 +218,7 @@ def render_special(
|
||||
t = max(1, min(cell_height - underline_position - 1, t))
|
||||
dl([add_line, add_line, add_dline, add_curl][underline], underline_position, t, cell_height)
|
||||
if strikethrough:
|
||||
pos = int(0.65 * baseline)
|
||||
dl(add_line, pos, underline_thickness, cell_height)
|
||||
dl(add_line, strikethrough_position, strikethrough_thickness, cell_height)
|
||||
|
||||
return ans
|
||||
|
||||
@@ -268,6 +269,8 @@ def prerender_function(
|
||||
baseline: int,
|
||||
underline_position: int,
|
||||
underline_thickness: int,
|
||||
strikethrough_position: int,
|
||||
strikethrough_thickness: int,
|
||||
cursor_beam_thickness: float,
|
||||
cursor_underline_thickness: float,
|
||||
dpi_x: float,
|
||||
@@ -276,7 +279,8 @@ def prerender_function(
|
||||
# Pre-render the special underline, strikethrough and missing and cursor cells
|
||||
f = partial(
|
||||
render_special, cell_width=cell_width, cell_height=cell_height, baseline=baseline,
|
||||
underline_position=underline_position, underline_thickness=underline_thickness)
|
||||
underline_position=underline_position, underline_thickness=underline_thickness,
|
||||
strikethrough_position=strikethrough_position, strikethrough_thickness=strikethrough_thickness)
|
||||
c = partial(
|
||||
render_cursor, cursor_beam_thickness=cursor_beam_thickness,
|
||||
cursor_underline_thickness=cursor_underline_thickness, cell_width=cell_width,
|
||||
|
||||
@@ -22,12 +22,13 @@
|
||||
|
||||
#include FT_FREETYPE_H
|
||||
#include FT_BITMAP_H
|
||||
#include FT_TRUETYPE_TABLES_H
|
||||
typedef struct {
|
||||
PyObject_HEAD
|
||||
|
||||
FT_Face face;
|
||||
unsigned int units_per_EM;
|
||||
int ascender, descender, height, max_advance_width, max_advance_height, underline_position, underline_thickness;
|
||||
int ascender, descender, height, max_advance_width, max_advance_height, underline_position, underline_thickness, strikethrough_position, strikethrough_thickness;
|
||||
int hinting, hintstyle, index;
|
||||
bool is_scalable, has_color;
|
||||
float size_in_pts;
|
||||
@@ -207,6 +208,12 @@ init_ft_face(Face *self, PyObject *path, int hinting, int hintstyle, FONTS_DATA_
|
||||
if (self->harfbuzz_font == NULL) { PyErr_NoMemory(); return false; }
|
||||
hb_ft_font_set_load_flags(self->harfbuzz_font, get_load_flags(self->hinting, self->hintstyle, FT_LOAD_DEFAULT));
|
||||
|
||||
TT_OS2 *os2 = (TT_OS2*)FT_Get_Sfnt_Table(self->face, FT_SFNT_OS2);
|
||||
if (os2 != NULL) {
|
||||
self->strikethrough_position = os2->yStrikeoutPosition;
|
||||
self->strikethrough_thickness = os2->yStrikeoutSize;
|
||||
}
|
||||
|
||||
self->path = path;
|
||||
Py_INCREF(self->path);
|
||||
self->index = self->face->face_index & 0xFFFF;
|
||||
@@ -263,11 +270,11 @@ static PyObject *
|
||||
repr(Face *self) {
|
||||
const char *ps_name = FT_Get_Postscript_Name(self->face);
|
||||
return PyUnicode_FromFormat(
|
||||
"Face(family=%s, style=%s, ps_name=%s, path=%S, index=%d, is_scalable=%S, has_color=%S, ascender=%i, descender=%i, height=%i, underline_position=%i, underline_thickness=%i)",
|
||||
"Face(family=%s, style=%s, ps_name=%s, path=%S, index=%d, is_scalable=%S, has_color=%S, ascender=%i, descender=%i, height=%i, underline_position=%i, underline_thickness=%i, strikethrough_position=%i, strikethrough_thickness=%i)",
|
||||
self->face->family_name ? self->face->family_name : "", self->face->style_name ? self->face->style_name : "",
|
||||
ps_name ? ps_name: "",
|
||||
self->path, self->index, self->is_scalable ? Py_True : Py_False, self->has_color ? Py_True : Py_False,
|
||||
self->ascender, self->descender, self->height, self->underline_position, self->underline_thickness
|
||||
self->ascender, self->descender, self->height, self->underline_position, self->underline_thickness, self->strikethrough_position, self->strikethrough_thickness
|
||||
);
|
||||
}
|
||||
|
||||
@@ -292,13 +299,24 @@ calc_cell_width(Face *self) {
|
||||
}
|
||||
|
||||
void
|
||||
cell_metrics(PyObject *s, unsigned int* cell_width, unsigned int* cell_height, unsigned int* baseline, unsigned int* underline_position, unsigned int* underline_thickness) {
|
||||
cell_metrics(PyObject *s, unsigned int* cell_width, unsigned int* cell_height, unsigned int* baseline, unsigned int* underline_position, unsigned int* underline_thickness, unsigned int* strikethrough_position, unsigned int* strikethrough_thickness) {
|
||||
Face *self = (Face*)s;
|
||||
*cell_width = calc_cell_width(self);
|
||||
*cell_height = calc_cell_height(self, true);
|
||||
*baseline = font_units_to_pixels_y(self, self->ascender);
|
||||
*underline_position = MIN(*cell_height - 1, (unsigned int)font_units_to_pixels_y(self, MAX(0, self->ascender - self->underline_position)));
|
||||
*underline_thickness = MAX(1, font_units_to_pixels_y(self, self->underline_thickness));
|
||||
|
||||
if (self->strikethrough_position != 0) {
|
||||
*strikethrough_position = MIN(*cell_height - 1, (unsigned int)font_units_to_pixels_y(self, MAX(0, self->ascender - self->strikethrough_position)));
|
||||
} else {
|
||||
*strikethrough_position = (unsigned int)floor(*baseline * 0.65);
|
||||
}
|
||||
if (self->strikethrough_thickness > 0) {
|
||||
*strikethrough_thickness = MAX(1, font_units_to_pixels_y(self, self->strikethrough_thickness));
|
||||
} else {
|
||||
*strikethrough_thickness = *underline_thickness;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int
|
||||
@@ -659,6 +677,8 @@ static PyMemberDef members[] = {
|
||||
MEM(max_advance_height, T_INT),
|
||||
MEM(underline_position, T_INT),
|
||||
MEM(underline_thickness, T_INT),
|
||||
MEM(strikethrough_position, T_INT),
|
||||
MEM(strikethrough_thickness, T_INT),
|
||||
MEM(is_scalable, T_BOOL),
|
||||
MEM(path, T_OBJECT_EX),
|
||||
{NULL} /* Sentinel */
|
||||
|
||||
Reference in New Issue
Block a user