mirror of
https://gitlab.freedesktop.org/cairo/cairo.git
synced 2026-05-05 19:18:12 +02:00
[ft] Fix resizing of bitmap fonts
Say, you were asking cairo for a font at 200px. For bitmap-only fonts,
cairo was finding the closes strike size and using it. If the strike
was at 20px, well, that's what you were getting. We now scale that 20px
strike by a factor of 10 to get the correct size rendering.
Note that by itself this patch doesn't change much on the Linux desktop.
The reason is that the size you are interested in (eg. 200px) is lost by
fontconfig. When you request a font at 200px, fontconfig returns a font
pattern that says 20px, and so the next layers thing you want a font at
20px. To address that, one also needs a piece of fontconfig config that
puts the 200 back into the pixelsize. Something like this:
<match target="font">
<test name="scalable" mode="eq">
<bool>false</bool>
</test>
<edit name="pixelsize" mode="assign">
<times>
<name>size</name>
<name>dpi</name>
<double>0.0138888888888</double> <!--1/72.-->
</times>
</edit>
</match>
I'm going to try to upstream this config so it will be enabled by
default. The config can be a bit smarter. For example, if
metricshinting is enabled and the size difference is small, we may as
well not scale.
The nice thing about this is that the configuration of whether and when
to scale bitmaps will be done in fontconfig, not cairo / Qt / ... code.
This commit is contained in:
parent
1404ed9692
commit
b94a519aad
1 changed files with 34 additions and 32 deletions
|
|
@ -708,7 +708,8 @@ _cairo_ft_unscaled_font_unlock_face (cairo_ft_unscaled_font_t *unscaled)
|
|||
|
||||
static cairo_status_t
|
||||
_compute_transform (cairo_ft_font_transform_t *sf,
|
||||
cairo_matrix_t *scale)
|
||||
cairo_matrix_t *scale,
|
||||
cairo_ft_unscaled_font_t *unscaled)
|
||||
{
|
||||
cairo_status_t status;
|
||||
double x_scale, y_scale;
|
||||
|
|
@ -736,6 +737,30 @@ _compute_transform (cairo_ft_font_transform_t *sf,
|
|||
if (y_scale < 1.0)
|
||||
y_scale = 1.0;
|
||||
|
||||
if (unscaled && (unscaled->face->face_flags & FT_FACE_FLAG_SCALABLE) == 0) {
|
||||
double min_distance = DBL_MAX;
|
||||
int i;
|
||||
int best_i = 0;
|
||||
double best_x_size = 0;
|
||||
double best_y_size = 0;
|
||||
|
||||
for (i = 0; i < unscaled->face->num_fixed_sizes; i++) {
|
||||
double x_size = unscaled->face->available_sizes[i].y_ppem / 64.;
|
||||
double y_size = unscaled->face->available_sizes[i].y_ppem / 64.;
|
||||
double distance = fabs (y_size - y_scale);
|
||||
|
||||
if (distance <= min_distance) {
|
||||
min_distance = distance;
|
||||
best_i = i;
|
||||
best_x_size = x_size;
|
||||
best_y_size = y_size;
|
||||
}
|
||||
}
|
||||
|
||||
x_scale = best_x_size;
|
||||
y_scale = best_y_size;
|
||||
}
|
||||
|
||||
sf->x_scale = x_scale;
|
||||
sf->y_scale = y_scale;
|
||||
|
||||
|
|
@ -773,7 +798,7 @@ _cairo_ft_unscaled_font_set_scale (cairo_ft_unscaled_font_t *unscaled,
|
|||
unscaled->have_scale = TRUE;
|
||||
unscaled->current_scale = *scale;
|
||||
|
||||
status = _compute_transform (&sf, scale);
|
||||
status = _compute_transform (&sf, scale, unscaled);
|
||||
if (unlikely (status))
|
||||
return status;
|
||||
|
||||
|
|
@ -798,35 +823,12 @@ _cairo_ft_unscaled_font_set_scale (cairo_ft_unscaled_font_t *unscaled,
|
|||
|
||||
FT_Set_Transform(unscaled->face, &mat, NULL);
|
||||
|
||||
if ((unscaled->face->face_flags & FT_FACE_FLAG_SCALABLE) != 0) {
|
||||
error = FT_Set_Char_Size (unscaled->face,
|
||||
sf.x_scale * 64.0 + .5,
|
||||
sf.y_scale * 64.0 + .5,
|
||||
0, 0);
|
||||
if (error)
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
} else {
|
||||
double min_distance = DBL_MAX;
|
||||
int i;
|
||||
int best_i = 0;
|
||||
|
||||
for (i = 0; i < unscaled->face->num_fixed_sizes; i++) {
|
||||
double size = unscaled->face->available_sizes[i].y_ppem / 64.;
|
||||
double distance = fabs (size - sf.y_scale);
|
||||
|
||||
if (distance <= min_distance) {
|
||||
min_distance = distance;
|
||||
best_i = i;
|
||||
}
|
||||
}
|
||||
error = FT_Set_Char_Size (unscaled->face,
|
||||
unscaled->face->available_sizes[best_i].x_ppem,
|
||||
unscaled->face->available_sizes[best_i].y_ppem,
|
||||
0, 0);
|
||||
|
||||
if (error)
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
}
|
||||
error = FT_Set_Char_Size (unscaled->face,
|
||||
sf.x_scale * 64.0 + .5,
|
||||
sf.y_scale * 64.0 + .5,
|
||||
0, 0);
|
||||
if (error)
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
|
@ -3079,7 +3081,7 @@ _cairo_ft_resolve_pattern (FcPattern *pattern,
|
|||
font_matrix,
|
||||
&scale);
|
||||
|
||||
status = _compute_transform (&sf, &scale);
|
||||
status = _compute_transform (&sf, &scale, NULL);
|
||||
if (unlikely (status))
|
||||
return (cairo_font_face_t *)&_cairo_font_face_nil;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue