summaryrefslogtreecommitdiff
path: root/base/gsiparam.h
diff options
context:
space:
mode:
Diffstat (limited to 'base/gsiparam.h')
-rw-r--r--base/gsiparam.h101
1 files changed, 98 insertions, 3 deletions
diff --git a/base/gsiparam.h b/base/gsiparam.h
index bcf65371f..3c776a719 100644
--- a/base/gsiparam.h
+++ b/base/gsiparam.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2021 Artifex Software, Inc.
+/* Copyright (C) 2001-2023 Artifex Software, Inc.
All Rights Reserved.
This software is provided AS-IS with no warranty, either express or
@@ -73,7 +73,6 @@ typedef enum {
* how the data are actually supplied.
*/
#define gs_data_image_common\
- const gx_image_type_t *type;\
/*\
* Define the transformation from user space to image space.\
*/\
@@ -104,11 +103,107 @@ typedef enum {
/*\
* Define whether to smooth the image.\
*/\
- bool Interpolate
+ bool Interpolate;\
+ /* If set, then the imagematrices have been changed (currently\
+ * just by the pdfwrite device for the purposes of handling\
+ * type3 masked images), so we can't trust them for mapping\
+ * backwards for source clipping. */\
+ bool imagematrices_are_untrustworthy;\
+ /* Put the type field last. See why below.*/\
+ const gx_image_type_t *type
typedef struct gs_data_image_s {
gs_data_image_common;
} gs_data_image_t;
+/* Ghostscript uses macros to define 'extended' structures.
+ * Suppose we want to define a structure foo, that can be extended to
+ * bigger_foo (and then maybe even to even_bigger_foo). We first
+ * define a macro such as 'foo_common' that contains the fields for
+ * foo.
+ *
+ * #define foo_common \
+ * void *a;\
+ * int b
+ *
+ * Then we define foo in terms of this:
+ *
+ * typedef struct {
+ * foo_common;
+ * } foo;
+ *
+ * Then we can extend this to other types as follows:
+ *
+ * typedef struct {
+ * foo_common;
+ * int c;
+ * int d;
+ * } bigger_foo;
+ *
+ * Or we can use macros to use even further extension:
+ *
+ * #define bigger_foo_common \
+ * foo_common;\
+ * int c;\
+ * int d
+ *
+ * typedef struct {
+ * bigger_foo_common;
+ * } bigger_foo;
+ *
+ * and hence:
+ *
+ * typedef struct {
+ * bigger_foo_common;
+ * int e;
+ * } even_bigger_foo;
+ *
+ * On the whole, this works well, and avoids the extra layer of
+ * structure that would occur if we used the more usual structure
+ * definition way of working:
+ *
+ * typedef struct {
+ * void *a;
+ * int b;
+ * } foo;
+ *
+ * typedef struct {
+ * foo base;
+ * int c;
+ * int d;
+ * } bigger_foo;
+ *
+ * typedef struct {
+ * bigger_foo base;
+ * int e;
+ * } even_bigger_foo;
+ *
+ * In this formulation even_bigger_foo would need to access 'a' as
+ * base.base.a, whereas the ghostscript method can just use 'a'.
+ *
+ * Unfortunately, there is one drawback to this method, to do with
+ * structure packing in C. C likes structures to be easily used in
+ * arrays. Hence (in a 64bit build), foo will be 16 bytes, where
+ * the foo fields included at the start of bigger_foo will only
+ * take 12.
+ *
+ * This means that constructs such as:
+ *
+ * void simple(foo *a)
+ * {
+ * bigger_foo b;
+ * b.c = 1;
+ * *(foo *)b = *a;
+ * ...
+ * }
+ *
+ * where we attempt to initialise the 'foo' fields of a bigger_foo, b, by
+ * copying them from an existing 'foo', will corrupt b.c.
+ *
+ * To allow this idiom to work, we either need to ensure that the largest
+ * alignment object in the 'foo' fields comes last, or we need to introduce
+ * padding. The former is easier.
+ */
+
#define public_st_gs_data_image() /* in gximage.c */\
gs_public_st_simple(st_gs_data_image, gs_data_image_t,\
"gs_data_image_t")