Commit 2aead7a8 authored by Matthias Clasen's avatar Matthias Clasen
Browse files

Add layout serialization api

Add api to serialize PangoLayout, for the benefit
of testing and debugging. Currently, this uses
json, but that is an implementation detail.

Some tests included.
parent 2f2cb726
......@@ -232,6 +232,7 @@ harfbuzz_req_version = '>= 2.6.0'
fontconfig_req_version = '>= 2.13.0'
xft_req_version = '>= 2.0.0'
cairo_req_version = '>= 1.12.10'
json_glib_version = '>= 1.6.0'
# libm
mathlib_dep = cc.find_library('m', required: false)
......@@ -251,6 +252,9 @@ fribidi_dep = dependency('fribidi', version: fribidi_req_version,
default_options: ['docs=false'])
pango_deps += fribidi_dep
json_glib_dep = dependency('json-glib-1.0', version: json_glib_version)
pango_deps += json_glib_dep
thai_dep = dependency('libthai', version: libthai_req_version, required: get_option('libthai'))
if thai_dep.found()
pango_conf.set('HAVE_LIBTHAI', 1)
......
......@@ -27,6 +27,7 @@ pango_sources = [
'pango-utils.c',
'reorder-items.c',
'shape.c',
'serializer.c',
]
pango_headers = [
......
......@@ -2802,7 +2802,7 @@ pango_attr_list_from_string (const char *text)
p = endp + strspn (endp, " ");
endp = (char *)strpbrk (p, " ");
endp = (char *)p + strcspn (p, " ");
attr_type = get_attr_type_by_nick (p, endp - p);
p = endp + strspn (endp, " ");
......@@ -2929,8 +2929,7 @@ pango_attr_list_from_string (const char *text)
break;
case PANGO_ATTR_SHAPE:
endp = (char *)strpbrk (p, ",\n");
p = endp + strspn (endp, " ");
endp = (char *)p + strcspn (p, ",\n");
continue; /* FIXME */
case PANGO_ATTR_SCALE:
......
......@@ -351,6 +351,31 @@ GSList * pango_layout_get_lines (PangoLayout *layout);
PANGO_AVAILABLE_IN_1_16
GSList * pango_layout_get_lines_readonly (PangoLayout *layout);
#define PANGO_LAYOUT_SERIALIZE_ERROR (pango_layout_serialize_error_quark ())
typedef enum {
PANGO_LAYOUT_SERIALIZE_INVALID,
PANGO_LAYOUT_SERIALIZE_INVALID_SYNTAX,
PANGO_LAYOUT_SERIALIZE_INVALID_VALUE,
PANGO_LAYOUT_SERIALIZE_MISSING_VALUE,
} PangoLayoutSerializeError;
PANGO_AVAILABLE_IN_1_50
GQuark pango_layout_serialize_error_quark (void);
PANGO_AVAILABLE_IN_1_50
GBytes * pango_layout_serialize (PangoLayout *layout);
PANGO_AVAILABLE_IN_1_50
PangoLayout * pango_layout_deserialize (PangoContext *context,
GBytes *bytes,
GError **error);
PANGO_AVAILABLE_IN_1_50
gboolean pango_layout_write_to_file (PangoLayout *layout,
const char *filename,
GError **error);
#define PANGO_TYPE_LAYOUT_LINE (pango_layout_line_get_type ())
......
This diff is collapsed.
......@@ -21,6 +21,7 @@
#include "config.h"
#include <glib.h>
#include <pango/pangocairo.h>
#include <gio/gio.h>
static void
test_serialize_attr_list (void)
......@@ -122,6 +123,168 @@ test_serialize_tab_array (void)
}
}
static void
test_serialize_layout_minimal (void)
{
const char *test =
"{\n"
" \"text\" : \"Almost nothing\"\n"
"}";
PangoContext *context;
GBytes *bytes;
PangoLayout *layout;
GError *error = NULL;
GBytes *out_bytes;
const char *str;
context = pango_font_map_create_context (pango_cairo_font_map_get_default ());
bytes = g_bytes_new_static (test, -1);
layout = pango_layout_deserialize (context, bytes, &error);
g_assert_no_error (error);
g_assert_true (PANGO_IS_LAYOUT (layout));
g_assert_cmpstr (pango_layout_get_text (layout), ==, "Almost nothing");
g_assert_null (pango_layout_get_attributes (layout));
g_assert_null (pango_layout_get_tabs (layout));
g_assert_null (pango_layout_get_font_description (layout));
g_assert_cmpint (pango_layout_get_alignment (layout), ==, PANGO_ALIGN_LEFT);
g_assert_cmpint (pango_layout_get_width (layout), ==, -1);
out_bytes = pango_layout_serialize (layout);
str = g_bytes_get_data (out_bytes, NULL);
g_assert_cmpstr (str, ==, test);
g_bytes_unref (out_bytes);
g_object_unref (layout);
g_bytes_unref (bytes);
g_object_unref (context);
}
static void
test_serialize_layout_valid (void)
{
const char *test =
"{\n"
" \"text\" : \"Some fun with layouts!\",\n"
" \"attributes\" : [\n"
" {\n"
" \"end\" : 4,\n"
" \"type\" : \"foreground\",\n"
" \"value\" : \"#ffff00000000\"\n"
" },\n"
" {\n"
" \"start\" : 5,\n"
" \"end\" : 8,\n"
" \"type\" : \"foreground\",\n"
" \"value\" : \"#000080800000\"\n"
" },\n"
" {\n"
" \"start\" : 14,\n"
" \"type\" : \"foreground\",\n"
" \"value\" : \"#ffff0000ffff\"\n"
" }\n"
" ],\n"
" \"font\" : \"Sans Bold 32\",\n"
" \"tabs\" : {\n"
" \"positions-in-pixels\" : true,\n"
" \"positions\" : [\n"
" 0,\n"
" 50,\n"
" 100\n"
" ]\n"
" },\n"
" \"alignment\" : \"center\",\n"
" \"width\" : 350000,\n"
" \"line-spacing\" : 1.5\n"
"}";
PangoContext *context;
GBytes *bytes;
PangoLayout *layout;
PangoTabArray *tabs;
GError *error = NULL;
GBytes *out_bytes;
const char *str;
char *s;
context = pango_font_map_create_context (pango_cairo_font_map_get_default ());
bytes = g_bytes_new_static (test, -1);
layout = pango_layout_deserialize (context, bytes, &error);
g_assert_no_error (error);
g_assert_true (PANGO_IS_LAYOUT (layout));
g_assert_cmpstr (pango_layout_get_text (layout), ==, "Some fun with layouts!");
g_assert_nonnull (pango_layout_get_attributes (layout));
tabs = pango_layout_get_tabs (layout);
g_assert_nonnull (tabs);
pango_tab_array_free (tabs);
s = pango_font_description_to_string (pango_layout_get_font_description (layout));
g_assert_cmpstr (s, ==, "Sans Bold 32");
g_free (s);
g_assert_cmpint (pango_layout_get_alignment (layout), ==, PANGO_ALIGN_CENTER);
g_assert_cmpint (pango_layout_get_width (layout), ==, 350000);
g_assert_cmpfloat_with_epsilon (pango_layout_get_line_spacing (layout), 1.5, 0.0001);
out_bytes = pango_layout_serialize (layout);
str = g_bytes_get_data (out_bytes, NULL);
g_assert_cmpstr (str, ==, test);
g_bytes_unref (out_bytes);
g_object_unref (layout);
g_bytes_unref (bytes);
g_object_unref (context);
}
static void
test_serialize_layout_invalid (void)
{
const char *test1 =
"{\n"
" \"attributes\" : [\n"
" {\n"
" \"type\" : \"caramba\"\n"
" }\n"
" ]\n"
"}";
const char *test2 =
"{\n"
" \"attributes\" : [\n"
" {\n"
" \"type\" : \"weight\"\n"
" }\n"
" ]\n"
"}";
PangoContext *context;
GBytes *bytes;
PangoLayout *layout;
GError *error = NULL;
context = pango_font_map_create_context (pango_cairo_font_map_get_default ());
bytes = g_bytes_new_static (test1, -1);
layout = pango_layout_deserialize (context, bytes, &error);
g_assert_null (layout);
g_assert_error (error, PANGO_LAYOUT_SERIALIZE_ERROR, PANGO_LAYOUT_SERIALIZE_INVALID_VALUE);
g_bytes_unref (bytes);
g_clear_error (&error);
bytes = g_bytes_new_static (test2, -1);
layout = pango_layout_deserialize (context, bytes, &error);
g_assert_null (layout);
g_assert_error (error, PANGO_LAYOUT_SERIALIZE_ERROR, PANGO_LAYOUT_SERIALIZE_MISSING_VALUE);
g_bytes_unref (bytes);
g_object_unref (context);
}
int
main (int argc, char *argv[])
{
......@@ -129,6 +292,9 @@ main (int argc, char *argv[])
g_test_add_func ("/serialize/attr-list", test_serialize_attr_list);
g_test_add_func ("/serialize/tab-array", test_serialize_tab_array);
g_test_add_func ("/serialize/layout/minimal", test_serialize_layout_minimal);
g_test_add_func ("/serialize/layout/valid", test_serialize_layout_valid);
g_test_add_func ("/serialize/layout/invalid", test_serialize_layout_invalid);
return g_test_run ();
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment