text: Obtain ascender + descender sizes

This commit is contained in:
K. Lange 2023-03-25 17:29:15 +09:00
parent db4914ad7e
commit 06807a20f9
3 changed files with 58 additions and 0 deletions

View File

@ -28,3 +28,10 @@ extern int tt_string_width_int(struct TT_Font * font, const char * s);
extern int tt_draw_string(gfx_context_t * ctx, struct TT_Font * font, int x, int y, const char * s, uint32_t color);
extern void tt_draw_string_shadow(gfx_context_t * ctx, struct TT_Font * font, char * string, int font_size, int left, int top, uint32_t text_color, uint32_t shadow_color, int blur);
struct TT_FontMetrics {
float ascender;
float descender;
float lineGap;
};
extern int tt_measure_font(struct TT_Font * font, struct TT_FontMetrics * metrics);

View File

@ -871,6 +871,23 @@ KRK_Method(Font,width) {
return INTEGER_VAL(tt_string_width(self->fontData, s));
}
KRK_Method(Font,measure) {
INIT_CHECK(Font);
KrkTuple * out = krk_newTuple(3);
krk_push(OBJECT_VAL(out));
struct TT_FontMetrics metrics;
tt_measure_font(self->fontData, &metrics);
out->values.values[out->values.count++] = FLOATING_VAL(metrics.ascender);
out->values.values[out->values.count++] = FLOATING_VAL(metrics.descender);
out->values.values[out->values.count++] = FLOATING_VAL(metrics.lineGap);
return krk_pop();
}
#undef CURRENT_CTYPE
WRAP_TYPE(MenuBar,struct menu_bar,menuBar);
@ -1645,6 +1662,7 @@ KrkValue krk_module_onload__yutani2(void) {
BIND_METHOD(Font,draw_string);
BIND_METHOD(Font,draw_string_shadow);
BIND_METHOD(Font,width);
BIND_METHOD(Font,measure);
BIND_PROP(Font,size);
krk_finalizeClass(Font);

View File

@ -85,6 +85,7 @@ struct TT_Font {
struct TT_Table hhea_ptr;
struct TT_Table hmtx_ptr;
struct TT_Table name_ptr;
struct TT_Table os_2_ptr;
off_t cmap_start;
@ -97,6 +98,11 @@ struct TT_Font {
int loca_type;
};
struct TT_FontMetrics {
float ascender;
float descender;
float lineGap;
};
/* Currently, the edge sorter is disabled. It doesn't really help much,
* and it's very slow with our horrible qsort implementation. */
@ -381,6 +387,29 @@ static inline uint16_t tt_read_16(struct TT_Font * font) {
((b & 0xFF) << 0);
}
int tt_measure_font(struct TT_Font * font, struct TT_FontMetrics * metrics) {
int a, d, l;
if (font->os_2_ptr.offset) {
tt_seek(font, font->os_2_ptr.offset + 2 * 37);
a = (int16_t)tt_read_16(font);
d = -(int16_t)tt_read_16(font);
tt_seek(font, font->hhea_ptr.offset + 2 * 4);
l = (int16_t)tt_read_16(font);
} else {
tt_seek(font, font->hhea_ptr.offset + 2 * 2);
a = (int16_t)tt_read_16(font);
d = (int16_t)tt_read_16(font);
l = (int16_t)tt_read_16(font);
}
metrics->ascender = a * font->scale;
metrics->descender = d * font->scale;
metrics->lineGap = l * font->scale;
return 0;
}
int tt_xadvance_for_glyph(struct TT_Font * font, unsigned int ind) {
tt_seek(font, font->hhea_ptr.offset + 2 * 17);
uint16_t numLong = tt_read_16(font);
@ -843,6 +872,10 @@ static int tt_font_load(struct TT_Font * font) {
font->name_ptr.offset = offset;
font->name_ptr.length = length;
break;
case 0x4f532f32: /* OS/2 */
font->os_2_ptr.offset = offset;
font->name_ptr.length = length;
break;
}
}