Linux: Automatically increase cell height if the font being used is broken and draws the underscore outside the bounding box
See #690
This commit is contained in:
parent
4e9dabfb25
commit
1ae32b5742
@ -29,6 +29,9 @@ To update |kitty|, :doc:`follow the instructions <binary>`.
|
||||
- When resizing and only a single window is present in the current layout,
|
||||
use that window's background color to fill in the blank areas.
|
||||
|
||||
- Linux: Automatically increase cell height if the font being used is broken
|
||||
and draws the underscore outside the bounding box (:iss:`690`)
|
||||
|
||||
|
||||
0.14.0 [2019-05-24]
|
||||
---------------------
|
||||
|
||||
@ -280,7 +280,9 @@ cell_metrics(PyObject *s, unsigned int* cell_width, unsigned int* cell_height, u
|
||||
*baseline = (unsigned int)self->ascent;
|
||||
// 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.
|
||||
CFStringRef ts = CFSTR("test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test");
|
||||
#define W "AQWMH_gyl "
|
||||
CFStringRef ts = CFSTR(W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W);
|
||||
#undef W
|
||||
CFMutableAttributedStringRef test_string = CFAttributedStringCreateMutable(kCFAllocatorDefault, CFStringGetLength(ts));
|
||||
CFAttributedStringReplaceString(test_string, CFRangeMake(0, 0), ts);
|
||||
CFAttributedStringSetAttribute(test_string, CFRangeMake(0, CFStringGetLength(ts)), kCTFontAttributeName, self->ct_font);
|
||||
|
||||
@ -75,8 +75,6 @@ set_freetype_error(const char* prefix, int err_code) {
|
||||
|
||||
static FT_Library library;
|
||||
|
||||
#define CALC_CELL_HEIGHT(self) font_units_to_pixels_y(self, self->height)
|
||||
|
||||
static inline int
|
||||
font_units_to_pixels_y(Face *self, int x) {
|
||||
return ceil((double)FT_MulFix(x, self->face->size->metrics.y_scale) / 64.0);
|
||||
@ -87,11 +85,56 @@ font_units_to_pixels_x(Face *self, int x) {
|
||||
return ceil((double)FT_MulFix(x, self->face->size->metrics.x_scale) / 64.0);
|
||||
}
|
||||
|
||||
|
||||
static inline int
|
||||
get_load_flags(int hinting, int hintstyle, int base) {
|
||||
int flags = base;
|
||||
if (hinting) {
|
||||
if (hintstyle >= 3) flags |= FT_LOAD_TARGET_NORMAL;
|
||||
else if (0 < hintstyle && hintstyle < 3) flags |= FT_LOAD_TARGET_LIGHT;
|
||||
} else flags |= FT_LOAD_NO_HINTING;
|
||||
return flags;
|
||||
}
|
||||
|
||||
|
||||
static inline bool
|
||||
load_glyph(Face *self, int glyph_index, int load_type) {
|
||||
int flags = get_load_flags(self->hinting, self->hintstyle, load_type);
|
||||
int error = FT_Load_Glyph(self->face, glyph_index, flags);
|
||||
if (error) { set_freetype_error("Failed to load glyph, with error:", error); return false; }
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline unsigned int
|
||||
get_height_for_char(Face *self, char ch) {
|
||||
unsigned int ans = 0;
|
||||
int glyph_index = FT_Get_Char_Index(self->face, ch);
|
||||
if (load_glyph(self, glyph_index, FT_LOAD_DEFAULT)) {
|
||||
unsigned int baseline = font_units_to_pixels_y(self, self->ascender);
|
||||
FT_GlyphSlotRec *glyph = self->face->glyph;
|
||||
FT_Bitmap *bm = &glyph->bitmap;
|
||||
if (glyph->bitmap_top <= 0 || (glyph->bitmap_top > 0 && (unsigned int)glyph->bitmap_top < baseline)) {
|
||||
ans = baseline - glyph->bitmap_top + bm->rows;
|
||||
}
|
||||
}
|
||||
return ans;
|
||||
}
|
||||
|
||||
static inline unsigned int
|
||||
calc_cell_height(Face *self, bool for_metrics) {
|
||||
unsigned int ans = font_units_to_pixels_y(self, self->height);
|
||||
unsigned int underscore_height = get_height_for_char(self, '_');
|
||||
if (for_metrics && global_state.debug_font_fallback && underscore_height > ans) {
|
||||
printf("Increasing cell height by %u pixels to work around buggy font that renders underscore outside the bounding box\n", underscore_height - ans);
|
||||
}
|
||||
return MAX(ans, underscore_height);
|
||||
}
|
||||
|
||||
static inline bool
|
||||
set_font_size(Face *self, FT_F26Dot6 char_width, FT_F26Dot6 char_height, FT_UInt xdpi, FT_UInt ydpi, unsigned int desired_height, unsigned int cell_height) {
|
||||
int error = FT_Set_Char_Size(self->face, 0, char_height, xdpi, ydpi);
|
||||
if (!error) {
|
||||
unsigned int ch = CALC_CELL_HEIGHT(self);
|
||||
unsigned int ch = calc_cell_height(self, false);
|
||||
if (desired_height && ch != desired_height) {
|
||||
FT_F26Dot6 h = floor((double)char_height * (double)desired_height / (double) ch);
|
||||
return set_font_size(self, 0, h, xdpi, ydpi, 0, cell_height);
|
||||
@ -147,17 +190,6 @@ set_size_for_face(PyObject *s, unsigned int desired_height, bool force, FONTS_DA
|
||||
return set_font_size(self, w, w, xdpi, ydpi, desired_height, fg->cell_height);
|
||||
}
|
||||
|
||||
static inline int
|
||||
get_load_flags(int hinting, int hintstyle, int base) {
|
||||
int flags = base;
|
||||
if (hinting) {
|
||||
if (hintstyle >= 3) flags |= FT_LOAD_TARGET_NORMAL;
|
||||
else if (0 < hintstyle && hintstyle < 3) flags |= FT_LOAD_TARGET_LIGHT;
|
||||
} else flags |= FT_LOAD_NO_HINTING;
|
||||
return flags;
|
||||
}
|
||||
|
||||
|
||||
static inline bool
|
||||
init_ft_face(Face *self, PyObject *path, int hinting, int hintstyle, FONTS_DATA_HANDLE fg) {
|
||||
#define CPY(n) self->n = self->face->n;
|
||||
@ -236,14 +268,6 @@ repr(Face *self) {
|
||||
}
|
||||
|
||||
|
||||
static inline bool
|
||||
load_glyph(Face *self, int glyph_index, int load_type) {
|
||||
int flags = get_load_flags(self->hinting, self->hintstyle, load_type);
|
||||
int error = FT_Load_Glyph(self->face, glyph_index, flags);
|
||||
if (error) { set_freetype_error("Failed to load glyph, with error:", error); return false; }
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline unsigned int
|
||||
calc_cell_width(Face *self) {
|
||||
unsigned int ans = 0;
|
||||
@ -260,7 +284,7 @@ void
|
||||
cell_metrics(PyObject *s, unsigned int* cell_width, unsigned int* cell_height, unsigned int* baseline, unsigned int* underline_position, unsigned int* underline_thickness) {
|
||||
Face *self = (Face*)s;
|
||||
*cell_width = calc_cell_width(self);
|
||||
*cell_height = CALC_CELL_HEIGHT(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));
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user