diff options
-rw-r--r-- | Makefile | 7 | ||||
-rw-r--r-- | xps/muxps.h | 3 | ||||
-rw-r--r-- | xps/xpsanalyze.c | 309 | ||||
-rw-r--r-- | xps/xpscolor.c | 191 | ||||
-rw-r--r-- | xps/xpscommon.c | 187 | ||||
-rw-r--r-- | xps/xpsfont.c | 54 | ||||
-rw-r--r-- | xps/xpsglyphs.c | 70 | ||||
-rw-r--r-- | xps/xpsimage.c | 4 | ||||
-rw-r--r-- | xps/xpsjxr.c | 10 | ||||
-rw-r--r-- | xps/xpsmem.c | 7 | ||||
-rw-r--r-- | xps/xpsopacity.c | 63 | ||||
-rw-r--r-- | xps/xpstile.c | 35 | ||||
-rw-r--r-- | xps/xpsutf.c | 55 | ||||
-rw-r--r-- | xps/xpsvisual.c | 39 |
14 files changed, 289 insertions, 745 deletions
@@ -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); - } -} |