diff options
34 files changed, 285 insertions, 304 deletions
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index b43a1a571..11f45725a 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -8,7 +8,7 @@ include: variables: FDO_UPSTREAM_REPO: 'cairo/cairo' FDO_DISTRIBUTION_VERSION: '34' - FDO_DISTRIBUTION_TAG: '2021-07-31.0' + FDO_DISTRIBUTION_TAG: '2021-08-26.0' # TODO: should probably get its own image at some point instead of reusing the GStreamer one. WINDOWS_IMAGE: "registry.freedesktop.org/gstreamer/gst-ci/amd64/windows:v16-master" @@ -62,7 +62,7 @@ fedora image: gcc g++ zlib-devel - expat + expat-devel libpng-devel fontconfig-devel freetype-devel diff --git a/Makefile.am b/Makefile.am index 1b7c59bf0..12cd9bf25 100644 --- a/Makefile.am +++ b/Makefile.am @@ -82,11 +82,8 @@ EXTRA_DIST += \ subprojects/fontconfig.wrap \ subprojects/freetype2.wrap \ subprojects/glib.wrap \ - subprojects/gperf.wrap \ - subprojects/libffi.wrap \ subprojects/libpng.wrap \ subprojects/pixman.wrap \ - subprojects/proxy-libintl.wrap \ subprojects/zlib.wrap \ $(NULL) diff --git a/boilerplate/cairo-boilerplate.h b/boilerplate/cairo-boilerplate.h index 544d38816..736534eaf 100644 --- a/boilerplate/cairo-boilerplate.h +++ b/boilerplate/cairo-boilerplate.h @@ -74,8 +74,13 @@ #endif #if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ > 4) -#define CAIRO_BOILERPLATE_PRINTF_FORMAT(fmt_index, va_index) \ +#ifdef __MINGW32__ +#define CAIRO_BOILERPLATE_PRINTF_FORMAT(fmt_index, va_index) \ + __attribute__((__format__(__MINGW_PRINTF_FORMAT, fmt_index, va_index))) +#else +#define CAIRO_BOILERPLATE_PRINTF_FORMAT(fmt_index, va_index) \ __attribute__((__format__(__printf__, fmt_index, va_index))) +#endif #else #define CAIRO_BOILERPLATE_PRINTF_FORMAT(fmt_index, va_index) #endif diff --git a/doc/public/cairo-sections.txt b/doc/public/cairo-sections.txt index be958eef1..6f9f86d98 100644 --- a/doc/public/cairo-sections.txt +++ b/doc/public/cairo-sections.txt @@ -82,6 +82,7 @@ cairo_pdf_version_to_string cairo_pdf_surface_set_size cairo_pdf_surface_add_outline cairo_pdf_surface_set_metadata +cairo_pdf_surface_set_custom_metadata cairo_pdf_surface_set_page_label cairo_pdf_surface_set_thumbnail_size </SECTION> diff --git a/meson.build b/meson.build index 6236d743b..3c261d0ff 100644 --- a/meson.build +++ b/meson.build @@ -1,5 +1,5 @@ project('cairo', 'c', 'cpp', - meson_version: '>= 0.54.0', + meson_version: '>= 0.56.0', version: run_command(find_program('version.py'), check: true).stdout().strip(), default_options: ['warning_level=2'], ) @@ -964,7 +964,7 @@ subdir('src') if feature_conf.get('CAIRO_HAS_PNG_FUNCTIONS', 0) == 1 subdir('boilerplate') else - cairoboilerplate_dep = dependency() + cairoboilerplate_dep = dependency('', required: false) endif subdir('util') diff --git a/src/cairo-compiler-private.h b/src/cairo-compiler-private.h index 502478a5c..103b7a859 100644 --- a/src/cairo-compiler-private.h +++ b/src/cairo-compiler-private.h @@ -107,8 +107,13 @@ #endif #if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ > 4) -#define CAIRO_PRINTF_FORMAT(fmt_index, va_index) \ +#ifdef __MINGW32__ +#define CAIRO_PRINTF_FORMAT(fmt_index, va_index) \ + __attribute__((__format__(__MINGW_PRINTF_FORMAT, fmt_index, va_index))) +#else +#define CAIRO_PRINTF_FORMAT(fmt_index, va_index) \ __attribute__((__format__(__printf__, fmt_index, va_index))) +#endif #else #define CAIRO_PRINTF_FORMAT(fmt_index, va_index) #endif diff --git a/src/cairo-composite-rectangles.c b/src/cairo-composite-rectangles.c index 10f30da92..80e23f23a 100644 --- a/src/cairo-composite-rectangles.c +++ b/src/cairo-composite-rectangles.c @@ -473,20 +473,6 @@ _cairo_composite_rectangles_init_for_glyphs (cairo_composite_rectangles_t *exten return CAIRO_INT_STATUS_NOTHING_TO_DO; } - /* Computing the exact bbox and the overlap is expensive. - * First perform a cheap test to see if the glyphs are all clipped out. - */ - if (extents->is_bounded & CAIRO_OPERATOR_BOUND_BY_MASK && - _cairo_scaled_font_glyph_approximate_extents (scaled_font, - glyphs, num_glyphs, - &extents->mask)) - { - if (! _cairo_rectangle_intersect (&extents->bounded, &extents->mask)) { - _cairo_composite_rectangles_fini(extents); - return CAIRO_INT_STATUS_NOTHING_TO_DO; - } - } - status = _cairo_scaled_font_glyph_device_extents (scaled_font, glyphs, num_glyphs, &extents->mask, diff --git a/src/cairo-ft-font.c b/src/cairo-ft-font.c index 66300dd03..683ee916d 100644 --- a/src/cairo-ft-font.c +++ b/src/cairo-ft-font.c @@ -93,6 +93,11 @@ #define FT_LCD_FILTER_LEGACY 16 #endif +/* FreeType version older than 2.11 does not have the FT_RENDER_MODE_SDF enum value in FT_Render_Mode */ +#if FREETYPE_MAJOR > 2 || (FREETYPE_MAJOR == 2 && FREETYPE_MINOR >= 11) +#define HAVE_FT_RENDER_MODE_SDF 1 +#endif + #define DOUBLE_FROM_26_6(t) ((double)(t) / 64.0) #define DOUBLE_TO_16_16(d) ((FT_Fixed)((d) * 65536.0)) #define DOUBLE_FROM_16_16(t) ((double)(t) / 65536.0) @@ -1498,6 +1503,9 @@ _render_glyph_outline (FT_Face face, case FT_RENDER_MODE_LIGHT: case FT_RENDER_MODE_NORMAL: case FT_RENDER_MODE_MAX: +#if HAVE_FT_RENDER_MODE_SDF + case FT_RENDER_MODE_SDF: +#endif default: format = CAIRO_FORMAT_A8; break; @@ -1531,6 +1539,9 @@ _render_glyph_outline (FT_Face face, case FT_RENDER_MODE_LIGHT: case FT_RENDER_MODE_NORMAL: case FT_RENDER_MODE_MAX: +#if HAVE_FT_RENDER_MODE_SDF + case FT_RENDER_MODE_SDF: +#endif default: break; } @@ -3277,8 +3288,6 @@ _cairo_ft_font_face_get_implementation (void *abstract_face, const cairo_matrix_t *ctm, const cairo_font_options_t *options) { - cairo_ft_font_face_t *font_face = abstract_face; - /* The handling of font options is different depending on how the * font face was created. When the user creates a font face with * cairo_ft_font_face_create_for_ft_face(), then the load flags @@ -3290,6 +3299,8 @@ _cairo_ft_font_face_get_implementation (void *abstract_face, */ #if CAIRO_HAS_FC_FONT + cairo_ft_font_face_t *font_face = abstract_face; + /* If we have an unresolved pattern, resolve it and create * unscaled font. Otherwise, use the ones stored in font_face. */ diff --git a/src/cairo-output-stream-private.h b/src/cairo-output-stream-private.h index 2542646b8..fe091d0c0 100644 --- a/src/cairo-output-stream-private.h +++ b/src/cairo-output-stream-private.h @@ -58,7 +58,7 @@ struct _cairo_output_stream { cairo_output_stream_write_func_t write_func; cairo_output_stream_flush_func_t flush_func; cairo_output_stream_close_func_t close_func; - unsigned long position; + long long position; cairo_status_t status; cairo_bool_t closed; }; @@ -140,7 +140,7 @@ cairo_private void _cairo_output_stream_print_matrix (cairo_output_stream_t *stream, const cairo_matrix_t *matrix); -cairo_private long +cairo_private long long _cairo_output_stream_get_position (cairo_output_stream_t *stream); cairo_private cairo_status_t diff --git a/src/cairo-output-stream.c b/src/cairo-output-stream.c index 935fa44c3..826c9cf8e 100644 --- a/src/cairo-output-stream.c +++ b/src/cairo-output-stream.c @@ -1,3 +1,4 @@ +/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */ /* cairo-output-stream.c: Output stream abstraction * * Copyright © 2005 Red Hat, Inc @@ -382,7 +383,8 @@ _cairo_dtostr (char *buffer, size_t size, double d, cairo_bool_t limited_precisi } enum { - LENGTH_MODIFIER_LONG = 0x100 + LENGTH_MODIFIER_LONG = 0x100, + LENGTH_MODIFIER_LONG_LONG = 0x200 }; /* Here's a limited reimplementation of printf. The reason for doing @@ -440,6 +442,10 @@ _cairo_output_stream_vprintf (cairo_output_stream_t *stream, if (*f == 'l') { length_modifier = LENGTH_MODIFIER_LONG; f++; + if (*f == 'l') { + length_modifier = LENGTH_MODIFIER_LONG_LONG; + f++; + } } /* The only format strings exist in the cairo implementation @@ -490,6 +496,20 @@ _cairo_output_stream_vprintf (cairo_output_stream_t *stream, single_fmt, va_arg (ap, long int)); } break; + case 'd' | LENGTH_MODIFIER_LONG_LONG: + case 'u' | LENGTH_MODIFIER_LONG_LONG: + case 'o' | LENGTH_MODIFIER_LONG_LONG: + case 'x' | LENGTH_MODIFIER_LONG_LONG: + case 'X' | LENGTH_MODIFIER_LONG_LONG: + if (var_width) { + width = va_arg (ap, int); + snprintf (buffer, sizeof buffer, + single_fmt, width, va_arg (ap, long long int)); + } else { + snprintf (buffer, sizeof buffer, + single_fmt, va_arg (ap, long long int)); + } + break; case 's': { /* Write out strings as they may be larger than the buffer. */ const char *s = va_arg (ap, const char *); @@ -570,7 +590,7 @@ _cairo_output_stream_print_matrix (cairo_output_stream_t *stream, m.xx, m.yx, m.xy, m.yy, m.x0, m.y0); } -long +long long _cairo_output_stream_get_position (cairo_output_stream_t *stream) { return stream->position; diff --git a/src/cairo-pdf-interchange.c b/src/cairo-pdf-interchange.c index 921952afb..38bec977f 100644 --- a/src/cairo-pdf-interchange.c +++ b/src/cairo-pdf-interchange.c @@ -1169,6 +1169,9 @@ cairo_pdf_interchange_write_docinfo (cairo_pdf_surface_t *surface) { cairo_pdf_interchange_t *ic = &surface->interchange; cairo_int_status_t status; + unsigned int i, num_elems; + struct metadata *data; + unsigned char *p; surface->docinfo_res = _cairo_pdf_surface_new_object (surface); if (surface->docinfo_res.id == 0) @@ -1203,6 +1206,26 @@ cairo_pdf_interchange_write_docinfo (cairo_pdf_surface_t *surface) if (ic->docinfo.mod_date) _cairo_output_stream_printf (surface->object_stream.stream, " /ModDate %s\n", ic->docinfo.mod_date); + num_elems = _cairo_array_num_elements (&ic->custom_metadata); + for (i = 0; i < num_elems; i++) { + data = _cairo_array_index (&ic->custom_metadata, i); + if (data->value) { + _cairo_output_stream_printf (surface->object_stream.stream, " /"); + /* The name can be any utf8 string. Use hex codes as + * specified in section 7.3.5 of PDF reference + */ + p = (unsigned char *)data->name; + while (*p) { + if (*p < 0x21 || *p > 0x7e || *p == '#' || *p == '/') + _cairo_output_stream_printf (surface->object_stream.stream, "#%02x", *p); + else + _cairo_output_stream_printf (surface->object_stream.stream, "%c", *p); + p++; + } + _cairo_output_stream_printf (surface->object_stream.stream, " %s\n", data->value); + } + } + _cairo_output_stream_printf (surface->object_stream.stream, ">>\n"); _cairo_pdf_surface_object_end (surface); @@ -1624,6 +1647,7 @@ _cairo_pdf_interchange_init (cairo_pdf_surface_t *surface) return _cairo_error (CAIRO_STATUS_NO_MEMORY); memset (&ic->docinfo, 0, sizeof (ic->docinfo)); + _cairo_array_init (&ic->custom_metadata, sizeof(struct metadata)); _cairo_pdf_interchange_set_create_date (surface); status = _cairo_array_append (&ic->outline, &outline_root); @@ -1654,6 +1678,8 @@ void _cairo_pdf_interchange_fini (cairo_pdf_surface_t *surface) { cairo_pdf_interchange_t *ic = &surface->interchange; + unsigned int i, num_elems; + struct metadata *data; _cairo_tag_stack_fini (&ic->analysis_tag_stack); _cairo_tag_stack_fini (&ic->render_tag_stack); @@ -1674,6 +1700,14 @@ _cairo_pdf_interchange_fini (cairo_pdf_surface_t *surface) free (ic->docinfo.creator); free (ic->docinfo.create_date); free (ic->docinfo.mod_date); + + num_elems = _cairo_array_num_elements (&ic->custom_metadata); + for (i = 0; i < num_elems; i++) { + data = _cairo_array_index (&ic->custom_metadata, i); + free (data->name); + free (data->value); + } + _cairo_array_fini (&ic->custom_metadata); } cairo_int_status_t @@ -1868,3 +1902,69 @@ _cairo_pdf_interchange_set_metadata (cairo_pdf_surface_t *surface, return CAIRO_STATUS_SUCCESS; } + +static const char *reserved_metadata_names[] = { + "", + "Title", + "Author", + "Subject", + "Keywords", + "Creator", + "Producer", + "CreationDate", + "ModDate", + "Trapped", +}; + +cairo_int_status_t +_cairo_pdf_interchange_set_custom_metadata (cairo_pdf_surface_t *surface, + const char *name, + const char *value) +{ + cairo_pdf_interchange_t *ic = &surface->interchange; + struct metadata *data; + struct metadata new_data; + int i, num_elems; + cairo_int_status_t status; + char *s = NULL; + + if (name == NULL) + return CAIRO_STATUS_NULL_POINTER; + + for (i = 0; i < ARRAY_LENGTH (reserved_metadata_names); i++) { + if (strcmp(name, reserved_metadata_names[i]) == 0) + return CAIRO_STATUS_INVALID_STRING; + } + + /* First check if we already have an entry for this name. If so, + * update the value. A NULL value means the entry has been removed + * and will not be emitted. */ + num_elems = _cairo_array_num_elements (&ic->custom_metadata); + for (i = 0; i < num_elems; i++) { + data = _cairo_array_index (&ic->custom_metadata, i); + if (strcmp(name, data->name) == 0) { + free (data->value); + data->value = NULL; + if (value && strlen(value)) { + status = _cairo_utf8_to_pdf_string (value, &s); + if (unlikely (status)) + return status; + data->value = s; + } + return CAIRO_STATUS_SUCCESS; + } + } + + /* Add new entry */ + status = CAIRO_STATUS_SUCCESS; + if (value && strlen(value)) { + new_data.name = strdup (name); + status = _cairo_utf8_to_pdf_string (value, &s); + if (unlikely (status)) + return status; + new_data.value = s; + status = _cairo_array_append (&ic->custom_metadata, &new_data); + } + + return status; +} diff --git a/src/cairo-pdf-surface-private.h b/src/cairo-pdf-surface-private.h index b2d857550..87f5ffa25 100644 --- a/src/cairo-pdf-surface-private.h +++ b/src/cairo-pdf-surface-private.h @@ -227,6 +227,11 @@ struct docinfo { char *mod_date; }; +struct metadata { + char *name; + char *value; +}; + typedef struct _cairo_pdf_interchange { cairo_tag_stack_t analysis_tag_stack; cairo_tag_stack_t render_tag_stack; @@ -248,6 +253,7 @@ typedef struct _cairo_pdf_interchange { int annot_page; cairo_array_t outline; /* array of pointers to cairo_pdf_outline_entry_t; */ struct docinfo docinfo; + cairo_array_t custom_metadata; /* array of struct metadata */ } cairo_pdf_interchange_t; @@ -302,7 +308,7 @@ struct _cairo_pdf_surface { cairo_bool_t active; cairo_pdf_resource_t self; cairo_pdf_resource_t length; - long start_offset; + long long start_offset; cairo_bool_t compressed; cairo_output_stream_t *old_output; } pdf_stream; @@ -420,4 +426,9 @@ _cairo_pdf_interchange_set_metadata (cairo_pdf_surface_t *surface, cairo_pdf_metadata_t metadata, const char *utf8); +cairo_private cairo_int_status_t +_cairo_pdf_interchange_set_custom_metadata (cairo_pdf_surface_t *surface, + const char *name, + const char *value); + #endif /* CAIRO_PDF_SURFACE_PRIVATE_H */ diff --git a/src/cairo-pdf-surface.c b/src/cairo-pdf-surface.c index 3c9d12471..07fe5dffc 100644 --- a/src/cairo-pdf-surface.c +++ b/src/cairo-pdf-surface.c @@ -243,7 +243,7 @@ typedef enum { typedef struct _cairo_pdf_object { cairo_pdf_object_type_t type; union { - long offset; /* type == PDF_OBJECT_UNCOMPRESSED */ + long long offset; /* type == PDF_OBJECT_UNCOMPRESSED */ struct compressed_obj { /* type == PDF_OBJECT_COMPRESSED */ cairo_pdf_resource_t xref_stream; int index; @@ -253,7 +253,7 @@ typedef struct _cairo_pdf_object { typedef struct _cairo_xref_stream_object { cairo_pdf_resource_t resource; - long offset; + long long offset; } cairo_xref_stream_object_t; typedef struct _cairo_pdf_font { @@ -313,7 +313,7 @@ static cairo_int_status_t _cairo_pdf_surface_write_catalog (cairo_pdf_surface_t *surface, cairo_pdf_resource_t catalog); -static long +static long long _cairo_pdf_surface_write_xref (cairo_pdf_surface_t *surface); static cairo_int_status_t @@ -321,7 +321,7 @@ _cairo_pdf_surface_write_xref_stream (cairo_pdf_surface_t *surface, cairo_pdf_resource_t xref_res, cairo_pdf_resource_t root_res, cairo_pdf_resource_t info_res, - long *xref_offset); + long long *xref_offset); static cairo_int_status_t _cairo_pdf_surface_write_patterns_and_smask_groups (cairo_pdf_surface_t *surface, @@ -908,6 +908,42 @@ cairo_pdf_surface_set_metadata (cairo_surface_t *surface, } /** + * cairo_pdf_surface_set_custom_metadata: + * @surface: a PDF #cairo_surface_t + * @name: The name of the custom metadata item to set (utf8). + * @value: The value of the metadata (utf8). + * + * Set custom document metadata. @name may be any string except for + * the following names reserved by PDF: "Title", "Author", "Subject", + * "Keywords", "Creator", "Producer", "CreationDate", "ModDate", + * "Trapped". + * + * If @value is NULL or an empty string, the @name metadata will not be set. + * + * For example: + * <informalexample><programlisting> + * cairo_pdf_surface_set_custom_metadata (surface, "ISBN", "978-0123456789"); + * </programlisting></informalexample> + * + * Since: 1.18 + **/ +void +cairo_pdf_surface_set_custom_metadata (cairo_surface_t *surface, + const char *name, + const char *value) +{ + cairo_pdf_surface_t *pdf_surface = NULL; /* hide compiler warning */ + cairo_status_t status; + + if (! _extract_pdf_surface (surface, &pdf_surface)) + return; + + status = _cairo_pdf_interchange_set_custom_metadata (pdf_surface, name, value); + if (status) + status = _cairo_surface_set_error (surface, status); +} + +/** * cairo_pdf_surface_set_page_label: * @surface: a PDF #cairo_surface_t * @utf8: The page label. @@ -1936,7 +1972,7 @@ static cairo_int_status_t _cairo_pdf_surface_close_stream (cairo_pdf_surface_t *surface) { cairo_int_status_t status; - long length; + long long length; if (! surface->pdf_stream.active) return CAIRO_INT_STATUS_SUCCESS; @@ -1966,7 +2002,7 @@ _cairo_pdf_surface_close_stream (cairo_pdf_surface_t *surface) surface->pdf_stream.length); _cairo_output_stream_printf (surface->output, "%d 0 obj\n" - " %ld\n" + " %lld\n" "endobj\n", surface->pdf_stream.length.id, length); @@ -2205,7 +2241,7 @@ _cairo_pdf_surface_close_object_stream (cairo_pdf_surface_t *surface) { int i, num_objects; cairo_xref_stream_object_t *xref_obj; - long start_pos, length; + long long start_pos, length; cairo_output_stream_t *index_stream; cairo_output_stream_t *deflate_stream; cairo_pdf_resource_t length_res; @@ -2230,7 +2266,7 @@ _cairo_pdf_surface_close_object_stream (cairo_pdf_surface_t *surface) for (i = 0; i < num_objects; i++) { xref_obj = _cairo_array_index (&surface->object_stream.objects, i); _cairo_output_stream_printf (index_stream, - "%d %ld\n", + "%d %lld\n", xref_obj->resource.id, xref_obj->offset); } @@ -2285,7 +2321,7 @@ _cairo_pdf_surface_close_object_stream (cairo_pdf_surface_t *surface) length_res); _cairo_output_stream_printf (surface->output, "%d 0 obj\n" - " %ld\n" + " %lld\n" "endobj\n", length_res.id, length); @@ -2423,7 +2459,7 @@ static cairo_status_t _cairo_pdf_surface_finish (void *abstract_surface) { cairo_pdf_surface_t *surface = abstract_surface; - long offset; + long long offset; cairo_pdf_resource_t catalog; cairo_status_t status, status2; int size, i; @@ -2491,7 +2527,7 @@ _cairo_pdf_surface_finish (void *abstract_surface) } _cairo_output_stream_printf (surface->output, "startxref\n" - "%ld\n" + "%lld\n" "%%%%EOF\n", offset); @@ -6738,12 +6774,12 @@ _cairo_pdf_surface_write_catalog (cairo_pdf_surface_t *surface, return status; } -static long +static long long _cairo_pdf_surface_write_xref (cairo_pdf_surface_t *surface) { cairo_pdf_object_t *object; int num_objects, i; - long offset; + long long offset; char buffer[11]; num_objects = _cairo_array_num_elements (&surface->objects); @@ -6758,7 +6794,7 @@ _cairo_pdf_surface_write_xref (cairo_pdf_surface_t *surface) "0000000000 65535 f \n"); for (i = 0; i < num_objects; i++) { object = _cairo_array_index (&surface->objects, i); - snprintf (buffer, sizeof buffer, "%010ld", object->u.offset); + snprintf (buffer, sizeof buffer, "%010lld", object->u.offset); _cairo_output_stream_printf (surface->output, "%s 00000 n \n", buffer); } @@ -6771,7 +6807,7 @@ _cairo_write_xref_stream_entry (cairo_output_stream_t *stream, int id, int type, int field2_size, - long field2, + long long field2, int field3, cairo_bool_t write_as_comments) { @@ -6779,7 +6815,7 @@ _cairo_write_xref_stream_entry (cairo_output_stream_t *stream, int i; if (write_as_comments) { - _cairo_output_stream_printf (stream, "%% %5d %2d %10ld %d\n", id, type, field2, field3); + _cairo_output_stream_printf (stream, "%% %5d %2d %10lld %d\n", id, type, field2, field3); } else { /* Each field is big endian */ buf[0] = type; /* field 1 */ @@ -6794,10 +6830,10 @@ _cairo_write_xref_stream_entry (cairo_output_stream_t *stream, } static void -_cairo_write_xref_stream_entrys (cairo_pdf_surface_t *surface, - cairo_output_stream_t *stream, - int field2_size, - cairo_bool_t write_as_comments) +_cairo_write_xref_stream_entries (cairo_pdf_surface_t *surface, + cairo_output_stream_t *stream, + int field2_size, + cairo_bool_t write_as_comments) { cairo_pdf_object_t *object; int num_objects, i; @@ -6847,11 +6883,11 @@ _cairo_pdf_surface_write_xref_stream (cairo_pdf_surface_t *surface, cairo_pdf_resource_t xref_res, cairo_pdf_resource_t root_res, cairo_pdf_resource_t info_res, - long *xref_offset) + long long *xref_offset) { cairo_output_stream_t *mem_stream; cairo_output_stream_t *xref_stream; - long offset; + long long offset; int offset_bytes; cairo_status_t status; @@ -6867,7 +6903,7 @@ _cairo_pdf_surface_write_xref_stream (cairo_pdf_surface_t *surface, mem_stream = _cairo_memory_stream_create (); xref_stream = _cairo_deflate_stream_create (mem_stream); - _cairo_write_xref_stream_entrys (surface, xref_stream, offset_bytes, FALSE); + _cairo_write_xref_stream_entries (surface, xref_stream, offset_bytes, FALSE); status = _cairo_output_stream_destroy (xref_stream); if (unlikely (status)) @@ -6900,7 +6936,7 @@ _cairo_pdf_surface_write_xref_stream (cairo_pdf_surface_t *surface, */ _cairo_output_stream_printf (surface->output, "%% id type offset/obj gen/index\n"); - _cairo_write_xref_stream_entrys (surface, surface->output, offset_bytes, TRUE); + _cairo_write_xref_stream_entries (surface, surface->output, offset_bytes, TRUE); } _cairo_output_stream_printf (surface->output, diff --git a/src/cairo-pdf.h b/src/cairo-pdf.h index 5be0b3f1b..49afb687e 100644 --- a/src/cairo-pdf.h +++ b/src/cairo-pdf.h @@ -144,6 +144,11 @@ cairo_pdf_surface_set_metadata (cairo_surface_t *surface, const char *utf8); cairo_public void +cairo_pdf_surface_set_custom_metadata (cairo_surface_t *surface, + const char *name, + const char *value); + +cairo_public void cairo_pdf_surface_set_page_label (cairo_surface_t *surface, const char *utf8); diff --git a/src/cairo-scaled-font.c b/src/cairo-scaled-font.c index ef0db0506..e0b586589 100755 --- a/src/cairo-scaled-font.c +++ b/src/cairo-scaled-font.c @@ -629,7 +629,7 @@ _hash_mix_bits (uint64_t hash) static uintptr_t _cairo_scaled_font_compute_hash (cairo_scaled_font_t *scaled_font) { - uintptr_t hash = FNV1_64_INIT; + uint64_t hash = FNV1_64_INIT; /* We do a bytewise hash on the font matrices */ hash = _hash_matrix_fnv (&scaled_font->font_matrix, hash); diff --git a/src/win32/cairo-win32-display-surface.c b/src/win32/cairo-win32-display-surface.c index 93d33b38b..a3f224c58 100644 --- a/src/win32/cairo-win32-display-surface.c +++ b/src/win32/cairo-win32-display-surface.c @@ -987,11 +987,18 @@ cairo_win32_surface_create_with_format (HDC hdc, cairo_format_t format) cairo_device_t *device; switch (format) { - default: - return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_FORMAT)); - case CAIRO_FORMAT_ARGB32: - case CAIRO_FORMAT_RGB24: - break; + case CAIRO_FORMAT_INVALID: + case CAIRO_FORMAT_A8: + case CAIRO_FORMAT_A1: + case CAIRO_FORMAT_RGB16_565: + case CAIRO_FORMAT_RGB30: + case CAIRO_FORMAT_RGB96F: + case CAIRO_FORMAT_RGBA128F: + default: + return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_FORMAT)); + case CAIRO_FORMAT_ARGB32: + case CAIRO_FORMAT_RGB24: + break; } surface = _cairo_malloc (sizeof (*surface)); @@ -1102,14 +1109,19 @@ cairo_win32_surface_create_with_ddb (HDC hdc, HBITMAP saved_dc_bitmap; switch (format) { - default: /* XXX handle these eventually */ - case CAIRO_FORMAT_A8: - case CAIRO_FORMAT_A1: - return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_FORMAT)); - case CAIRO_FORMAT_ARGB32: - case CAIRO_FORMAT_RGB24: - break; + case CAIRO_FORMAT_INVALID: + case CAIRO_FORMAT_A8: + case CAIRO_FORMAT_A1: + case CAIRO_FORMAT_RGB16_565: + case CAIRO_FORMAT_RGB30: + case CAIRO_FORMAT_RGB96F: + case CAIRO_FORMAT_RGBA128F: + default: + return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_FORMAT)); + case CAIRO_FORMAT_ARGB32: + case CAIRO_FORMAT_RGB24: + break; } if (!hdc) { diff --git a/src/win32/cairo-win32-font.c b/src/win32/cairo-win32-font.c index eb4ba7a22..ae375ae06 100644 --- a/src/win32/cairo-win32-font.c +++ b/src/win32/cairo-win32-font.c @@ -650,227 +650,6 @@ _cairo_win32_scaled_font_fini (void *abstract_font) DeleteObject (scaled_font->unscaled_hfont); } -static cairo_int_status_t -_cairo_win32_scaled_font_type1_text_to_glyphs (cairo_win32_scaled_font_t *scaled_font, - double x, - double y, - const char *utf8, - cairo_glyph_t **glyphs, - int *num_glyphs) -{ - uint16_t *utf16; - int n16; - int i; - WORD *glyph_indices = NULL; - cairo_status_t status; - double x_pos, y_pos; - HDC hdc = NULL; - cairo_matrix_t mat; - - status = _cairo_utf8_to_utf16 (utf8, -1, &utf16, &n16); - if (status) - return status; - - glyph_indices = _cairo_malloc_ab (n16 + 1, sizeof (WORD)); - if (!glyph_indices) { - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - goto FAIL1; - } - - hdc = _get_global_font_dc (); - assert (hdc != NULL); - - status = cairo_win32_scaled_font_select_font (&scaled_font->base, hdc); - if (status) - goto FAIL2; - - if (GetGlyphIndicesW (hdc, utf16, n16, glyph_indices, 0) == GDI_ERROR) { - status = _cairo_win32_print_gdi_error ("_cairo_win32_scaled_font_type1_text_to_glyphs:GetGlyphIndicesW"); - goto FAIL3; - } - - *num_glyphs = n16; - *glyphs = _cairo_malloc_ab (n16, sizeof (cairo_glyph_t)); - if (!*glyphs) { - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - goto FAIL3; - } - - x_pos = x; - y_pos = y; - - mat = scaled_font->base.ctm; - status = cairo_matrix_invert (&mat); - assert (status == CAIRO_STATUS_SUCCESS); - - _cairo_scaled_font_freeze_cache (&scaled_font->base); - - for (i = 0; i < n16; i++) { - cairo_scaled_glyph_t *scaled_glyph; - - (*glyphs)[i].index = glyph_indices[i]; - (*glyphs)[i].x = x_pos; - (*glyphs)[i].y = y_pos; - - status = _cairo_scaled_glyph_lookup (&scaled_font->base, - glyph_indices[i], - CAIRO_SCALED_GLYPH_INFO_METRICS, - NULL, /* foreground color */ - &scaled_glyph); - if (status) { - free (*glyphs); - *glyphs = NULL; - break; - } - - x = scaled_glyph->x_advance; - y = scaled_glyph->y_advance; - cairo_matrix_transform_distance (&mat, &x, &y); - x_pos += x; - y_pos += y; - } - - _cairo_scaled_font_thaw_cache (&scaled_font->base); - -FAIL3: - cairo_win32_scaled_font_done_font (&scaled_font->base); -FAIL2: - free (glyph_indices); -FAIL1: - free (utf16); - - return status; -} - -static cairo_int_status_t -_cairo_win32_scaled_font_text_to_glyphs (void *abstract_font, - double x, - double y, - const char *utf8, - cairo_glyph_t **glyphs, - int *num_glyphs) -{ - cairo_win32_scaled_font_t *scaled_font = abstract_font; - uint16_t *utf16; - int n16; - GCP_RESULTSW gcp_results; - unsigned int buffer_size, i; - WCHAR *glyph_indices = NULL; - int *dx = NULL; - cairo_status_t status; - double x_pos, y_pos; - double x_incr, y_incr; - HDC hdc = NULL; - - /* GetCharacterPlacement() returns utf16 instead of glyph indices - * for Type 1 fonts. Use GetGlyphIndices for Type 1 fonts. */ - if (scaled_font->is_type1) - return _cairo_win32_scaled_font_type1_text_to_glyphs (scaled_font, - x, - y, - utf8, - glyphs, - num_glyphs); - - /* Compute a vector in user space along the baseline of length one logical space unit */ - x_incr = 1; - y_incr = 0; - cairo_matrix_transform_distance (&scaled_font->base.font_matrix, &x_incr, &y_incr); - x_incr /= scaled_font->logical_scale; - y_incr /= scaled_font->logical_scale; - - status = _cairo_utf8_to_utf16 (utf8, -1, &utf16, &n16); - if (status) - return status; - - gcp_results.lStructSize = sizeof (GCP_RESULTS); - gcp_results.lpOutString = NULL; - gcp_results.lpOrder = NULL; - gcp_results.lpCaretPos = NULL; - gcp_results.lpClass = NULL; - - buffer_size = MAX (n16 * 1.2, 16); /* Initially guess number of chars plus a few */ - if (buffer_size > INT_MAX) { - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - goto FAIL1; - } - - hdc = _get_global_font_dc (); - assert (hdc != NULL); - - status = cairo_win32_scaled_font_select_font (&scaled_font->base, hdc); - if (status) - goto FAIL1; - - while (TRUE) { - free (glyph_indices); - glyph_indices = NULL; - - free (dx); - dx = NULL; - - glyph_indices = _cairo_malloc_ab (buffer_size, sizeof (WCHAR)); - dx = _cairo_malloc_ab (buffer_size, sizeof (int)); - if (!glyph_indices || !dx) { - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - goto FAIL2; - } - - gcp_results.nGlyphs = buffer_size; - gcp_results.lpDx = dx; - gcp_results.lpGlyphs = glyph_indices; - - if (!GetCharacterPlacementW (hdc, utf16, n16, - 0, - &gcp_results, - GCP_DIACRITIC | GCP_LIGATE | GCP_GLYPHSHAPE | GCP_REORDER)) { - status = _cairo_win32_print_gdi_error ("_cairo_win32_scaled_font_text_to_glyphs"); - goto FAIL2; - } - - if (gcp_results.lpDx && gcp_results.lpGlyphs) - break; - - /* Too small a buffer, try again */ - - buffer_size += buffer_size / 2; - if (buffer_size > INT_MAX) { - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - goto FAIL2; - } - } - - *num_glyphs = gcp_results.nGlyphs; - *glyphs = _cairo_malloc_ab (gcp_results.nGlyphs, sizeof (cairo_glyph_t)); - if (!*glyphs) { - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - goto FAIL2; - } - - x_pos = x; - y_pos = y; - - for (i = 0; i < gcp_results.nGlyphs; i++) { - (*glyphs)[i].index = glyph_indices[i]; - (*glyphs)[i].x = x_pos ; - (*glyphs)[i].y = y_pos; - - x_pos += x_incr * dx[i]; - y_pos += y_incr * dx[i]; - } - - FAIL2: - free (glyph_indices); - free (dx); - - cairo_win32_scaled_font_done_font (&scaled_font->base); - - FAIL1: - free (utf16); - - return status; -} - static unsigned long _cairo_win32_scaled_font_ucs4_to_index (void *abstract_font, uint32_t ucs4) @@ -1845,7 +1624,7 @@ const cairo_scaled_font_backend_t _cairo_win32_scaled_font_backend = { CAIRO_FONT_TYPE_WIN32, _cairo_win32_scaled_font_fini, _cairo_win32_scaled_font_glyph_init, - NULL, /* _cairo_win32_scaled_font_text_to_glyphs, FIXME */ + NULL, /* _cairo_win32_scaled_font_text_to_glyphs */ _cairo_win32_scaled_font_ucs4_to_index, _cairo_win32_scaled_font_load_truetype_table, _cairo_win32_scaled_font_index_to_ucs4, diff --git a/src/win32/cairo-win32-printing-surface.c b/src/win32/cairo-win32-printing-surface.c index 19b7f9e93..d01210745 100644 --- a/src/win32/cairo-win32-printing-surface.c +++ b/src/win32/cairo-win32-printing-surface.c @@ -167,8 +167,15 @@ _cairo_win32_printing_surface_init_language_pack (cairo_win32_printing_surface_t module = GetModuleHandleW (L"GDI32.DLL"); if (module) { +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wcast-function-type" +#endif gdi_init_lang_pack = (gdi_init_lang_pack_func_t) GetProcAddress (module, "GdiInitializeLanguagePack"); +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif if (gdi_init_lang_pack) gdi_init_lang_pack (0); } diff --git a/subprojects/gperf.wrap b/subprojects/gperf.wrap deleted file mode 100644 index 748973312..000000000 --- a/subprojects/gperf.wrap +++ /dev/null @@ -1,5 +0,0 @@ -[wrap-git] -directory=gperf -url=https://gitlab.freedesktop.org/tpm/gperf.git -push-url=https://gitlab.freedesktop.org/tpm/gperf.git -revision=meson diff --git a/subprojects/libffi.wrap b/subprojects/libffi.wrap deleted file mode 100644 index 6dea9ebed..000000000 --- a/subprojects/libffi.wrap +++ /dev/null @@ -1,4 +0,0 @@ -[wrap-git] -directory=libffi -url=https://gitlab.freedesktop.org/gstreamer/meson-ports/libffi.git -revision=meson diff --git a/subprojects/proxy-libintl.wrap b/subprojects/proxy-libintl.wrap deleted file mode 100644 index b53c8f7c3..000000000 --- a/subprojects/proxy-libintl.wrap +++ /dev/null @@ -1,4 +0,0 @@ -[wrap-git] -directory=proxy-libintl -url=https://github.com/frida/proxy-libintl.git -revision=0.1 diff --git a/test/cairo-test.c b/test/cairo-test.c index 3d241d814..df230e523 100644 --- a/test/cairo-test.c +++ b/test/cairo-test.c @@ -1508,9 +1508,13 @@ _cairo_test_context_run_for_target (cairo_test_context_t *ctx, if (! RUNNING_ON_VALGRIND) { void (* volatile old_segfault_handler)(int); void (* volatile old_segfpe_handler)(int); +#ifdef SIGPIPE void (* volatile old_sigpipe_handler)(int); +#endif void (* volatile old_sigabrt_handler)(int); +#ifdef SIGALRM void (* volatile old_sigalrm_handler)(int); +#endif /* Set up a checkpoint to get back to in case of segfaults. */ #ifdef SIGSEGV diff --git a/test/meson.build b/test/meson.build index 73bb0d2d9..b7bda2333 100644 --- a/test/meson.build +++ b/test/meson.build @@ -517,7 +517,7 @@ build_any2ppm = false has_multipage_surfaces = false add_fallback_resolution = false -if conf.get('HAVE_REAL_PTHREAD', 0) == 1 +if conf.get('CAIRO_HAS_REAL_PTHREAD', 0) == 1 test_sources += test_pthread_sources endif diff --git a/test/pdf-tagged-text.c b/test/pdf-tagged-text.c index 8908eb25d..1e5abcae8 100644 --- a/test/pdf-tagged-text.c +++ b/test/pdf-tagged-text.c @@ -377,6 +377,12 @@ create_document (cairo_surface_t *surface, cairo_t *cr) cairo_pdf_surface_set_metadata (surface, CAIRO_PDF_METADATA_CREATE_DATE, "2016-01-01T12:34:56+10:30"); cairo_pdf_surface_set_metadata (surface, CAIRO_PDF_METADATA_MOD_DATE, "2016-06-21T05:43:21Z"); + cairo_pdf_surface_set_custom_metadata (surface, "DocumentNumber", "12345"); + /* Include some non ASCII characters */ + cairo_pdf_surface_set_custom_metadata (surface, "Document Name", "\xc2\xab""cairo test\xc2\xbb"); + /* Test unsetting custom metadata. "DocumentNumber" should not be emitted. */ + cairo_pdf_surface_set_custom_metadata (surface, "DocumentNumber", ""); + cairo_tag_begin (cr, "Document", NULL); draw_cover (surface, cr); @@ -465,7 +471,9 @@ check_created_pdf(cairo_test_context_t *ctx, const char* filename) cairo_test_status_t result = CAIRO_TEST_SUCCESS; int fd; struct stat st; +#ifdef HAVE_MMAP void *contents; +#endif fd = open(filename, O_RDONLY, 0); if (fd < 0) { diff --git a/test/reference/pthread-show-text.quartz.ref.png b/test/reference/pthread-show-text.quartz.ref.png Binary files differindex 77971f956..5d51b40ad 100644 --- a/test/reference/pthread-show-text.quartz.ref.png +++ b/test/reference/pthread-show-text.quartz.ref.png diff --git a/test/reference/user-font-mask.quartz.ref.png b/test/reference/user-font-mask.quartz.ref.png Binary files differnew file mode 100644 index 000000000..1ef2160cd --- /dev/null +++ b/test/reference/user-font-mask.quartz.ref.png diff --git a/test/reference/user-font-mask.recording.ref.png b/test/reference/user-font-mask.recording.ref.png Binary files differnew file mode 100644 index 000000000..1ef2160cd --- /dev/null +++ b/test/reference/user-font-mask.recording.ref.png diff --git a/test/reference/user-font-mask.script.ref.png b/test/reference/user-font-mask.script.ref.png Binary files differnew file mode 100644 index 000000000..1ef2160cd --- /dev/null +++ b/test/reference/user-font-mask.script.ref.png diff --git a/test/reference/user-font-mask.xcb-render-0_0.ref.png b/test/reference/user-font-mask.xcb-render-0_0.ref.png Binary files differnew file mode 100644 index 000000000..1ef2160cd --- /dev/null +++ b/test/reference/user-font-mask.xcb-render-0_0.ref.png diff --git a/test/reference/user-font-mask.xcb.ref.png b/test/reference/user-font-mask.xcb.ref.png Binary files differnew file mode 100644 index 000000000..1ef2160cd --- /dev/null +++ b/test/reference/user-font-mask.xcb.ref.png diff --git a/test/reference/user-font-mask.xlib-render-0_0.ref.png b/test/reference/user-font-mask.xlib-render-0_0.ref.png Binary files differnew file mode 100644 index 000000000..1ef2160cd --- /dev/null +++ b/test/reference/user-font-mask.xlib-render-0_0.ref.png diff --git a/test/reference/user-font-mask.xlib.ref.png b/test/reference/user-font-mask.xlib.ref.png Binary files differnew file mode 100644 index 000000000..1ef2160cd --- /dev/null +++ b/test/reference/user-font-mask.xlib.ref.png diff --git a/util/cairo-script/csi-replay.c b/util/cairo-script/csi-replay.c index 4c66b7752..9d9be72c2 100644 --- a/util/cairo-script/csi-replay.c +++ b/util/cairo-script/csi-replay.c @@ -41,7 +41,9 @@ #include <stdlib.h> #include <string.h> +#if defined(CAIRO_HAS_XLIB_SURFACE) || defined(CAIRO_HAS_XLIB_XRENDER_SURFACE) static const cairo_user_data_key_t _key; +#endif #define SINGLE_SURFACE 1 diff --git a/util/cairo-trace/trace.c b/util/cairo-trace/trace.c index cc4b18c0d..bb79c85b9 100644 --- a/util/cairo-trace/trace.c +++ b/util/cairo-trace/trace.c @@ -99,8 +99,13 @@ #define CAIRO_BITSWAP8(c) ((((c) * 0x0802LU & 0x22110LU) | ((c) * 0x8020LU & 0x88440LU)) * 0x10101LU >> 16) #if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ > 4) -#define CAIRO_PRINTF_FORMAT(fmt_index, va_index) \ +#ifdef __MINGW32__ +#define CAIRO_PRINTF_FORMAT(fmt_index, va_index) \ + __attribute__((__format__(__MINGW_PRINTF_FORMAT, fmt_index, va_index))) +#else +#define CAIRO_PRINTF_FORMAT(fmt_index, va_index) \ __attribute__((__format__(__printf__, fmt_index, va_index))) +#endif #else #define CAIRO_PRINTF_FORMAT(fmt_index, va_index) #endif |