[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Emacs-diffs] master d1dde7d: Use bitmap strikes as fallbacks for ftcr f
From: |
YAMAMOTO Mitsuharu |
Subject: |
[Emacs-diffs] master d1dde7d: Use bitmap strikes as fallbacks for ftcr font backend |
Date: |
Fri, 19 Apr 2019 23:44:39 -0400 (EDT) |
branch: master
commit d1dde7d04e5244179735592adc11d2a6f0af64ac
Author: YAMAMOTO Mitsuharu <address@hidden>
Commit: YAMAMOTO Mitsuharu <address@hidden>
Use bitmap strikes as fallbacks for ftcr font backend
* src/ftfont.h (struct font_info): New member bitmap_strike_index.
* src/ftfont.c (ftfont_open2): Try bitmap strikes as fallbacks.
(ftfont_open): Discard bitmap strikes.
* src/ftcrfont.c (ftcrfont_open): Recalculate metrics for bitmap strikes.
(ftcrfont_get_bitmap, ftcrfont_anchor_point, ftcrfont_shape): New functions.
(struct font_driver): Use them.
---
src/ftcrfont.c | 100 +++++++++++++++++++++++++++++++++++++++++++++++++++++----
src/ftfont.c | 44 ++++++++++++++++++++++---
src/ftfont.h | 4 +++
3 files changed, 137 insertions(+), 11 deletions(-)
diff --git a/src/ftcrfont.c b/src/ftcrfont.c
index 4845ee4..e341c40 100644
--- a/src/ftcrfont.c
+++ b/src/ftcrfont.c
@@ -135,7 +135,10 @@ ftcrfont_open (struct frame *f, Lisp_Object entity, int
pixel_size)
font->driver = &ftcrfont_driver;
FT_New_Size (ft_face, &ftcrfont_info->ft_size_draw);
FT_Activate_Size (ftcrfont_info->ft_size_draw);
- FT_Set_Pixel_Sizes (ft_face, 0, font->pixel_size);
+ if (ftcrfont_info->bitmap_strike_index < 0)
+ FT_Set_Pixel_Sizes (ft_face, 0, font->pixel_size);
+ else
+ FT_Select_Size (ft_face, ftcrfont_info->bitmap_strike_index);
cairo_font_face_t *font_face =
cairo_ft_font_face_create_for_ft_face (ft_face, 0);
cairo_matrix_t font_matrix, ctm;
@@ -148,6 +151,56 @@ ftcrfont_open (struct frame *f, Lisp_Object entity, int
pixel_size)
cairo_font_options_destroy (options);
ftcrfont_info->metrics = NULL;
ftcrfont_info->metrics_nrows = 0;
+ if (ftcrfont_info->bitmap_strike_index >= 0)
+ {
+ /* Several members of struct font/font_info set by
+ ftfont_open2 are bogus. Recalculate them with cairo
+ scaled font functions. */
+ cairo_font_extents_t extents;
+ cairo_scaled_font_extents (ftcrfont_info->cr_scaled_font, &extents);
+ font->ascent = lround (extents.ascent);
+ font->descent = lround (extents.descent);
+ font->height = lround (extents.height);
+
+ cairo_glyph_t stack_glyph;
+ int n = 0;
+ font->min_width = font->average_width = font->space_width = 0;
+ for (char c = 32; c < 127; c++)
+ {
+ cairo_glyph_t *glyphs = &stack_glyph;
+ int num_glyphs = 1;
+ cairo_status_t status =
+ cairo_scaled_font_text_to_glyphs (ftcrfont_info->cr_scaled_font,
+ 0, 0, &c, 1,
+ &glyphs, &num_glyphs,
+ NULL, NULL, NULL);
+
+ if (status == CAIRO_STATUS_SUCCESS)
+ {
+ if (glyphs != &stack_glyph)
+ cairo_glyph_free (glyphs);
+ else
+ {
+ int this_width =
+ ftcrfont_glyph_extents (font, stack_glyph.index, NULL);
+
+ if (this_width > 0
+ && (! font->min_width
+ || font->min_width > this_width))
+ font->min_width = this_width;
+ if (c == 32)
+ font->space_width = this_width;
+ font->average_width += this_width;
+ n++;
+ }
+ }
+ }
+ if (n > 0)
+ font->average_width /= n;
+
+ font->underline_position = -1;
+ font->underline_thickness = 0;
+ }
}
unblock_input ();
@@ -211,6 +264,43 @@ ftcrfont_text_extents (struct font *font,
}
static int
+ftcrfont_get_bitmap (struct font *font, unsigned int code,
+ struct font_bitmap *bitmap, int bits_per_pixel)
+{
+ struct font_info *ftcrfont_info = (struct font_info *) font;
+
+ if (ftcrfont_info->bitmap_strike_index < 0)
+ return ftfont_get_bitmap (font, code, bitmap, bits_per_pixel);
+
+ return -1;
+}
+
+static int
+ftcrfont_anchor_point (struct font *font, unsigned int code, int idx,
+ int *x, int *y)
+{
+ struct font_info *ftcrfont_info = (struct font_info *) font;
+
+ if (ftcrfont_info->bitmap_strike_index < 0)
+ return ftfont_anchor_point (font, code, idx, x, y);
+
+ return -1;
+}
+
+static Lisp_Object
+ftcrfont_shape (Lisp_Object lgstring)
+{
+#if defined HAVE_M17N_FLT && defined HAVE_LIBOTF
+ struct font_info *ftcrfont_info = (struct font_info *) font;
+
+ if (ftcrfont_info->bitmap_strike_index < 0)
+ return ftfont_shape (lgstring);
+#endif
+
+ return make_fixnum (0);
+}
+
+static int
ftcrfont_draw (struct glyph_string *s,
int from, int to, int x, int y, bool with_background)
{
@@ -286,14 +376,12 @@ struct font_driver const ftcrfont_driver =
.encode_char = ftfont_encode_char,
.text_extents = ftcrfont_text_extents,
.draw = ftcrfont_draw,
- .get_bitmap = ftfont_get_bitmap,
- .anchor_point = ftfont_anchor_point,
+ .get_bitmap = ftcrfont_get_bitmap,
+ .anchor_point = ftcrfont_anchor_point,
#ifdef HAVE_LIBOTF
.otf_capability = ftfont_otf_capability,
#endif
-#if defined HAVE_M17N_FLT && defined HAVE_LIBOTF
- .shape = ftfont_shape,
-#endif
+ .shape = ftcrfont_shape,
#ifdef HAVE_OTF_GET_VARIATION_GLYPHS
.get_variation_glyphs = ftfont_variation_glyphs,
#endif
diff --git a/src/ftfont.c b/src/ftfont.c
index 3e820f5..d0078a3 100644
--- a/src/ftfont.c
+++ b/src/ftfont.c
@@ -1097,6 +1097,7 @@ ftfont_open2 (struct frame *f,
int spacing;
int i;
double upEM;
+ FT_Int strike_index = -1;
val = assq_no_quit (QCfont_entity, AREF (entity, FONT_EXTRA_INDEX));
if (! CONSP (val))
@@ -1126,12 +1127,32 @@ ftfont_open2 (struct frame *f,
size = pixel_size;
if (FT_Set_Pixel_Sizes (ft_face, size, size) != 0)
{
- if (cache_data->face_refcount == 0)
+ int min_distance = INT_MAX;
+ bool magnify = true;
+
+ for (FT_Int i = 0; i < ft_face->num_fixed_sizes; i++)
{
- FT_Done_Face (ft_face);
- cache_data->ft_face = NULL;
+ int distance = ft_face->available_sizes[i].height - (int) size;
+
+ /* Prefer down-scaling to upscaling. */
+ if (magnify == (distance < 0) ? abs (distance) <= min_distance
+ : magnify)
+ {
+ magnify = distance < 0;
+ min_distance = abs (distance);
+ strike_index = i;
+ }
+ }
+
+ if (strike_index < 0 || FT_Select_Size (ft_face, strike_index) != 0)
+ {
+ if (cache_data->face_refcount == 0)
+ {
+ FT_Done_Face (ft_face);
+ cache_data->ft_face = NULL;
+ }
+ return Qnil;
}
- return Qnil;
}
cache_data->face_refcount++;
@@ -1144,6 +1165,7 @@ ftfont_open2 (struct frame *f,
ftfont_info->maybe_otf = (ft_face->face_flags & FT_FACE_FLAG_SFNT) != 0;
ftfont_info->otf = NULL;
#endif /* HAVE_LIBOTF */
+ ftfont_info->bitmap_strike_index = strike_index;
/* This means that there's no need of transformation. */
ftfont_info->matrix.xx = 0;
font->pixel_size = size;
@@ -1229,7 +1251,19 @@ ftfont_open (struct frame *f, Lisp_Object entity, int
pixel_size)
size = pixel_size;
font_object = font_build_object (VECSIZE (struct font_info),
Qfreetype, entity, size);
- return ftfont_open2 (f, entity, pixel_size, font_object);
+ font_object = ftfont_open2 (f, entity, pixel_size, font_object);
+ if (FONT_OBJECT_P (font_object))
+ {
+ struct font *font = XFONT_OBJECT (font_object);
+ struct font_info *ftfont_info = (struct font_info *) font;
+
+ if (ftfont_info->bitmap_strike_index >= 0)
+ {
+ ftfont_close (font);
+ font_object = Qnil;
+ }
+ }
+ return font_object;
}
void
diff --git a/src/ftfont.h b/src/ftfont.h
index 327cd08..adbda49 100644
--- a/src/ftfont.h
+++ b/src/ftfont.h
@@ -54,6 +54,10 @@ struct font_info
#endif /* HAVE_LIBOTF */
FT_Size ft_size;
int index;
+ /* Index of the bitmap strike used as a fallback for
+ FT_Set_Pixel_Sizes failure. If the value is non-negative, then
+ ft_size is not of the requested size. Otherwise it is -1. */
+ FT_Int bitmap_strike_index;
FT_Matrix matrix;
#ifdef USE_CAIRO
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Emacs-diffs] master d1dde7d: Use bitmap strikes as fallbacks for ftcr font backend,
YAMAMOTO Mitsuharu <=