Compare commits
7 Commits
main
...
unhinted-t
Author | SHA1 | Date | |
---|---|---|---|
|
39051aec9b | ||
|
f3612c8616 | ||
|
49491cf5f8 | ||
|
65bf74a96d | ||
|
52f7e7ea22 | ||
|
43f9e1ea90 | ||
|
afc6f1c5ea |
@@ -11,6 +11,7 @@
|
||||
#include "gdk/gdkprofilerprivate.h"
|
||||
|
||||
#include "gsk/gskdebugprivate.h"
|
||||
#include "gsk/gskprivate.h"
|
||||
|
||||
#define MAX_SLICES_PER_ATLAS 64
|
||||
|
||||
@@ -905,6 +906,7 @@ gsk_gpu_device_lookup_glyph_image (GskGpuDevice *self,
|
||||
GskGpuImage *image;
|
||||
gsize atlas_x, atlas_y, padding;
|
||||
float subpixel_x, subpixel_y;
|
||||
PangoFont *scaled_font;
|
||||
|
||||
cache = g_hash_table_lookup (priv->glyph_cache, &lookup);
|
||||
if (cache)
|
||||
@@ -916,13 +918,14 @@ gsk_gpu_device_lookup_glyph_image (GskGpuDevice *self,
|
||||
return cache->image;
|
||||
}
|
||||
|
||||
scaled_font = gsk_get_scaled_font (font, scale);
|
||||
subpixel_x = (flags & 3) / 4.f;
|
||||
subpixel_y = ((flags >> 2) & 3) / 4.f;
|
||||
pango_font_get_glyph_extents (font, glyph, &ink_rect, NULL);
|
||||
origin.x = floor (ink_rect.x * scale / PANGO_SCALE + subpixel_x);
|
||||
origin.y = floor (ink_rect.y * scale / PANGO_SCALE + subpixel_y);
|
||||
rect.size.width = ceil ((ink_rect.x + ink_rect.width) * scale / PANGO_SCALE + subpixel_x) - origin.x;
|
||||
rect.size.height = ceil ((ink_rect.y + ink_rect.height) * scale / PANGO_SCALE + subpixel_y) - origin.y;
|
||||
pango_font_get_glyph_extents (scaled_font, glyph, &ink_rect, NULL);
|
||||
origin.x = floor (ink_rect.x * 1.0 / PANGO_SCALE + subpixel_x);
|
||||
origin.y = floor (ink_rect.y * 1.0 / PANGO_SCALE + subpixel_y);
|
||||
rect.size.width = ceil ((ink_rect.x + ink_rect.width) * 1.0 / PANGO_SCALE + subpixel_x) - origin.x;
|
||||
rect.size.height = ceil ((ink_rect.y + ink_rect.height) * 1.0 / PANGO_SCALE + subpixel_y) - origin.y;
|
||||
padding = 1;
|
||||
|
||||
image = gsk_gpu_device_add_atlas_image (self,
|
||||
@@ -956,7 +959,7 @@ gsk_gpu_device_lookup_glyph_image (GskGpuDevice *self,
|
||||
|
||||
gsk_gpu_upload_glyph_op (frame,
|
||||
cache->image,
|
||||
font,
|
||||
scaled_font,
|
||||
glyph,
|
||||
&(cairo_rectangle_int_t) {
|
||||
.x = rect.origin.x - padding,
|
||||
@@ -964,7 +967,7 @@ gsk_gpu_device_lookup_glyph_image (GskGpuDevice *self,
|
||||
.width = rect.size.width + 2 * padding,
|
||||
.height = rect.size.height + 2 * padding,
|
||||
},
|
||||
scale,
|
||||
1.0,
|
||||
&GRAPHENE_POINT_INIT (cache->origin.x + padding,
|
||||
cache->origin.y + padding));
|
||||
|
||||
|
107
gsk/gskprivate.c
107
gsk/gskprivate.c
@@ -1,6 +1,10 @@
|
||||
#include "gskresources.h"
|
||||
#include "gskprivate.h"
|
||||
|
||||
#include <cairo.h>
|
||||
#include <pango/pangocairo.h>
|
||||
#include <math.h>
|
||||
|
||||
static gpointer
|
||||
register_resources (gpointer data)
|
||||
{
|
||||
@@ -15,3 +19,106 @@ gsk_ensure_resources (void)
|
||||
|
||||
g_once (®ister_resources_once, register_resources, NULL);
|
||||
}
|
||||
|
||||
/*< private >
|
||||
* gsk_get_unhinted_font:
|
||||
* @font: (transfer full): a `PangoFont`
|
||||
*
|
||||
* Returns a font that is just like @font, but does not apply
|
||||
* hinting to its glyphs or metrics.
|
||||
*
|
||||
* Returns: (transfer full): an unhinted `PangoFont`
|
||||
*/
|
||||
PangoFont *
|
||||
gsk_get_unhinted_font (PangoFont *font)
|
||||
{
|
||||
PangoFont *font2 = font;
|
||||
cairo_scaled_font_t *sc;
|
||||
cairo_font_options_t *options;
|
||||
|
||||
sc = pango_cairo_font_get_scaled_font (PANGO_CAIRO_FONT (font));
|
||||
options = cairo_font_options_create ();
|
||||
cairo_scaled_font_get_font_options (sc, options);
|
||||
if (cairo_font_options_get_hint_metrics (options) != CAIRO_HINT_METRICS_OFF ||
|
||||
cairo_font_options_get_hint_style (options) != CAIRO_HINT_STYLE_NONE)
|
||||
{
|
||||
font2 = PANGO_FONT (g_object_get_data (G_OBJECT (font), "gsk-unhinted-font"));
|
||||
if (!font2)
|
||||
{
|
||||
PangoFontMap *fontmap = pango_font_get_font_map (font);
|
||||
PangoContext *context;
|
||||
PangoFontDescription *desc;
|
||||
|
||||
cairo_font_options_set_hint_metrics (options, CAIRO_HINT_METRICS_OFF);
|
||||
cairo_font_options_set_hint_style (options, CAIRO_HINT_STYLE_NONE);
|
||||
|
||||
context = pango_font_map_create_context (fontmap);
|
||||
pango_cairo_context_set_font_options (context, options);
|
||||
|
||||
desc = pango_font_describe (font);
|
||||
font2 = pango_font_map_load_font (fontmap, context, desc);
|
||||
|
||||
pango_font_description_free (desc);
|
||||
g_object_unref (context);
|
||||
|
||||
g_object_set_data_full (G_OBJECT (font), "gsk-unhinted-font",
|
||||
font2, g_object_unref);
|
||||
}
|
||||
}
|
||||
|
||||
cairo_font_options_destroy (options);
|
||||
|
||||
return font2;
|
||||
}
|
||||
|
||||
PangoFont *
|
||||
gsk_get_scaled_font (PangoFont *font,
|
||||
float scale)
|
||||
{
|
||||
GHashTable *fonts;
|
||||
int key;
|
||||
PangoFont *font2;
|
||||
PangoFontDescription *desc;
|
||||
int size;
|
||||
PangoFontMap *fontmap;
|
||||
PangoContext *context;
|
||||
|
||||
key = (int) CLAMP (roundf (scale * PANGO_SCALE), G_MININT, G_MAXINT);
|
||||
|
||||
if (key == PANGO_SCALE)
|
||||
return font;
|
||||
|
||||
fonts = (GHashTable *) g_object_get_data (G_OBJECT (font), "gsk-scaled-fonts");
|
||||
|
||||
if (fonts)
|
||||
{
|
||||
font2 = g_hash_table_lookup (fonts, GINT_TO_POINTER (key));
|
||||
if (font2)
|
||||
return font2;
|
||||
}
|
||||
else
|
||||
{
|
||||
fonts = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, g_object_unref);
|
||||
g_object_set_data_full (G_OBJECT (font), "gsk-scaled-fonts",
|
||||
fonts, (GDestroyNotify) g_hash_table_unref);
|
||||
}
|
||||
|
||||
desc = pango_font_describe (font);
|
||||
size = pango_font_description_get_size (desc);
|
||||
|
||||
if (pango_font_description_get_size_is_absolute (desc))
|
||||
pango_font_description_set_absolute_size (desc, size * scale);
|
||||
else
|
||||
pango_font_description_set_size (desc, (int) roundf (size * scale));
|
||||
|
||||
fontmap = pango_font_get_font_map (font);
|
||||
context = pango_font_map_create_context (fontmap);
|
||||
font2 = pango_font_map_load_font (fontmap, context, desc);
|
||||
|
||||
pango_font_description_free (desc);
|
||||
g_object_unref (context);
|
||||
|
||||
g_hash_table_insert (fonts, GINT_TO_POINTER (key), font2);
|
||||
|
||||
return font2;
|
||||
}
|
||||
|
@@ -5,7 +5,11 @@
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
void gsk_ensure_resources (void);
|
||||
void gsk_ensure_resources (void);
|
||||
|
||||
PangoFont *gsk_get_unhinted_font (PangoFont *font);
|
||||
PangoFont *gsk_get_scaled_font (PangoFont *font,
|
||||
float scale);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
@@ -31,6 +31,7 @@
|
||||
#include "gskroundedrectprivate.h"
|
||||
#include "gskstrokeprivate.h"
|
||||
#include "gsktransformprivate.h"
|
||||
#include "gskprivate.h"
|
||||
|
||||
#include "gdk/gdkmemoryformatprivate.h"
|
||||
#include "gdk/gdkprivate.h"
|
||||
@@ -5791,6 +5792,12 @@ gsk_text_node_class_init (gpointer g_class,
|
||||
node_class->diff = gsk_text_node_diff;
|
||||
}
|
||||
|
||||
static inline float
|
||||
pango_units_to_float (int i)
|
||||
{
|
||||
return (float) i / PANGO_SCALE;
|
||||
}
|
||||
|
||||
/**
|
||||
* gsk_text_node_new:
|
||||
* @font: the `PangoFont` containing the glyphs
|
||||
@@ -5817,8 +5824,7 @@ gsk_text_node_new (PangoFont *font,
|
||||
PangoGlyphInfo *glyph_infos;
|
||||
int n;
|
||||
|
||||
pango_glyph_string_extents (glyphs, font, &ink_rect, NULL);
|
||||
pango_extents_to_pixels (&ink_rect, NULL);
|
||||
pango_glyph_string_extents (glyphs, gsk_get_unhinted_font (font), &ink_rect, NULL);
|
||||
|
||||
/* Don't create nodes with empty bounds */
|
||||
if (ink_rect.width == 0 || ink_rect.height == 0)
|
||||
@@ -5855,10 +5861,10 @@ gsk_text_node_new (PangoFont *font,
|
||||
self->num_glyphs = n;
|
||||
|
||||
gsk_rect_init (&node->bounds,
|
||||
offset->x + ink_rect.x,
|
||||
offset->y + ink_rect.y,
|
||||
ink_rect.width,
|
||||
ink_rect.height);
|
||||
offset->x + pango_units_to_float (ink_rect.x),
|
||||
offset->y + pango_units_to_float (ink_rect.y),
|
||||
pango_units_to_float (ink_rect.width),
|
||||
pango_units_to_float (ink_rect.height));
|
||||
|
||||
return node;
|
||||
}
|
||||
|
16
testsuite/gsk/compare/o-from-hell.node
Normal file
16
testsuite/gsk/compare/o-from-hell.node
Normal file
@@ -0,0 +1,16 @@
|
||||
blend {
|
||||
mode: difference;
|
||||
bottom: text {
|
||||
color: rgb(255,0,0);
|
||||
font: "Noto Sans Mono 300";
|
||||
glyphs: "o";
|
||||
}
|
||||
top: transform {
|
||||
transform: scale(100);
|
||||
child: text {
|
||||
color: rgb(255,0,0);
|
||||
font: "Noto Sans Mono 3";
|
||||
glyphs: "o";
|
||||
}
|
||||
}
|
||||
}
|
BIN
testsuite/gsk/compare/o-from-hell.png
Normal file
BIN
testsuite/gsk/compare/o-from-hell.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 6.1 KiB |
16
testsuite/gsk/compare/o-from-hell2.node
Normal file
16
testsuite/gsk/compare/o-from-hell2.node
Normal file
@@ -0,0 +1,16 @@
|
||||
blend {
|
||||
mode: difference;
|
||||
bottom: text {
|
||||
color: rgb(255,0,0);
|
||||
font: "Noto Sans Mono 300";
|
||||
glyphs: "o";
|
||||
}
|
||||
top: transform {
|
||||
transform: scale(0.01);
|
||||
child: text {
|
||||
color: rgb(255,0,0);
|
||||
font: "Noto Sans Mono 30000";
|
||||
glyphs: "o";
|
||||
}
|
||||
}
|
||||
}
|
BIN
testsuite/gsk/compare/o-from-hell2.png
Normal file
BIN
testsuite/gsk/compare/o-from-hell2.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 6.1 KiB |
@@ -98,6 +98,8 @@ compare_render_tests = [
|
||||
'mask-texture-color-alpha',
|
||||
'mipmap-generation-later',
|
||||
'nested-rounded-clips',
|
||||
'o-from-hell',
|
||||
'o-from-hell2',
|
||||
'offscreen-fractional-translate-nogl',
|
||||
'offscreen-pixel-alignment-nogl-nocairo',
|
||||
'offscreen-pixel-alignment2',
|
||||
|
Reference in New Issue
Block a user