summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile7
-rw-r--r--xps/muxps.h3
-rw-r--r--xps/xpsanalyze.c309
-rw-r--r--xps/xpscolor.c191
-rw-r--r--xps/xpscommon.c187
-rw-r--r--xps/xpsfont.c54
-rw-r--r--xps/xpsglyphs.c70
-rw-r--r--xps/xpsimage.c4
-rw-r--r--xps/xpsjxr.c10
-rw-r--r--xps/xpsmem.c7
-rw-r--r--xps/xpsopacity.c63
-rw-r--r--xps/xpstile.c35
-rw-r--r--xps/xpsutf.c55
-rw-r--r--xps/xpsvisual.c39
14 files changed, 289 insertions, 745 deletions
diff --git a/Makefile b/Makefile
index 11fb41c6..96ebd0f2 100644
--- a/Makefile
+++ b/Makefile
@@ -172,27 +172,20 @@ $(MUPDF_OBJ): $(MUPDF_HDR)
MUXPS_HDR := $(FITZ_HDR) xps/muxps.h
MUXPS_SRC := \
- xps/xpsanalyze.c \
- xps/xpscolor.c \
xps/xpscommon.c \
xps/xpsdoc.c \
- xps/xpsfont.c \
xps/xpsglyphs.c \
xps/xpsgradient.c \
xps/xpshash.c \
- xps/xpsjxr.c \
xps/xpsimage.c \
xps/xpsjpeg.c \
xps/xpsmem.c \
- xps/xpsopacity.c \
xps/xpspage.c \
xps/xpspath.c \
xps/xpspng.c \
xps/xpsresource.c \
xps/xpstiff.c \
xps/xpstile.c \
- xps/xpsutf.c \
- xps/xpsvisual.c \
xps/xpsxml.c \
xps/xpszip.c
MUXPS_OBJ := $(MUXPS_SRC:xps/%.c=$(OBJDIR)/%.o)
diff --git a/xps/muxps.h b/xps/muxps.h
index 0455ee68..e4595dbe 100644
--- a/xps/muxps.h
+++ b/xps/muxps.h
@@ -32,8 +32,6 @@ typedef struct xps_context_s xps_context;
int xps_strcasecmp(char *a, char *b);
void xps_absolute_path(char *output, char *base_uri, char *path, int output_size);
-int xps_utf8_to_ucs(int *p, const char *s, int n);
-
/*
* Generic hashtable.
*/
@@ -153,7 +151,6 @@ void xps_debug_path(xps_context *ctx);
* Colorspaces and colors.
*/
-fz_colorspace *xps_read_icc_colorspace(xps_context *ctx, char *base_uri, char *profile);
void xps_parse_color(xps_context *ctx, char *base_uri, char *hexstring, fz_colorspace **csp, float *samples);
void xps_set_color(xps_context *ctx, fz_colorspace *colorspace, float *samples);
diff --git a/xps/xpsanalyze.c b/xps/xpsanalyze.c
deleted file mode 100644
index 86dd4626..00000000
--- a/xps/xpsanalyze.c
+++ /dev/null
@@ -1,309 +0,0 @@
-/* XPS interpreter - analyze page checking for transparency.
- * This is a stripped down parser that looks for alpha values < 1.0 in
- * any part of the page.
- */
-
-#include "fitz.h"
-#include "muxps.h"
-
-static int
-xps_remote_resource_dictionary_has_transparency(xps_context *ctx, char *base_uri, char *source_att)
-{
- //dputs("page has transparency: uses a remote resource; not parsed; being conservative\n");
- return 1;
-}
-
-int
-xps_resource_dictionary_has_transparency(xps_context *ctx, char *base_uri, xml_element *root)
-{
- char *source;
- xml_element *node;
-
- source = xml_att(root, "Source");
- if (source)
- return xps_remote_resource_dictionary_has_transparency(ctx, base_uri, source);
-
- for (node = xml_down(root); node; node = xml_next(node))
- {
- // TODO: ... all kinds of stuff can be here, brushes, elements, whatnot
- }
-
- return 1;
-}
-
-static int
-xps_gradient_stops_have_transparency(xps_context *ctx, char *base_uri, xml_element *root)
-{
- xml_element *node;
- fz_colorspace *colorspace;
- char *color_att;
- float samples[32];
-
- for (node = xml_down(root); node; node = xml_next(node))
- {
- if (!strcmp(xml_tag(node), "GradientStop"))
- {
- color_att = xml_att(node, "Color");
- if (color_att)
- {
- xps_parse_color(ctx, base_uri, color_att, &colorspace, samples);
- if (samples[0] < 1.0)
- {
- //dputs("page has transparency: GradientStop has alpha\n");
- return 1;
- }
- }
- }
- }
-
- return 0;
-}
-
-static int
-xps_gradient_brush_has_transparency(xps_context *ctx, char *base_uri, xml_element *root)
-{
- xml_element *node;
- char *opacity_att;
-
- opacity_att = xml_att(root, "Opacity");
- if (opacity_att)
- {
- if (atof(opacity_att) < 1.0)
- {
- //dputs("page has transparency: GradientBrush Opacity\n");
- return 1;
- }
- }
-
- for (node = xml_down(root); node; node = xml_next(node))
- {
- if (!strcmp(xml_tag(node), "RadialGradientBrush.GradientStops"))
- {
- if (xps_gradient_stops_have_transparency(ctx, base_uri, node))
- return 1;
- }
- if (!strcmp(xml_tag(node), "LinearGradientBrush.GradientStops"))
- {
- if (xps_gradient_stops_have_transparency(ctx, base_uri, node))
- return 1;
- }
- }
-
- return 0;
-}
-
-static int
-xps_brush_has_transparency(xps_context *ctx, char *base_uri, xml_element *root)
-{
- char *opacity_att;
- char *color_att;
- xml_element *node;
-
- fz_colorspace *colorspace;
- float samples[32];
-
- if (!strcmp(xml_tag(root), "SolidColorBrush"))
- {
- opacity_att = xml_att(root, "Opacity");
- if (opacity_att)
- {
- if (atof(opacity_att) < 1.0)
- {
- //dputs("page has transparency: SolidColorBrush Opacity\n");
- return 1;
- }
- }
-
- color_att = xml_att(root, "Color");
- if (color_att)
- {
- xps_parse_color(ctx, base_uri, color_att, &colorspace, samples);
- if (samples[0] < 1.0)
- {
- //dputs("page has transparency: SolidColorBrush Color has alpha\n");
- return 1;
- }
- }
- }
-
- if (!strcmp(xml_tag(root), "VisualBrush"))
- {
- char *opacity_att = xml_att(root, "Opacity");
- if (opacity_att)
- {
- if (atof(opacity_att) < 1.0)
- {
- //dputs("page has transparency: VisualBrush Opacity\n");
- return 1;
- }
- }
-
- for (node = xml_down(root); node; node = xml_next(node))
- {
- if (!strcmp(xml_tag(node), "VisualBrush.Visual"))
- {
- if (xps_element_has_transparency(ctx, base_uri, xml_down(node)))
- return 1;
- }
- }
- }
-
- if (!strcmp(xml_tag(root), "ImageBrush"))
- {
- if (xps_image_brush_has_transparency(ctx, base_uri, root))
- return 1;
- }
-
- if (!strcmp(xml_tag(root), "LinearGradientBrush"))
- {
- if (xps_gradient_brush_has_transparency(ctx, base_uri, root))
- return 1;
- }
-
- if (!strcmp(xml_tag(root), "RadialGradientBrush"))
- {
- if (xps_gradient_brush_has_transparency(ctx, base_uri, root))
- return 1;
- }
-
- return 0;
-}
-
-static int
-xps_path_has_transparency(xps_context *ctx, char *base_uri, xml_element *root)
-{
- xml_element *node;
-
- for (node = xml_down(root); node; node = xml_next(node))
- {
- if (!strcmp(xml_tag(node), "Path.OpacityMask"))
- {
- //dputs("page has transparency: Path.OpacityMask\n");
- return 1;
- }
-
- if (!strcmp(xml_tag(node), "Path.Stroke"))
- {
- if (xps_brush_has_transparency(ctx, base_uri, xml_down(node)))
- return 1;
- }
-
- if (!strcmp(xml_tag(node), "Path.Fill"))
- {
- if (xps_brush_has_transparency(ctx, base_uri, xml_down(node)))
- return 1;
- }
- }
-
- return 0;
-}
-
-static int
-xps_glyphs_has_transparency(xps_context *ctx, char *base_uri, xml_element *root)
-{
- xml_element *node;
-
- for (node = xml_down(root); node; node = xml_next(node))
- {
- if (!strcmp(xml_tag(node), "Glyphs.OpacityMask"))
- {
- //dputs("page has transparency: Glyphs.OpacityMask\n");
- return 1;
- }
-
- if (!strcmp(xml_tag(node), "Glyphs.Fill"))
- {
- if (xps_brush_has_transparency(ctx, base_uri, xml_down(node)))
- return 1;
- }
- }
-
- return 0;
-}
-
-static int
-xps_canvas_has_transparency(xps_context *ctx, char *base_uri, xml_element *root)
-{
- xml_element *node;
-
- for (node = xml_down(root); node; node = xml_next(node))
- {
- if (!strcmp(xml_tag(node), "Canvas.Resources"))
- {
- if (xps_resource_dictionary_has_transparency(ctx, base_uri, xml_down(node)))
- return 1;
- }
-
- if (!strcmp(xml_tag(node), "Canvas.OpacityMask"))
- {
- //dputs("page has transparency: Canvas.OpacityMask\n");
- return 1;
- }
-
- if (xps_element_has_transparency(ctx, base_uri, node))
- return 1;
- }
-
- return 0;
-}
-
-int
-xps_element_has_transparency(xps_context *ctx, char *base_uri, xml_element *node)
-{
- char *opacity_att;
- char *stroke_att;
- char *fill_att;
-
- fz_colorspace *colorspace;
- float samples[32];
-
- stroke_att = xml_att(node, "Stroke");
- if (stroke_att)
- {
- xps_parse_color(ctx, base_uri, stroke_att, &colorspace, samples);
- if (samples[0] < 1.0)
- {
- //dprintf1("page has transparency: Stroke alpha=%g\n", samples[0]);
- return 1;
- }
- }
-
- fill_att = xml_att(node, "Fill");
- if (fill_att)
- {
- xps_parse_color(ctx, base_uri, fill_att, &colorspace, samples);
- if (samples[0] < 1.0)
- {
- //dprintf1("page has transparency: Fill alpha=%g\n", samples[0]);
- return 1;
- }
- }
-
- opacity_att = xml_att(node, "Opacity");
- if (opacity_att)
- {
- if (atof(opacity_att) < 1.0)
- {
- //dprintf1("page has transparency: Opacity=%g\n", atof(opacity_att));
- return 1;
- }
- }
-
- if (xml_att(node, "OpacityMask"))
- {
- //dputs("page has transparency: OpacityMask\n");
- return 1;
- }
-
- if (!strcmp(xml_tag(node), "Path"))
- if (xps_path_has_transparency(ctx, base_uri, node))
- return 1;
- if (!strcmp(xml_tag(node), "Glyphs"))
- if (xps_glyphs_has_transparency(ctx, base_uri, node))
- return 1;
- if (!strcmp(xml_tag(node), "Canvas"))
- if (xps_canvas_has_transparency(ctx, base_uri, node))
- return 1;
-
- return 0;
-}
diff --git a/xps/xpscolor.c b/xps/xpscolor.c
deleted file mode 100644
index 37dee5fe..00000000
--- a/xps/xpscolor.c
+++ /dev/null
@@ -1,191 +0,0 @@
-#include "fitz.h"
-#include "muxps.h"
-
-#include <ctype.h> /* for toupper() */
-
-void
-xps_set_color(xps_context *ctx, fz_colorspace *colorspace, float *samples)
-{
- int i;
- ctx->colorspace = colorspace;
- for (i = 0; i < colorspace->n; i++)
- ctx->color[i] = samples[i + 1];
- ctx->alpha = samples[0] * ctx->opacity[ctx->opacity_top];
-}
-
-static int unhex(int chr)
-{
- const char *hextable = "0123456789ABCDEF";
- return strchr(hextable, (toupper(chr))) - hextable;
-}
-
-static int count_commas(char *s)
-{
- int n = 0;
- while (*s)
- {
- if (*s == ',')
- n ++;
- s ++;
- }
- return n;
-}
-
-void
-xps_parse_color(xps_context *ctx, char *base_uri, char *string,
- fz_colorspace **csp, float *samples)
-{
- char *p;
- int i, n;
- char buf[1024];
- char *profile;
-
- *csp = fz_devicergb;
-
- samples[0] = 1.0;
- samples[1] = 0.0;
- samples[2] = 0.0;
- samples[3] = 0.0;
-
- if (string[0] == '#')
- {
- if (strlen(string) == 9)
- {
- samples[0] = unhex(string[1]) * 16 + unhex(string[2]);
- samples[1] = unhex(string[3]) * 16 + unhex(string[4]);
- samples[2] = unhex(string[5]) * 16 + unhex(string[6]);
- samples[3] = unhex(string[7]) * 16 + unhex(string[8]);
- }
- else
- {
- samples[0] = 255.0;
- samples[1] = unhex(string[1]) * 16 + unhex(string[2]);
- samples[2] = unhex(string[3]) * 16 + unhex(string[4]);
- samples[3] = unhex(string[5]) * 16 + unhex(string[6]);
- }
-
- samples[0] /= 255.0;
- samples[1] /= 255.0;
- samples[2] /= 255.0;
- samples[3] /= 255.0;
- }
-
- else if (string[0] == 's' && string[1] == 'c' && string[2] == '#')
- {
- if (count_commas(string) == 2)
- sscanf(string, "sc#%g,%g,%g", samples + 1, samples + 2, samples + 3);
- if (count_commas(string) == 3)
- sscanf(string, "sc#%g,%g,%g,%g", samples, samples + 1, samples + 2, samples + 3);
- }
-
- else if (strstr(string, "ContextColor ") == string)
- {
- /* Crack the string for profile name and sample values */
- strcpy(buf, string);
-
- profile = strchr(buf, ' ');
- if (!profile)
- {
- fz_warn("cannot find icc profile uri in '%s'", string);
- return;
- }
-
- *profile++ = 0;
- p = strchr(profile, ' ');
- if (!p)
- {
- fz_warn("cannot find component values in '%s'", profile);
- return;
- }
-
- *p++ = 0;
- n = count_commas(p) + 1;
- i = 0;
- while (i < n)
- {
- samples[i++] = atof(p);
- p = strchr(p, ',');
- if (!p)
- break;
- p ++;
- if (*p == ' ')
- p ++;
- }
- while (i < n)
- {
- samples[i++] = 0.0;
- }
-
- *csp = xps_read_icc_colorspace(ctx, base_uri, profile);
- if (!*csp)
- {
- /* Default fallbacks if the ICC stuff fails */
- switch (n)
- {
- case 2: *csp = fz_devicegray; break; /* alpha + tint */
- case 4: *csp = fz_devicergb; break; /* alpha + RGB */
- case 5: *csp = fz_devicecmyk; break; /* alpha + CMYK */
- default: *csp = fz_devicegray; break;
- }
- }
- }
-}
-
-fz_colorspace *
-xps_read_icc_colorspace(xps_context *ctx, char *base_uri, char *profilename)
-{
-#if 0
- fz_colorspace *space;
- xps_part *part;
- char partname[1024];
-
- /* Find ICC colorspace part */
- xps_absolute_path(partname, base_uri, profilename, sizeof partname);
-
- /* See if we cached the profile */
- space = xps_hash_lookup(ctx->colorspace_table, partname);
- if (!space)
- {
- part = xps_read_part(ctx, partname);
-
- /* Problem finding profile. Don't fail, just use default */
- if (!part) {
- fz_warn("cannot find icc profile part: %s", partname);
- return NULL;
- }
-
- /* Create the profile */
- profile = gsicc_profile_new(NULL, ctx->memory, NULL, 0);
-
- /* Set buffer */
- profile->buffer = part->data;
- profile->buffer_size = part->size;
-
- /* Parse */
- gsicc_init_profile_info(profile);
-
- /* Problem with profile. Don't fail, just use the default */
- if (profile->profile_handle == NULL)
- {
- gsicc_profile_reference(profile, -1);
- fz_warn("there was a problem with the profile: %s", partname);
- return NULL;
- }
-
- /* Create a new colorspace and associate with the profile */
- gs_cspace_build_ICC(&space, NULL, ctx->memory);
- space->cmm_icc_profile_data = profile;
-
- /* Steal the buffer data before freeing the part */
- part->data = NULL;
- xps_free_part(ctx, part);
-
- /* Add colorspace to xps color cache. */
- xps_hash_insert(ctx, ctx->colorspace_table, fz_strdup(partname), space);
- }
-
- return space;
-#else
- return NULL;
-#endif
-}
diff --git a/xps/xpscommon.c b/xps/xpscommon.c
index 77aec58c..7e489ef7 100644
--- a/xps/xpscommon.c
+++ b/xps/xpscommon.c
@@ -1,6 +1,14 @@
#include "fitz.h"
#include "muxps.h"
+static inline int unhex(int a)
+{
+ if (a >= 'A' && a <= 'F') return a - 'A' + 0xA;
+ if (a >= 'a' && a <= 'f') return a - 'a' + 0xA;
+ if (a >= '0' && a <= '9') return a - '0';
+ return 0;
+}
+
void
xps_parse_brush(xps_context *ctx, fz_matrix ctm, fz_rect area, char *base_uri, xps_resource *dict, xml_element *node)
{
@@ -30,6 +38,67 @@ xps_parse_element(xps_context *ctx, fz_matrix ctm, char *base_uri, xps_resource
}
void
+xps_begin_opacity(xps_context *ctx, fz_matrix ctm, fz_rect area,
+ char *base_uri, xps_resource *dict,
+ char *opacity_att, xml_element *opacity_mask_tag)
+{
+ float opacity;
+
+ if (!opacity_att && !opacity_mask_tag)
+ return;
+
+ opacity = 1.0;
+ if (opacity_att)
+ opacity = atof(opacity_att);
+
+ if (opacity_mask_tag && !strcmp(xml_tag(opacity_mask_tag), "SolidColorBrush"))
+ {
+ char *scb_opacity_att = xml_att(opacity_mask_tag, "Opacity");
+ char *scb_color_att = xml_att(opacity_mask_tag, "Color");
+ if (scb_opacity_att)
+ opacity = opacity * atof(scb_opacity_att);
+ if (scb_color_att)
+ {
+ fz_colorspace *colorspace;
+ float samples[32];
+ xps_parse_color(ctx, base_uri, scb_color_att, &colorspace, samples);
+ opacity = opacity * samples[0];
+ }
+ opacity_mask_tag = NULL;
+ }
+
+ if (ctx->opacity_top + 1 < nelem(ctx->opacity))
+ {
+ ctx->opacity[ctx->opacity_top + 1] = ctx->opacity[ctx->opacity_top] * opacity;
+ ctx->opacity_top++;
+ }
+
+ if (opacity_mask_tag)
+ {
+ ctx->dev->beginmask(ctx->dev->user, area, 0, NULL, NULL);
+ xps_parse_brush(ctx, ctm, area, base_uri, dict, opacity_mask_tag);
+ ctx->dev->endmask(ctx->dev->user);
+ }
+}
+
+void
+xps_end_opacity(xps_context *ctx, char *base_uri, xps_resource *dict,
+ char *opacity_att, xml_element *opacity_mask_tag)
+{
+ if (!opacity_att && !opacity_mask_tag)
+ return;
+
+ if (ctx->opacity_top > 0)
+ ctx->opacity_top--;
+
+ if (opacity_mask_tag)
+ {
+ if (strcmp(xml_tag(opacity_mask_tag), "SolidColorBrush"))
+ ctx->dev->popclip(ctx->dev->user);
+ }
+}
+
+void
xps_parse_render_transform(xps_context *ctx, char *transform, fz_matrix *matrix)
{
float args[6];
@@ -93,3 +162,121 @@ xps_parse_rectangle(xps_context *ctx, char *text, fz_rect *rect)
rect->x1 = args[0] + args[2];
rect->y1 = args[1] + args[3];
}
+
+static int count_commas(char *s)
+{
+ int n = 0;
+ while (*s)
+ {
+ if (*s == ',')
+ n ++;
+ s ++;
+ }
+ return n;
+}
+
+void
+xps_parse_color(xps_context *ctx, char *base_uri, char *string,
+ fz_colorspace **csp, float *samples)
+{
+ char *p;
+ int i, n;
+ char buf[1024];
+ char *profile;
+
+ *csp = fz_devicergb;
+
+ samples[0] = 1.0;
+ samples[1] = 0.0;
+ samples[2] = 0.0;
+ samples[3] = 0.0;
+
+ if (string[0] == '#')
+ {
+ if (strlen(string) == 9)
+ {
+ samples[0] = unhex(string[1]) * 16 + unhex(string[2]);
+ samples[1] = unhex(string[3]) * 16 + unhex(string[4]);
+ samples[2] = unhex(string[5]) * 16 + unhex(string[6]);
+ samples[3] = unhex(string[7]) * 16 + unhex(string[8]);
+ }
+ else
+ {
+ samples[0] = 255.0;
+ samples[1] = unhex(string[1]) * 16 + unhex(string[2]);
+ samples[2] = unhex(string[3]) * 16 + unhex(string[4]);
+ samples[3] = unhex(string[5]) * 16 + unhex(string[6]);
+ }
+
+ samples[0] /= 255.0;
+ samples[1] /= 255.0;
+ samples[2] /= 255.0;
+ samples[3] /= 255.0;
+ }
+
+ else if (string[0] == 's' && string[1] == 'c' && string[2] == '#')
+ {
+ if (count_commas(string) == 2)
+ sscanf(string, "sc#%g,%g,%g", samples + 1, samples + 2, samples + 3);
+ if (count_commas(string) == 3)
+ sscanf(string, "sc#%g,%g,%g,%g", samples, samples + 1, samples + 2, samples + 3);
+ }
+
+ else if (strstr(string, "ContextColor ") == string)
+ {
+ /* Crack the string for profile name and sample values */
+ strcpy(buf, string);
+
+ profile = strchr(buf, ' ');
+ if (!profile)
+ {
+ fz_warn("cannot find icc profile uri in '%s'", string);
+ return;
+ }
+
+ *profile++ = 0;
+ p = strchr(profile, ' ');
+ if (!p)
+ {
+ fz_warn("cannot find component values in '%s'", profile);
+ return;
+ }
+
+ *p++ = 0;
+ n = count_commas(p) + 1;
+ i = 0;
+ while (i < n)
+ {
+ samples[i++] = atof(p);
+ p = strchr(p, ',');
+ if (!p)
+ break;
+ p ++;
+ if (*p == ' ')
+ p ++;
+ }
+ while (i < n)
+ {
+ samples[i++] = 0.0;
+ }
+
+ /* TODO: load ICC profile */
+ switch (n)
+ {
+ case 2: *csp = fz_devicegray; break;
+ case 4: *csp = fz_devicergb; break;
+ case 5: *csp = fz_devicecmyk; break;
+ default: *csp = fz_devicegray; break;
+ }
+ }
+}
+
+void
+xps_set_color(xps_context *ctx, fz_colorspace *colorspace, float *samples)
+{
+ int i;
+ ctx->colorspace = colorspace;
+ for (i = 0; i < colorspace->n; i++)
+ ctx->color[i] = samples[i + 1];
+ ctx->alpha = samples[0] * ctx->opacity[ctx->opacity_top];
+}
diff --git a/xps/xpsfont.c b/xps/xpsfont.c
deleted file mode 100644
index a76cc10e..00000000
--- a/xps/xpsfont.c
+++ /dev/null
@@ -1,54 +0,0 @@
-#include "fitz.h"
-#include "muxps.h"
-
-#include <ft2build.h>
-#include FT_FREETYPE_H
-#include FT_ADVANCES_H
-
-int
-xps_count_font_encodings(fz_font *font)
-{
- FT_Face face = font->ftface;
- return face->num_charmaps;
-}
-
-void
-xps_identify_font_encoding(fz_font *font, int idx, int *pid, int *eid)
-{
- FT_Face face = font->ftface;
- *pid = face->charmaps[idx]->platform_id;
- *eid = face->charmaps[idx]->encoding_id;
-}
-
-void
-xps_select_font_encoding(fz_font *font, int idx)
-{
- FT_Face face = font->ftface;
- FT_Set_Charmap(face, face->charmaps[idx]);
-}
-
-int
-xps_encode_font_char(fz_font *font, int code)
-{
- FT_Face face = font->ftface;
- int gid = FT_Get_Char_Index(face, code);
- if (gid == 0 && face->charmap->platform_id == 3 && face->charmap->encoding_id == 0)
- gid = FT_Get_Char_Index(face, 0xF000 | code);
- return gid;
-}
-
-void
-xps_measure_font_glyph(xps_context *ctx, fz_font *font, int gid, xps_glyph_metrics *mtx)
-{
- int mask = FT_LOAD_NO_BITMAP | FT_LOAD_NO_HINTING | FT_LOAD_IGNORE_TRANSFORM;
- FT_Face face = font->ftface;
- FT_Fixed hadv, vadv;
-
- FT_Set_Char_Size(face, 64, 64, 72, 72);
- FT_Get_Advance(face, gid, mask, &hadv);
- FT_Get_Advance(face, gid, mask | FT_LOAD_VERTICAL_LAYOUT, &vadv);
-
- mtx->hadv = hadv / 65536.0f;
- mtx->vadv = vadv / 65536.0f;
- mtx->vorg = face->ascender / (float) face->units_per_EM;
-}
diff --git a/xps/xpsglyphs.c b/xps/xpsglyphs.c
index 1936534b..91c7dbcd 100644
--- a/xps/xpsglyphs.c
+++ b/xps/xpsglyphs.c
@@ -1,13 +1,69 @@
#include "fitz.h"
#include "muxps.h"
-#include <ctype.h> /* for tolower() */
+#include <ft2build.h>
+#include FT_FREETYPE_H
+#include FT_ADVANCES_H
-static inline int unhex(int i)
+static inline int ishex(int a)
{
- if (isdigit(i))
- return i - '0';
- return tolower(i) - 'a' + 10;
+ return (a >= 'A' && a <= 'F') || (a >= 'a' && a <= 'f') || (a >= '0' && a <= '9');
+}
+
+static inline int unhex(int a)
+{
+ if (a >= 'A' && a <= 'F') return a - 'A' + 0xA;
+ if (a >= 'a' && a <= 'f') return a - 'a' + 0xA;
+ if (a >= '0' && a <= '9') return a - '0';
+ return 0;
+}
+
+int
+xps_count_font_encodings(fz_font *font)
+{
+ FT_Face face = font->ftface;
+ return face->num_charmaps;
+}
+
+void
+xps_identify_font_encoding(fz_font *font, int idx, int *pid, int *eid)
+{
+ FT_Face face = font->ftface;
+ *pid = face->charmaps[idx]->platform_id;
+ *eid = face->charmaps[idx]->encoding_id;
+}
+
+void
+xps_select_font_encoding(fz_font *font, int idx)
+{
+ FT_Face face = font->ftface;
+ FT_Set_Charmap(face, face->charmaps[idx]);
+}
+
+int
+xps_encode_font_char(fz_font *font, int code)
+{
+ FT_Face face = font->ftface;
+ int gid = FT_Get_Char_Index(face, code);
+ if (gid == 0 && face->charmap->platform_id == 3 && face->charmap->encoding_id == 0)
+ gid = FT_Get_Char_Index(face, 0xF000 | code);
+ return gid;
+}
+
+void
+xps_measure_font_glyph(xps_context *ctx, fz_font *font, int gid, xps_glyph_metrics *mtx)
+{
+ int mask = FT_LOAD_NO_BITMAP | FT_LOAD_NO_HINTING | FT_LOAD_IGNORE_TRANSFORM;
+ FT_Face face = font->ftface;
+ FT_Fixed hadv, vadv;
+
+ FT_Set_Char_Size(face, 64, 64, 72, 72);
+ FT_Get_Advance(face, gid, mask, &hadv);
+ FT_Get_Advance(face, gid, mask | FT_LOAD_VERTICAL_LAYOUT, &vadv);
+
+ mtx->hadv = hadv / 65536.0f;
+ mtx->vadv = vadv / 65536.0f;
+ mtx->vorg = face->ascender / (float) face->units_per_EM;
}
/*
@@ -28,7 +84,7 @@ xps_deobfuscate_font_resource(xps_context *ctx, xps_part *part)
for (i = 0; i < 32 && *p; p++)
{
- if (isxdigit(*p))
+ if (ishex(*p))
buf[i++] = *p;
}
buf[i] = 0;
@@ -225,7 +281,7 @@ xps_parse_glyphs_imp(xps_context *ctx, fz_matrix ctm, fz_font *font, float size,
{
if (us && un > 0)
{
- int t = xps_utf8_to_ucs(&char_code, us, un);
+ int t = chartorune(&char_code, us);
us += t; un -= t;
}
}
diff --git a/xps/xpsimage.c b/xps/xpsimage.c
index c9bf64fd..ced58bb5 100644
--- a/xps/xpsimage.c
+++ b/xps/xpsimage.c
@@ -25,9 +25,7 @@ xps_decode_image(xps_image **imagep, xps_context *ctx, xps_part *part)
}
else if (memcmp(buf, "II", 2) == 0 && buf[2] == 0xBC)
{
- error = xps_decode_jpegxr(imagep, ctx, buf, len);
- if (error)
- return fz_rethrow(error, "cannot decode JPEG-XR image");
+ return fz_throw("JPEG-XR codec is not available");
}
else if (memcmp(buf, "MM", 2) == 0 || memcmp(buf, "II", 2) == 0)
{
diff --git a/xps/xpsjxr.c b/xps/xpsjxr.c
deleted file mode 100644
index 9499bdec..00000000
--- a/xps/xpsjxr.c
+++ /dev/null
@@ -1,10 +0,0 @@
-/* JPEG-XR (formerly HD-Photo (formerly Windows Media Photo)) support */
-
-#include "fitz.h"
-#include "muxps.h"
-
-int
-xps_decode_jpegxr(xps_image **imagep, xps_context *ctx, byte *rbuf, int rlen)
-{
- return fz_throw("JPEG-XR codec is not available");
-}
diff --git a/xps/xpsmem.c b/xps/xpsmem.c
index a85b2117..76175d68 100644
--- a/xps/xpsmem.c
+++ b/xps/xpsmem.c
@@ -1,8 +1,7 @@
#include "fitz.h"
#include "muxps.h"
-static inline int
-xps_tolower(int c)
+static inline int tolower(int c)
{
if (c >= 'A' && c <= 'Z')
return c + 32;
@@ -12,13 +11,13 @@ xps_tolower(int c)
int
xps_strcasecmp(char *a, char *b)
{
- while (xps_tolower(*a) == xps_tolower(*b))
+ while (tolower(*a) == tolower(*b))
{
if (*a++ == 0)
return 0;
b++;
}
- return xps_tolower(*a) - xps_tolower(*b);
+ return tolower(*a) - tolower(*b);
}
#define SEP(x) ((x)=='/' || (x) == 0)
diff --git a/xps/xpsopacity.c b/xps/xpsopacity.c
deleted file mode 100644
index 75064452..00000000
--- a/xps/xpsopacity.c
+++ /dev/null
@@ -1,63 +0,0 @@
-#include "fitz.h"
-#include "muxps.h"
-
-void
-xps_begin_opacity(xps_context *ctx, fz_matrix ctm, fz_rect area,
- char *base_uri, xps_resource *dict,
- char *opacity_att, xml_element *opacity_mask_tag)
-{
- float opacity;
-
- if (!opacity_att && !opacity_mask_tag)
- return;
-
- opacity = 1.0;
- if (opacity_att)
- opacity = atof(opacity_att);
-
- if (opacity_mask_tag && !strcmp(xml_tag(opacity_mask_tag), "SolidColorBrush"))
- {
- char *scb_opacity_att = xml_att(opacity_mask_tag, "Opacity");
- char *scb_color_att = xml_att(opacity_mask_tag, "Color");
- if (scb_opacity_att)
- opacity = opacity * atof(scb_opacity_att);
- if (scb_color_att)
- {
- fz_colorspace *colorspace;
- float samples[32];
- xps_parse_color(ctx, base_uri, scb_color_att, &colorspace, samples);
- opacity = opacity * samples[0];
- }
- opacity_mask_tag = NULL;
- }
-
- if (ctx->opacity_top + 1 < nelem(ctx->opacity))
- {
- ctx->opacity[ctx->opacity_top + 1] = ctx->opacity[ctx->opacity_top] * opacity;
- ctx->opacity_top++;
- }
-
- if (opacity_mask_tag)
- {
- ctx->dev->beginmask(ctx->dev->user, area, 0, NULL, NULL);
- xps_parse_brush(ctx, ctm, area, base_uri, dict, opacity_mask_tag);
- ctx->dev->endmask(ctx->dev->user);
- }
-}
-
-void
-xps_end_opacity(xps_context *ctx, char *base_uri, xps_resource *dict,
- char *opacity_att, xml_element *opacity_mask_tag)
-{
- if (!opacity_att && !opacity_mask_tag)
- return;
-
- if (ctx->opacity_top > 0)
- ctx->opacity_top--;
-
- if (opacity_mask_tag)
- {
- if (strcmp(xml_tag(opacity_mask_tag), "SolidColorBrush"))
- ctx->dev->popclip(ctx->dev->user);
- }
-}
diff --git a/xps/xpstile.c b/xps/xpstile.c
index ecc0af3f..82ec543f 100644
--- a/xps/xpstile.c
+++ b/xps/xpstile.c
@@ -191,3 +191,38 @@ xps_parse_tiling_brush(xps_context *ctx, fz_matrix ctm, fz_rect area,
xps_end_opacity(ctx, base_uri, dict, opacity_att, NULL);
}
+
+static void
+xps_paint_visual_brush(xps_context *ctx, fz_matrix ctm,
+ char *base_uri, xps_resource *dict, xml_element *root, void *visual_tag)
+{
+ xps_parse_element(ctx, ctm, base_uri, dict, (xml_element *)visual_tag);
+}
+
+void
+xps_parse_visual_brush(xps_context *ctx, fz_matrix ctm, fz_rect area,
+ char *base_uri, xps_resource *dict, xml_element *root)
+{
+ xml_element *node;
+
+ char *visual_uri;
+ char *visual_att;
+ xml_element *visual_tag = NULL;
+
+ visual_att = xml_att(root, "Visual");
+
+ for (node = xml_down(root); node; node = xml_next(node))
+ {
+ if (!strcmp(xml_tag(node), "VisualBrush.Visual"))
+ visual_tag = xml_down(node);
+ }
+
+ visual_uri = base_uri;
+ xps_resolve_resource_reference(ctx, dict, &visual_att, &visual_tag, &visual_uri);
+
+ if (visual_tag)
+ {
+ xps_parse_tiling_brush(ctx, ctm, area,
+ visual_uri, dict, root, xps_paint_visual_brush, visual_tag);
+ }
+}
diff --git a/xps/xpsutf.c b/xps/xpsutf.c
deleted file mode 100644
index d5c1974e..00000000
--- a/xps/xpsutf.c
+++ /dev/null
@@ -1,55 +0,0 @@
-#include "fitz.h"
-#include "muxps.h"
-
-/*
- * http://tools.ietf.org/html/rfc3629
- */
-
-int
-xps_utf8_to_ucs(int *p, const char *ss, int n)
-{
- unsigned char *s = (unsigned char *)ss;
-
- if (s == NULL)
- goto bad;
-
- if ((s[0] & 0x80) == 0)
- {
- *p = (s[0] & 0x7f);
- return 1;
- }
-
- if ((s[0] & 0xe0) == 0xc0)
- {
- if (n < 2 || s[1] < 0x80)
- goto bad;
- *p = (s[0] & 0x1f) << 6;
- *p |= (s[1] & 0x3f);
- return 2;
- }
-
- if ((s[0] & 0xf0) == 0xe0)
- {
- if (n < 3 || s[1] < 0x80 || s[2] < 0x80)
- goto bad;
- *p = (s[0] & 0x0f) << 12;
- *p |= (s[1] & 0x3f) << 6;
- *p |= (s[2] & 0x3f);
- return 3;
- }
-
- if ((s[0] & 0xf8) == 0xf0)
- {
- if (n < 4 || s[1] < 0x80 || s[2] < 0x80 || s[3] < 0x80)
- goto bad;
- *p = (s[0] & 0x07) << 18;
- *p |= (s[1] & 0x3f) << 12;
- *p |= (s[2] & 0x3f) << 6;
- *p |= (s[3] & 0x3f);
- return 4;
- }
-
-bad:
- *p = 0x80;
- return 1;
-}
diff --git a/xps/xpsvisual.c b/xps/xpsvisual.c
deleted file mode 100644
index ac7de23c..00000000
--- a/xps/xpsvisual.c
+++ /dev/null
@@ -1,39 +0,0 @@
-#include "fitz.h"
-#include "muxps.h"
-
-enum { TILE_NONE, TILE_TILE, TILE_FLIP_X, TILE_FLIP_Y, TILE_FLIP_X_Y };
-
-static void
-xps_paint_visual_brush(xps_context *ctx, fz_matrix ctm,
- char *base_uri, xps_resource *dict, xml_element *root, void *visual_tag)
-{
- xps_parse_element(ctx, ctm, base_uri, dict, (xml_element *)visual_tag);
-}
-
-void
-xps_parse_visual_brush(xps_context *ctx, fz_matrix ctm, fz_rect area,
- char *base_uri, xps_resource *dict, xml_element *root)
-{
- xml_element *node;
-
- char *visual_uri;
- char *visual_att;
- xml_element *visual_tag = NULL;
-
- visual_att = xml_att(root, "Visual");
-
- for (node = xml_down(root); node; node = xml_next(node))
- {
- if (!strcmp(xml_tag(node), "VisualBrush.Visual"))
- visual_tag = xml_down(node);
- }
-
- visual_uri = base_uri;
- xps_resolve_resource_reference(ctx, dict, &visual_att, &visual_tag, &visual_uri);
-
- if (visual_tag)
- {
- xps_parse_tiling_brush(ctx, ctm, area,
- visual_uri, dict, root, xps_paint_visual_brush, visual_tag);
- }
-}