Adjust the point size of fallback and symbol fonts so that their heights match the current cell height
This commit is contained in:
parent
604e82fd65
commit
67a37f1f41
@ -218,8 +218,8 @@ python_send_to_gpu(unsigned int x, unsigned int y, unsigned int z, uint8_t* buf)
|
||||
|
||||
static inline PyObject*
|
||||
update_cell_metrics() {
|
||||
#define CALL(f, desired_height) { if ((f)->face) { if(!set_size_for_face((f)->face, desired_height)) return NULL; (f)->hb_font = harfbuzz_font_for_face((f)->face); } clear_sprite_map((f)); }
|
||||
CALL(&medium_font, 0); CALL(&bold_font, 0); CALL(&italic_font, 0); CALL(&bi_font, 0); CALL(&box_font, 0);
|
||||
#define CALL(f, desired_height, force) { if ((f)->face) { if(!set_size_for_face((f)->face, desired_height, force)) return NULL; (f)->hb_font = harfbuzz_font_for_face((f)->face); } clear_sprite_map((f)); }
|
||||
CALL(&medium_font, 0, false); CALL(&bold_font, 0, false); CALL(&italic_font, 0, false); CALL(&bi_font, 0, false); CALL(&box_font, 0, false);
|
||||
cell_metrics(medium_font.face, &cell_width, &cell_height, &baseline, &underline_position, &underline_thickness);
|
||||
if (!cell_width) { PyErr_SetString(PyExc_ValueError, "Failed to calculate cell width for the specified font."); return NULL; }
|
||||
if (OPT(adjust_line_height_px) != 0) cell_height += OPT(adjust_line_height_px);
|
||||
@ -232,10 +232,10 @@ update_cell_metrics() {
|
||||
free(canvas); canvas = malloc(CELLS_IN_CANVAS * cell_width * cell_height);
|
||||
if (canvas == NULL) return PyErr_NoMemory();
|
||||
for (size_t i = 0; fallback_fonts[i].face != NULL; i++) {
|
||||
CALL(fallback_fonts + i, cell_height);
|
||||
CALL(fallback_fonts + i, cell_height, true);
|
||||
}
|
||||
for (size_t i = 0; i < symbol_map_fonts_count; i++) {
|
||||
CALL(symbol_map_fonts + i, cell_height);
|
||||
CALL(symbol_map_fonts + i, cell_height, true);
|
||||
}
|
||||
return Py_BuildValue("IIIII", cell_width, cell_height, baseline, underline_position, underline_thickness);
|
||||
#undef CALL
|
||||
@ -279,7 +279,7 @@ fallback_font(Cell *cell) {
|
||||
if (face == NULL) { PyErr_Print(); return NULL; }
|
||||
if (face == Py_None) { Py_DECREF(face); return NULL; }
|
||||
if (!alloc_font(fallback_fonts + i, face, bold, italic, true)) { Py_DECREF(face); fatal("Out of memory"); }
|
||||
set_size_for_face(face, cell_height);
|
||||
set_size_for_face(face, cell_height, true);
|
||||
Py_DECREF(face);
|
||||
return fallback_fonts + i;
|
||||
}
|
||||
|
||||
@ -16,7 +16,7 @@
|
||||
|
||||
bool face_has_codepoint(PyObject *, char_type);
|
||||
hb_font_t* harfbuzz_font_for_face(PyObject*);
|
||||
bool set_size_for_face(PyObject*, unsigned int);
|
||||
bool set_size_for_face(PyObject*, unsigned int, bool);
|
||||
void cell_metrics(PyObject*, unsigned int*, unsigned int*, unsigned int*, unsigned int*, unsigned int*);
|
||||
void sprite_tracker_current_layout(unsigned int *x, unsigned int *y, unsigned int *z);
|
||||
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, uint8_t *canvas, unsigned int cell_width, unsigned int cell_height, unsigned int num_cells, unsigned int baseline);
|
||||
|
||||
@ -70,10 +70,22 @@ set_freetype_error(const char* prefix, int err_code) {
|
||||
|
||||
static FT_Library library;
|
||||
|
||||
#define CALC_CELL_HEIGHT(self) font_units_to_pixels(self, self->height)
|
||||
|
||||
static inline int
|
||||
font_units_to_pixels(Face *self, int x) {
|
||||
return ceil((double)FT_MulFix(x, self->face->size->metrics.y_scale) / 64.0);
|
||||
}
|
||||
|
||||
static inline bool
|
||||
set_font_size(Face *self, FT_F26Dot6 char_width, FT_F26Dot6 char_height, FT_UInt xdpi, FT_UInt ydpi) {
|
||||
int error = FT_Set_Char_Size(self->face, char_width, char_height, xdpi, ydpi);
|
||||
set_font_size(Face *self, FT_F26Dot6 char_width, FT_F26Dot6 char_height, FT_UInt xdpi, FT_UInt ydpi, unsigned int desired_height) {
|
||||
int error = FT_Set_Char_Size(self->face, 0, char_height, xdpi, ydpi);
|
||||
if (!error) {
|
||||
unsigned int ch = CALC_CELL_HEIGHT(self);
|
||||
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);
|
||||
}
|
||||
self->char_width = char_width; self->char_height = char_height; self->xdpi = xdpi; self->ydpi = ydpi;
|
||||
if (self->harfbuzz_font != NULL) {
|
||||
#ifdef HARFBUZZ_HAS_CHANGE_FONT
|
||||
@ -89,7 +101,7 @@ set_font_size(Face *self, FT_F26Dot6 char_width, FT_F26Dot6 char_height, FT_UInt
|
||||
} else {
|
||||
if (!self->is_scalable && self->face->num_fixed_sizes > 0) {
|
||||
int32_t min_diff = INT32_MAX;
|
||||
int desired_height = global_state.cell_height;
|
||||
if (desired_height == 0) desired_height = global_state.cell_height;
|
||||
if (desired_height == 0) {
|
||||
desired_height = ceil(((double)char_height / 64.) * (double)ydpi / 72.);
|
||||
desired_height += ceil(0.2 * desired_height);
|
||||
@ -97,7 +109,7 @@ set_font_size(Face *self, FT_F26Dot6 char_width, FT_F26Dot6 char_height, FT_UInt
|
||||
FT_Int strike_index = -1;
|
||||
for (FT_Int i = 0; i < self->face->num_fixed_sizes; i++) {
|
||||
int h = self->face->available_sizes[i].height;
|
||||
int32_t diff = h < desired_height ? desired_height - h : h - desired_height;
|
||||
int32_t diff = h < (int32_t)desired_height ? (int32_t)desired_height - h : h - (int32_t)desired_height;
|
||||
if (diff < min_diff) {
|
||||
min_diff = diff;
|
||||
strike_index = i;
|
||||
@ -116,12 +128,12 @@ set_font_size(Face *self, FT_F26Dot6 char_width, FT_F26Dot6 char_height, FT_UInt
|
||||
}
|
||||
|
||||
bool
|
||||
set_size_for_face(PyObject *s, unsigned int UNUSED desired_height) {
|
||||
set_size_for_face(PyObject *s, unsigned int desired_height, bool force) {
|
||||
Face *self = (Face*)s;
|
||||
FT_UInt w = (FT_UInt)(ceil(global_state.font_sz_in_pts * 64.0));
|
||||
if (self->char_width == w && self->char_height == w && self->xdpi == (FT_UInt)global_state.logical_dpi_x && self->ydpi == (FT_UInt)global_state.logical_dpi_x) return true;
|
||||
FT_UInt w = (FT_UInt)(ceil(global_state.font_sz_in_pts * 64.0)), xdpi = (FT_UInt)global_state.logical_dpi_x, ydpi = (FT_UInt)global_state.logical_dpi_y;
|
||||
if (!force && (self->char_width == w && self->char_height == w && self->xdpi == xdpi && self->ydpi == ydpi)) return true;
|
||||
((Face*)self)->size_in_pts = global_state.font_sz_in_pts;
|
||||
return set_font_size(self, w, w, (FT_UInt)global_state.logical_dpi_x, (FT_UInt)global_state.logical_dpi_y);
|
||||
return set_font_size(self, w, w, xdpi, ydpi, desired_height);
|
||||
}
|
||||
|
||||
static inline int
|
||||
@ -142,7 +154,7 @@ init_ft_face(Face *self, PyObject *path, int hinting, int hintstyle) {
|
||||
#undef CPY
|
||||
self->is_scalable = FT_IS_SCALABLE(self->face);
|
||||
self->hinting = hinting; self->hintstyle = hintstyle;
|
||||
if (!set_size_for_face((PyObject*)self, 0)) return false;
|
||||
if (!set_size_for_face((PyObject*)self, 0, false)) return false;
|
||||
self->harfbuzz_font = hb_ft_font_create(self->face, NULL);
|
||||
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));
|
||||
@ -273,16 +285,11 @@ calc_cell_width(Face *self) {
|
||||
return ans;
|
||||
}
|
||||
|
||||
static inline int
|
||||
font_units_to_pixels(Face *self, int x) {
|
||||
return ceil((double)FT_MulFix(x, self->face->size->metrics.y_scale) / 64.0);
|
||||
}
|
||||
|
||||
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 = font_units_to_pixels(self, self->height);
|
||||
*cell_height = CALC_CELL_HEIGHT(self);
|
||||
#ifdef __APPLE__
|
||||
// See https://stackoverflow.com/questions/5511830/how-does-line-spacing-work-in-core-text-and-why-is-it-different-from-nslayoutm
|
||||
if (self->apple_leading <= 0) {
|
||||
@ -344,9 +351,9 @@ render_bitmap(Face *self, int glyph_id, ProcessedBitmap *ans, unsigned int cell_
|
||||
} else if (rescale && self->is_scalable && extra > MAX(2, cell_width / 3)) {
|
||||
FT_F26Dot6 char_width = self->char_width, char_height = self->char_height;
|
||||
float ar = (float)max_width / (float)bitmap->width;
|
||||
if (set_font_size(self, (FT_F26Dot6)((float)self->char_width * ar), (FT_F26Dot6)((float)self->char_height * ar), self->xdpi, self->ydpi)) {
|
||||
if (set_font_size(self, (FT_F26Dot6)((float)self->char_width * ar), (FT_F26Dot6)((float)self->char_height * ar), self->xdpi, self->ydpi, 0)) {
|
||||
if (!render_bitmap(self, glyph_id, ans, cell_width, num_cells, bold, italic, false)) return false;
|
||||
if (!set_font_size(self, char_width, char_height, self->xdpi, self->ydpi)) return false;
|
||||
if (!set_font_size(self, char_width, char_height, self->xdpi, self->ydpi, 0)) return false;
|
||||
} else return false;
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user