summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--pango/fonts.c13
-rw-r--r--pango/pango-font-private.h1
-rw-r--r--pango/pango-font.h2
-rw-r--r--pango/pango-glyph.h6
-rw-r--r--pango/shape.c43
-rw-r--r--tests/test-shape.c13
6 files changed, 72 insertions, 6 deletions
diff --git a/pango/fonts.c b/pango/fonts.c
index f144097d..d2fd4308 100644
--- a/pango/fonts.c
+++ b/pango/fonts.c
@@ -1737,6 +1737,14 @@ pango_font_default_has_char (PangoFont *font,
return result != PANGO_COVERAGE_NONE;
}
+static PangoFontFace *
+pango_font_default_get_face (PangoFont *font)
+{
+ PangoFontMap *map = pango_font_get_font_map (font);
+
+ return PANGO_FONT_MAP_GET_CLASS (map)->get_face (map,font);
+}
+
static void
pango_font_class_init (PangoFontClass *class G_GNUC_UNUSED)
{
@@ -1751,6 +1759,7 @@ pango_font_class_init (PangoFontClass *class G_GNUC_UNUSED)
pclass->is_hinted = pango_font_default_is_hinted;
pclass->get_scale_factors = pango_font_default_get_scale_factors;
pclass->has_char = pango_font_default_has_char;
+ pclass->get_face = pango_font_default_get_face;
}
static void
@@ -1979,9 +1988,9 @@ pango_font_get_font_map (PangoFont *font)
PangoFontFace *
pango_font_get_face (PangoFont *font)
{
- PangoFontMap *map = pango_font_get_font_map (font);
+ PangoFontClassPrivate *pclass = PANGO_FONT_GET_CLASS_PRIVATE (font);
- return PANGO_FONT_MAP_GET_CLASS (map)->get_face (map,font);
+ return pclass->get_face (font);
}
/**
diff --git a/pango/pango-font-private.h b/pango/pango-font-private.h
index 1f31f559..93ce27aa 100644
--- a/pango/pango-font-private.h
+++ b/pango/pango-font-private.h
@@ -44,6 +44,7 @@ typedef struct {
gboolean (* has_char) (PangoFont *font,
gunichar wc);
+ PangoFontFace * (* get_face) (PangoFont *font);
} PangoFontClassPrivate;
gboolean pango_font_is_hinted (PangoFont *font);
diff --git a/pango/pango-font.h b/pango/pango-font.h
index 6b78c2ed..d4bded86 100644
--- a/pango/pango-font.h
+++ b/pango/pango-font.h
@@ -664,6 +664,8 @@ PangoLanguage ** pango_font_get_languages (PangoFont *font);
#endif
#endif
+G_DEFINE_AUTOPTR_CLEANUP_FUNC(PangoFontFamily, g_object_unref)
+G_DEFINE_AUTOPTR_CLEANUP_FUNC(PangoFontFace, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(PangoFont, g_object_unref)
G_END_DECLS
diff --git a/pango/pango-glyph.h b/pango/pango-glyph.h
index cd29b77a..fae7168c 100644
--- a/pango/pango-glyph.h
+++ b/pango/pango-glyph.h
@@ -89,16 +89,18 @@ struct _PangoGlyphGeometry
* are always ordered in logical order, since visual order is meaningless;
* that is, in Arabic text, accent glyphs follow the glyphs for the
* base character.)
+ * @is_color: set if the the font will render this glyph with color. Since 1.50
*
* A `PangoGlyphVisAttr` structure communicates information between
* the shaping and rendering phases.
*
- * Currently, it contains only cluster start information. More attributes
- * may be added in the future.
+ * Currently, it contains cluster start and color information.
+ * More attributes may be added in the future.
*/
struct _PangoGlyphVisAttr
{
guint is_cluster_start : 1;
+ guint is_color : 1;
};
/* A single glyph
diff --git a/pango/shape.c b/pango/shape.c
index 62c0f025..30131dd5 100644
--- a/pango/shape.c
+++ b/pango/shape.c
@@ -30,6 +30,8 @@
#include "pango-font-private.h"
+#include <hb-ot.h>
+
/* {{{ Harfbuzz shaping */
/* {{{{ Buffer handling */
@@ -335,6 +337,45 @@ find_text_transform (const PangoAnalysis *analysis)
return PANGO_TEXT_TRANSFORM_NONE;
}
+static gboolean
+glyph_has_color (hb_font_t *font,
+ hb_codepoint_t glyph)
+{
+ hb_face_t *face;
+ hb_blob_t *blob;
+
+ face = hb_font_get_face (font);
+
+ if (hb_ot_color_glyph_get_layers (face, glyph, 0, NULL, NULL) > 0)
+ return TRUE;
+
+ if (hb_ot_color_has_png (face))
+ {
+ blob = hb_ot_color_glyph_reference_png (font, glyph);
+ if (blob)
+ {
+ guint length = hb_blob_get_length (blob);
+ hb_blob_destroy (blob);
+ if (length > 0)
+ return TRUE;
+ }
+ }
+
+ if (hb_ot_color_has_svg (face))
+ {
+ blob = hb_ot_color_glyph_reference_svg (face, glyph);
+ if (blob)
+ {
+ guint length = hb_blob_get_length (blob);
+ hb_blob_destroy (blob);
+ if (length > 0)
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
/* }}}} */
static void
@@ -495,11 +536,13 @@ pango_hb_shape (const char *item_text,
pango_glyph_string_set_size (glyphs, num_glyphs);
infos = glyphs->glyphs;
last_cluster = -1;
+
for (i = 0; i < num_glyphs; i++)
{
infos[i].glyph = hb_glyph->codepoint;
glyphs->log_clusters[i] = hb_glyph->cluster - item_offset;
infos[i].attr.is_cluster_start = glyphs->log_clusters[i] != last_cluster;
+ infos[i].attr.is_color = glyph_has_color (hb_font, hb_glyph->codepoint);
hb_glyph++;
last_cluster = glyphs->log_clusters[i];
}
diff --git a/tests/test-shape.c b/tests/test-shape.c
index a16eb9d7..9380976f 100644
--- a/tests/test-shape.c
+++ b/tests/test-shape.c
@@ -142,7 +142,7 @@ test_file (const gchar *filename, GString *string)
PangoAttrList *itemize_attrs;
PangoAttrList *shape_attrs;
GList *items, *l;
- GString *s1, *s2, *s3, *s4, *s5, *s6, *s7, *s8;
+ GString *s1, *s2, *s3, *s4, *s5, *s6, *s7, *s8, *s9;
char *p1;
const char *sep = "";
@@ -174,6 +174,7 @@ test_file (const gchar *filename, GString *string)
s6 = g_string_new ("Item: ");
s7 = g_string_new ("Offset: ");
s8 = g_string_new ("Class: ");
+ s9 = g_string_new ("Color: ");
length = strlen (text);
if (text[length - 1] == '\n')
@@ -212,6 +213,7 @@ test_file (const gchar *filename, GString *string)
g_string_append (s6, sep);
g_string_append (s7, sep);
g_string_append (s8, sep);
+ g_string_append (s9, sep);
sep = "|";
g_string_append_printf (s6, "%d(%d)", item->num_chars, item->length);
@@ -233,6 +235,7 @@ test_file (const gchar *filename, GString *string)
g_string_append (s6, " ");
g_string_append (s7, "|");
g_string_append (s8, "|");
+ g_string_append (s9, "|");
}
char *p;
@@ -280,6 +283,8 @@ test_file (const gchar *filename, GString *string)
default:
g_assert_not_reached ();
}
+ if (gi->attr.is_color)
+ g_string_append_printf (s9, "c");
len = 0;
len = MAX (len, g_utf8_strlen (s1->str, s1->len));
len = MAX (len, g_utf8_strlen (s2->str, s2->len));
@@ -289,14 +294,16 @@ test_file (const gchar *filename, GString *string)
len = MAX (len, g_utf8_strlen (s6->str, s6->len));
len = MAX (len, g_utf8_strlen (s7->str, s7->len));
len = MAX (len, g_utf8_strlen (s8->str, s8->len));
+ len = MAX (len, g_utf8_strlen (s9->str, s9->len));
g_string_append_printf (s1, "%*s", len - (int)g_utf8_strlen (s1->str, s1->len), "");
- g_string_append_printf (s4, "%*s", len - (int)g_utf8_strlen (s4->str, s4->len), "");
g_string_append_printf (s2, "%*s", len - (int)g_utf8_strlen (s2->str, s2->len), "");
g_string_append_printf (s3, "%*s", len - (int)g_utf8_strlen (s3->str, s3->len), "");
+ g_string_append_printf (s4, "%*s", len - (int)g_utf8_strlen (s4->str, s4->len), "");
g_string_append_printf (s5, "%*s", len - (int)g_utf8_strlen (s5->str, s5->len), "");
g_string_append_printf (s6, "%*s", len - (int)g_utf8_strlen (s6->str, s6->len), "");
g_string_append_printf (s7, "%*s", len - (int)g_utf8_strlen (s7->str, s7->len), "");
g_string_append_printf (s8, "%*s", len - (int)g_utf8_strlen (s8->str, s8->len), "");
+ g_string_append_printf (s9, "%*s", len - (int)g_utf8_strlen (s9->str, s9->len), "");
}
pango_glyph_string_free (glyphs);
@@ -309,6 +316,7 @@ test_file (const gchar *filename, GString *string)
g_string_append_printf (string, "%s\n", s3->str);
g_string_append_printf (string, "%s\n", s2->str);
g_string_append_printf (string, "%s\n", s8->str);
+ g_string_append_printf (string, "%s\n", s9->str);
g_string_append_printf (string, "%s\n", s4->str);
g_string_append_printf (string, "%s\n", s7->str);
@@ -320,6 +328,7 @@ test_file (const gchar *filename, GString *string)
g_string_free (s6, TRUE);
g_string_free (s7, TRUE);
g_string_free (s8, TRUE);
+ g_string_free (s9, TRUE);
g_list_free_full (items, (GDestroyNotify)pango_item_free);
g_free (contents);