diff options
Diffstat (limited to 'Build/source/texk/dvipdfm-x/src')
-rw-r--r-- | Build/source/texk/dvipdfm-x/src/bmpimage.c | 460 | ||||
-rw-r--r-- | Build/source/texk/dvipdfm-x/src/cidtype0.c | 4 | ||||
-rw-r--r-- | Build/source/texk/dvipdfm-x/src/cidtype2.c | 1123 | ||||
-rw-r--r-- | Build/source/texk/dvipdfm-x/src/epdf.c | 763 | ||||
-rw-r--r-- | Build/source/texk/dvipdfm-x/src/epdf.h | 34 | ||||
-rw-r--r-- | Build/source/texk/dvipdfm-x/src/fontmap.c | 1528 | ||||
-rw-r--r-- | Build/source/texk/dvipdfm-x/src/pdfcolor.c | 62 | ||||
-rw-r--r-- | Build/source/texk/dvipdfm-x/src/pdfcolor.h | 112 | ||||
-rw-r--r-- | Build/source/texk/dvipdfm-x/src/pdfdev.c | 32 | ||||
-rw-r--r-- | Build/source/texk/dvipdfm-x/src/pdfdev.h | 2 | ||||
-rw-r--r-- | Build/source/texk/dvipdfm-x/src/pdfparse.c | 1044 | ||||
-rw-r--r-- | Build/source/texk/dvipdfm-x/src/pdfximage.c | 6 | ||||
-rw-r--r-- | Build/source/texk/dvipdfm-x/src/pdfximage.h | 94 | ||||
-rw-r--r-- | Build/source/texk/dvipdfm-x/src/sfnt.c | 529 | ||||
-rw-r--r-- | Build/source/texk/dvipdfm-x/src/tt_aux.c | 278 | ||||
-rw-r--r-- | Build/source/texk/dvipdfm-x/src/tt_aux.h | 35 | ||||
-rw-r--r-- | Build/source/texk/dvipdfm-x/src/tt_post.c | 275 | ||||
-rw-r--r-- | Build/source/texk/dvipdfm-x/src/tt_table.c | 507 |
18 files changed, 860 insertions, 6028 deletions
diff --git a/Build/source/texk/dvipdfm-x/src/bmpimage.c b/Build/source/texk/dvipdfm-x/src/bmpimage.c deleted file mode 100644 index 03fe341a34d..00000000000 --- a/Build/source/texk/dvipdfm-x/src/bmpimage.c +++ /dev/null @@ -1,460 +0,0 @@ -/* - - This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. - - Copyright (C) 2002-2012 by Jin-Hwan Cho and Shunsaku Hirata, - the dvipdfmx project team. - - Copyright (C) 1998, 1999 by Mark A. Wicks <mwicks@kettering.edu> - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. -*/ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -/* - * BMP SUPPORT: - */ - -#include "system.h" -#include "error.h" -#include "mem.h" - -#include "pdfobj.h" - -#include "bmpimage.h" - -#define DIB_FILE_HEADER_SIZE 14 -#define DIB_CORE_HEADER_SIZE 14 -#define DIB_INFO_HEADER_SIZE 40 - -#define DIB_COMPRESS_NONE 0 -#define DIB_COMPRESS_RLE8 1 -#define DIB_COMPRESS_RLE4 2 - -#define DIB_HEADER_SIZE_MAX (DIB_FILE_HEADER_SIZE+DIB_INFO_HEADER_SIZE) - -static long read_raster_rle8 (unsigned char *data_ptr, - long width, long height, FILE *fp); -static long read_raster_rle4 (unsigned char *data_ptr, - long width, long height, FILE *fp); - -int -check_for_bmp (FILE *fp) -{ - unsigned char sigbytes[2]; - - if (!fp) - return 0; - - rewind(fp); - if (fread(sigbytes, 1, sizeof(sigbytes), fp) != sizeof(sigbytes) || - sigbytes[0] != 'B' || sigbytes[1] != 'M') - return 0; - else - return 1; - - return 0; -} - -int -bmp_include_image (pdf_ximage *ximage, FILE *fp) -{ - pdf_obj *stream, *stream_dict, *colorspace; - ximage_info info; - unsigned char buf[DIB_HEADER_SIZE_MAX+4]; - unsigned char *p; - long offset, hsize, compression; - long psize; /* Bytes per palette color: 3 for OS2, 4 for Win */ - unsigned short bit_count; /* Bits per pix */ - int num_palette, flip; - int i; - - pdf_ximage_init_image_info(&info); - - stream = stream_dict = colorspace = NULL; - p = buf; - - rewind(fp); - if (fread(buf, 1, DIB_FILE_HEADER_SIZE + 4, fp) - != DIB_FILE_HEADER_SIZE + 4) { - WARN("Could not read BMP file header..."); - } - - if (p[0] != 'B' || p[1] != 'M') { - WARN("File not starting with \'B\' \'M\'... Not a BMP file?"); - return -1; - } - p += 2; - -#define ULONG_LE(b) ((b)[0] + ((b)[1] << 8) +\ - ((b)[2] << 16) + ((b)[3] << 24)) -#define USHORT_LE(b) ((b)[0] + ((b)[1] << 8)) - - /* fsize = ULONG_LE(p); */ p += 4; - if (ULONG_LE(p) != 0) { - WARN("Not a BMP file???"); - return -1; - } - p += 4; - offset = ULONG_LE(p); p += 4; - - /* info header */ - hsize = ULONG_LE(p); p += 4; - if (fread(p, sizeof(char), hsize - 4, fp) != hsize - 4) { - WARN("Could not read BMP file header..."); - return -1; - } - flip = 1; - if (hsize == DIB_CORE_HEADER_SIZE) { - info.width = USHORT_LE(p); p += 2; - info.height = USHORT_LE(p); p += 2; - if (USHORT_LE(p) != 1) { - WARN("Unknown bcPlanes value in BMP COREHEADER."); - return -1; - } - p += 2; - bit_count = USHORT_LE(p); p += 2; - compression = DIB_COMPRESS_NONE; - psize = 3; - } else if (hsize == DIB_INFO_HEADER_SIZE) { - info.width = ULONG_LE(p); p += 4; - info.height = ULONG_LE(p); p += 4; - if (USHORT_LE(p) != 1) { - WARN("Unknown biPlanes value in BMP INFOHEADER."); - return -1; - } - p += 2; - bit_count = USHORT_LE(p); p += 2; - compression = ULONG_LE(p); p += 4; - if (info.height < 0) { - info.height = -info.height; - flip = 0; - } - psize = 4; - } else { - WARN("Unknown BMP header type."); - return -1; - } - - if (bit_count < 24) { - if (bit_count != 1 && - bit_count != 4 && bit_count != 8) { - WARN("Unsupported palette size: %ld", bit_count); - return -1; - } - num_palette = (offset - hsize - DIB_FILE_HEADER_SIZE) / psize; - info.bits_per_component = bit_count; - info.num_components = 1; - } else if (bit_count == 24) { /* full color */ - num_palette = 1; /* dummy */ - info.bits_per_component = 8; - info.num_components = 3; - } else { - WARN("Unkown BMP bitCount: %ld", bit_count); - return -1; - } - - if (info.width == 0 || info.height == 0 || num_palette < 1) { - WARN("Invalid BMP file: width=%ld, height=%ld, #palette=%d", - info.width, info.height, num_palette); - return -1; - } - - stream = pdf_new_stream(STREAM_COMPRESS); - stream_dict = pdf_stream_dict(stream); - - if (bit_count < 24) { - pdf_obj *lookup; - unsigned char *palette, bgrq[4]; - - palette = NEW(num_palette*3+1, unsigned char); - for (i = 0; i < num_palette; i++) { - if (fread(bgrq, 1, psize, fp) != psize) { - WARN("Reading file failed..."); - RELEASE(palette); - return -1; - } - /* BGR data */ - palette[3*i ] = bgrq[2]; - palette[3*i+1] = bgrq[1]; - palette[3*i+2] = bgrq[0]; - } - lookup = pdf_new_string(palette, num_palette*3); - RELEASE(palette); - - colorspace = pdf_new_array(); - pdf_add_array(colorspace, pdf_new_name("Indexed")); - pdf_add_array(colorspace, pdf_new_name("DeviceRGB")); - pdf_add_array(colorspace, pdf_new_number(num_palette-1)); - pdf_add_array(colorspace, lookup); - } else { - colorspace = pdf_new_name("DeviceRGB"); - } - pdf_add_dict(stream_dict, pdf_new_name("ColorSpace"), colorspace); - - /* Raster data of BMP is four-byte aligned. */ - { - long rowbytes, n; - unsigned char *stream_data_ptr = NULL; - - rowbytes = (info.width * bit_count + 7) / 8; - - seek_absolute(fp, offset); - if (compression == DIB_COMPRESS_NONE) { - long dib_rowbytes; - int padding; - - padding = (rowbytes % 4) ? 4 - (rowbytes % 4) : 0; - dib_rowbytes = rowbytes + padding; - stream_data_ptr = NEW(rowbytes*info.height + padding, - unsigned char); - for (n = 0; n < info.height; n++) { - p = stream_data_ptr + n * rowbytes; - if (fread(p, 1, dib_rowbytes, fp) != dib_rowbytes) { - WARN("Reading BMP raster data failed..."); - pdf_release_obj(stream); - RELEASE(stream_data_ptr); - return -1; - } - } - } else if (compression == DIB_COMPRESS_RLE8) { - stream_data_ptr = NEW(rowbytes*info.height, unsigned char); - if (read_raster_rle8(stream_data_ptr, - info.width, info.height, fp) < 0) { - WARN("Reading BMP raster data failed..."); - pdf_release_obj(stream); - RELEASE(stream_data_ptr); - return -1; - } - } else if (compression == DIB_COMPRESS_RLE4) { - stream_data_ptr = NEW(rowbytes*info.height, unsigned char); - if (read_raster_rle4(stream_data_ptr, - info.width, info.height, fp) < 0) { - WARN("Reading BMP raster data failed..."); - pdf_release_obj(stream); - RELEASE(stream_data_ptr); - return -1; - } - } else { - pdf_release_obj(stream); - return -1; - } - - /* gbr --> rgb */ - if (bit_count == 24) { - for (n = 0; n < info.width * info.height * 3; n += 3) { - unsigned char g; - g = stream_data_ptr[n]; - stream_data_ptr[n ] = stream_data_ptr[n+2]; - stream_data_ptr[n+2] = g; - } - } - - if (flip) { - for (n = info.height - 1; n >= 0; n--) { - p = stream_data_ptr + n * rowbytes; - pdf_add_stream(stream, p, rowbytes); - } - } else { - pdf_add_stream(stream, stream_data_ptr, rowbytes*info.height); - } - RELEASE(stream_data_ptr); - } - - pdf_ximage_set_image(ximage, &info, stream); - - return 0; -} - -static long -read_raster_rle8 (unsigned char *data_ptr, - long width, long height, FILE *fp) -{ - long count = 0; - unsigned char *p, b0, b1; - long h, v, rowbytes; - int eol, eoi; - - p = data_ptr; - rowbytes = width; - memset(data_ptr, 0, rowbytes*height); - for (v = 0, eoi = 0; v < height && !eoi; v++) { - for (h = 0, eol = 0; h < width && !eol; ) { - - b0 = get_unsigned_byte(fp); - b1 = get_unsigned_byte(fp); - count += 2; - - p = data_ptr + v * rowbytes + h; - - if (b0 == 0x00) { - switch (b1) { - case 0x00: /* EOL */ - eol = 1; - break; - case 0x01: /* EOI */ - eoi = 1; - break; - case 0x02: - h += get_unsigned_byte(fp); - v += get_unsigned_byte(fp); - count += 2; - break; - default: - h += b1; - if (h > width) { - WARN("RLE decode failed..."); - return -1; - } - if (fread(p, 1, b1, fp) != b1) - return -1; - count += b1; - if (b1 % 2) { - get_unsigned_byte(fp); - count++; - } - break; - } - } else { - h += b0; - if (h > width) { - WARN("RLE decode failed..."); - return -1; - } - memset(p, b1, b0); - } - } - - /* Check for EOL and EOI marker */ - if (!eol && !eoi) { - b0 = get_unsigned_byte(fp); - b1 = get_unsigned_byte(fp); - if (b0 != 0x00) { - WARN("RLE decode failed..."); - return -1; - } else if (b1 == 0x01) { - eoi = 1; - } else if (b1 != 0x00) { - WARN("RLE decode failed..."); - return -1; - } - } - - /* next row ... */ - } - - return count; -} - -static long -read_raster_rle4 (unsigned char *data_ptr, - long width, long height, FILE *fp) -{ - long count = 0; - unsigned char *p, b0, b1, b; - long h, v, rowbytes; - int eol, eoi, i, nbytes; - - p = data_ptr; - rowbytes = (width + 1) / 2; - memset(data_ptr, 0, rowbytes*height); - for (v = 0, eoi = 0; v < height && !eoi; v++) { - for (h = 0, eol = 0; h < width && !eol; ) { - - b0 = get_unsigned_byte(fp); - b1 = get_unsigned_byte(fp); - count += 2; - - p = data_ptr + v * rowbytes + (h / 2); - if (b0 == 0x00) { - switch (b1) { - case 0x00: /* EOL */ - eol = 1; - break; - case 0x01: /* EOI */ - eoi = 1; - break; - case 0x02: - h += get_unsigned_byte(fp); - v += get_unsigned_byte(fp); - count += 2; - break; - default: - if (h + b1 > width) { - WARN("RLE decode failed..."); - return -1; - } - nbytes = (b1 + 1)/2; - if (h % 2) { /* starting at hi-nib */ - for (i = 0; i < nbytes; i++) { - b = get_unsigned_byte(fp); - *p++ |= (b >> 4) & 0x0f; - *p = (b << 4) & 0xf0; - } - } else { - if (fread(p, 1, nbytes, fp) != nbytes) { - return -1; - } - } - h += b1; - count += nbytes; - if (nbytes % 2) { - get_unsigned_byte(fp); - count++; - } - break; - } - } else { - if (h + b0 > width) { - WARN("RLE decode failed..."); - return -1; - } - if (h % 2) { - *p++ = (b1 >> 4) & 0x0f; - b1 = ((b1 << 4) & 0xf0)|((b1 >> 4) & 0x0f); - b0--; - h++; - } - nbytes = (b0 + 1)/2; - memset(p, b1, nbytes); - h += b0; - if (h % 2) - p[nbytes-1] &= 0xf0; - } - } - - /* Check for EOL and EOI marker */ - if (!eol && !eoi) { - b0 = get_unsigned_byte(fp); - b1 = get_unsigned_byte(fp); - if (b0 != 0x00) { - WARN("No EOL/EOI marker. RLE decode failed..."); - return -1; - } else if (b1 == 0x01) { - eoi = 1; - } else if (b1 != 0x00) { - WARN("No EOL/EOI marker. RLE decode failed..."); - return -1; - } - } - - /* next row ... */ - } - - return count; -} diff --git a/Build/source/texk/dvipdfm-x/src/cidtype0.c b/Build/source/texk/dvipdfm-x/src/cidtype0.c index 00b24f2aee1..363c8088a9d 100644 --- a/Build/source/texk/dvipdfm-x/src/cidtype0.c +++ b/Build/source/texk/dvipdfm-x/src/cidtype0.c @@ -833,7 +833,7 @@ CIDFont_type0_open (CIDFont *font, const char *name, /* getting font info. from TrueType tables */ if ((font->descriptor - = tt_get_fontdesc(sfont, &(opt->embed), opt->stemv, 0, NULL)) == NULL) + = tt_get_fontdesc(sfont, &(opt->embed), opt->stemv, 0, name)) == NULL) ERROR("Could not obtain necessary font info."); if (opt->embed) { @@ -1245,7 +1245,7 @@ CIDFont_type0_t1copen (CIDFont *font, const char *name, /* getting font info. from TrueType tables */ if ((font->descriptor - = tt_get_fontdesc(sfont, &(opt->embed), opt->stemv, 0, NULL)) == NULL) + = tt_get_fontdesc(sfont, &(opt->embed), opt->stemv, 0, name)) == NULL) ERROR("Could not obtain necessary font info."); if (opt->embed) { diff --git a/Build/source/texk/dvipdfm-x/src/cidtype2.c b/Build/source/texk/dvipdfm-x/src/cidtype2.c deleted file mode 100644 index 7fc87ecd8d0..00000000000 --- a/Build/source/texk/dvipdfm-x/src/cidtype2.c +++ /dev/null @@ -1,1123 +0,0 @@ -/* - - This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. - - Copyright (C) 2002-2012 by Jin-Hwan Cho and Shunsaku Hirata, - the dvipdfmx project team. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. -*/ - -/* - * TrueType glyf table is sorted by CID and no CIDToGIDMap is used here. - * GhostScript can't handle CIDToGIDMap correctly. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include "system.h" -#include "numbers.h" -#include "mem.h" -#include "error.h" -#include "dpxfile.h" - -#include "pdfobj.h" -/* pseudo unique tag */ -#include "pdffont.h" - -#ifndef PDF_NAME_LEN_MAX -# define PDF_NAME_LEN_MAX 255 -#endif - -/* TrueType */ -#include "sfnt.h" -#include "tt_aux.h" -#include "tt_glyf.h" -#include "tt_cmap.h" -#include "tt_table.h" - -#include "tt_gsub.h" - -/* CID font */ -#include "cmap.h" -#include "type0.h" -#include "cid.h" -#include "cid_p.h" -#include "cidtype2.h" - -static int verbose = 0; -static int opt_flags = 0; - -void -CIDFont_type2_set_verbose (void) -{ - verbose++; -} - -void -CIDFont_type2_set_flags (long flags) -{ - opt_flags = flags; -} - -/* - * PDF viewer applications use following tables (CIDFontType 2) - * - * head, hhea, loca, maxp, glyf, hmtx, fpgm, cvt_, prep - * - * - from PDF Ref. v.1.3, 2nd ed. - * - * The fpgm, cvt_, and prep tables appears only when TrueType instructions - * requires them. Those tables must be preserved if they exist. - * We use must_exist flag to indicate `preserve it if present' - * and to make sure not to cause an error when it does not exist. - * - * post and name table must exist in ordinary TrueType font file, - * but when a TrueType font is converted to CIDFontType 2 font, those tables - * are no longer required. - * - * The OS/2 table (required for TrueType font for Windows and OS/2) contains - * liscencing information, but PDF viewers seems not using them. - * - * The 'name' table added. See comments in ttf.c. - */ - -static struct -{ - const char *name; - int must_exist; -} required_table[] = { - {"OS/2", 0}, {"head", 1}, {"hhea", 1}, {"loca", 1}, {"maxp", 1}, - {"name", 1}, {"glyf", 1}, {"hmtx", 1}, {"fpgm", 0}, {"cvt ", 0}, - {"prep", 0}, {NULL, 0} -}; - -static void -validate_name (char *fontname, int len) -{ - int i, count; - char *p; - static const char *badstrlist[] = { - "-WIN-RKSJ-H", - "-WINP-RKSJ-H", - "-WING-RKSJ-H", - "-90pv-RKSJ-H", - NULL - }; - - for (count = 0, i = 0; i < len; i++) { - if (fontname[i] == 0) { - memmove(fontname + i, fontname + i + 1, len - i); - count++; - len--; - } - } - if (count > 0) { - WARN("Removed %d null character(s) from fontname --> %s", - count, fontname); - } - fontname[len] = '\0'; - - /* For some fonts that have bad PS name. ad hoc. remove me. */ - for (i = 0; badstrlist[i] != NULL; i++) { - p = strstr(fontname, badstrlist[i]); - if (p && p > fontname) { - WARN("Removed string \"%s\" from fontname \"%s\".", - badstrlist[i], fontname); - p[0] = '\0'; - len = (int) (p - fontname); - break; - } - } - - if (len < 1) { - ERROR("No valid character found in fontname string."); - } -} - -/* - * We will follow the convension for finding ToUnicode CMap described in PDF - * Reference 4th ed., page 432. The name of "ToCode" (not limited to Unicode - * here) CMap is obtained by concatenating the registry, ordering, and the - * name of encoding. - * - * UCSms-UCS4, UCSms-UCS2, UCS4 added... - */ - -#define WIN_UCS_INDEX_MAX 1 -#define KNOWN_ENCODINGS_MAX 9 -static struct -{ - unsigned short platform; - unsigned short encoding; - const char *pdfnames[5]; -} known_encodings[] = { - {TT_WIN, TT_WIN_UCS4, {"UCSms-UCS4", "UCSms-UCS2", "UCS4", "UCS2", NULL}}, - {TT_WIN, TT_WIN_UNICODE, {"UCSms-UCS4", "UCSms-UCS2", "UCS4", "UCS2", NULL}}, - {TT_WIN, TT_WIN_SJIS, {"90ms-RKSJ", NULL}}, - {TT_WIN, TT_WIN_RPC, {"GBK-EUC", NULL}}, - {TT_WIN, TT_WIN_BIG5, {"ETen-B5", NULL}}, - {TT_WIN, TT_WIN_WANSUNG, {"KSCms-UHC", NULL}}, - {TT_MAC, TT_MAC_JAPANESE, {"90pv-RKSJ", NULL}}, - {TT_MAC, TT_MAC_TRADITIONAL_CHINESE, {"B5pc", NULL}}, - {TT_MAC, TT_MAC_SIMPLIFIED_CHINESE, {"GBpc-EUC", NULL}}, - {TT_MAC, TT_MAC_KOREAN, {"KSCpc-EUC", NULL}}, - {0, 0, {NULL}} -}; - -static CMap * -find_tocode_cmap (const char *reg, const char *ord, int select) -{ - int cmap_id = -1, i; - char *cmap_name; - const char *append; - - if (!reg || !ord || - select < 0 || select > KNOWN_ENCODINGS_MAX) - ERROR("Character set unknown."); - - if (!strcmp(ord, "UCS") && - select <= WIN_UCS_INDEX_MAX) - return NULL; - - for (i = 0; cmap_id < 0 && i < 5; i++) { - append = known_encodings[select].pdfnames[i]; - if (!append) - break; - cmap_name = NEW(strlen(reg) + strlen(ord) + strlen(append) + 3, char); - sprintf(cmap_name, "%s-%s-%s", reg, ord, append); - cmap_id = CMap_cache_find(cmap_name); - RELEASE(cmap_name); - } - if (cmap_id < 0) { - WARN("Could not find CID-to-Code mapping for \"%s-%s\".", reg, ord); - WARN("I tried to load (one of) the following file(s):"); - for (i = 0; i < 5; i++) { - append = known_encodings[select].pdfnames[i]; - if (!append) - break; - MESG(" %s-%s-%s", reg, ord, append); - } - WARN("Please check if this file exists."); - ERROR("Cannot continue..."); - } - - return CMap_cache_get(cmap_id); -} - - -/* - * CIDFont glyph metrics: - * Mostly same as add_CID[HV]Metrics in cidtype0.c. - */ -#define PDFUNIT(v) ((double) (ROUND(1000.0*(v)/(g->emsize), 1))) - -static void -add_TTCIDHMetrics (pdf_obj *fontdict, struct tt_glyphs *g, - char *used_chars, unsigned char *cidtogidmap, unsigned short last_cid) -{ - long cid, start = 0, prev = 0; - pdf_obj *w_array, *an_array = NULL; - double dw; - int empty = 1; - - w_array = pdf_new_array(); - if (g->dw != 0 && g->dw <= g->emsize) { - dw = PDFUNIT(g->dw); - } else { - dw = PDFUNIT(g->gd[0].advw); - } - for (cid = 0; cid <= last_cid; cid++) { - USHORT idx, gid; - double width; - - if (!is_used_char2(used_chars, cid)) - continue; - gid = (cidtogidmap) ? ((cidtogidmap[2*cid] << 8)|cidtogidmap[2*cid+1]) : cid; - idx = tt_get_index(g, gid); - if (cid != 0 && idx == 0) - continue; - width = PDFUNIT((g->gd)[idx].advw); - if (width == dw) { - if (an_array) { - pdf_add_array(w_array, pdf_new_number(start)); - pdf_add_array(w_array, an_array); - an_array = NULL; - empty = 0; - } - } else { - if (cid != prev + 1) { - if (an_array) { - pdf_add_array(w_array, pdf_new_number(start)); - pdf_add_array(w_array, an_array); - an_array = NULL; - empty = 0; - } - } - if (an_array == NULL) { - an_array = pdf_new_array(); - start = cid; - } - pdf_add_array(an_array, pdf_new_number(width)); - prev = cid; - } - } - - if (an_array) { - pdf_add_array(w_array, pdf_new_number(start)); - pdf_add_array(w_array, an_array); - empty = 0; - } - - pdf_add_dict(fontdict, - pdf_new_name("DW"), - pdf_new_number(dw)); - if (!empty) { - pdf_add_dict(fontdict, - pdf_new_name("W"), - pdf_ref_obj(w_array)); - } - pdf_release_obj(w_array); - - return; -} - -static void -add_TTCIDVMetrics (pdf_obj *fontdict, struct tt_glyphs *g, - char *used_chars, unsigned char *cidtogidmap, unsigned short last_cid) -{ - pdf_obj *w2_array, *an_array = NULL; - long cid; -#if 0 - long prev = 0, start = 0; -#endif - double defaultVertOriginY, defaultAdvanceHeight; - int empty = 1; - - defaultVertOriginY = PDFUNIT(g->default_advh - g->default_tsb); - defaultAdvanceHeight = PDFUNIT(g->default_advh); - - w2_array = pdf_new_array(); - for (cid = 0; cid <= last_cid; cid++) { - USHORT idx; -#if 0 - USHORT gid; -#endif - double vertOriginX, vertOriginY, advanceHeight; - - if (!is_used_char2(used_chars, cid)) - continue; -#if 0 - gid = (cidtogidmap) ? ((cidtogidmap[2*cid] << 8)|cidtogidmap[2*cid+1]) : cid; -#endif - idx = tt_get_index(g, (USHORT)cid); - if (cid != 0 && idx == 0) - continue; - advanceHeight = PDFUNIT(g->gd[idx].advh); - vertOriginX = PDFUNIT(0.5*(g->gd[idx].advw)); - vertOriginY = PDFUNIT(g->gd[idx].tsb + g->gd[idx].ury); -#if 0 - /* - * c [w1_1y v_1x v_1y w1_2y v_2x v_2y ...] - * Not working... Why? - * Acrobat Reader: - * Wrong rendering, interpretation of position vector is wrong. - * Xpdf and gs: ignores W2? - */ - if (vertOriginY == defaultVertOriginY && - advanceHeight == defaultAdvanceHeight) { - if (an_array) { - pdf_add_array(w2_array, pdf_new_number(start)); - pdf_add_array(w2_array, an_array); - an_array = NULL; - empty = 0; - } - } else { - if (cid != prev + 1 && an_array) { - pdf_add_array(w2_array, pdf_new_number(start)); - pdf_add_array(w2_array, an_array); - an_array = NULL; - empty = 0; - } - if (an_array == NULL) { - an_array = pdf_new_array(); - start = cid; - } - pdf_add_array(an_array, pdf_new_number(-advanceHeight)); - pdf_add_array(an_array, pdf_new_number(vertOriginX)); - pdf_add_array(an_array, pdf_new_number(vertOriginY)); - prev = cid; - } -#else - /* - * c_first c_last w1_y v_x v_y - * This form may hit Acrobat's implementation limit of array element size, - * 8192. AFPL GhostScript 8.11 stops with rangecheck error with this. - * Maybe GS's bug? - */ - if (vertOriginY != defaultVertOriginY || - advanceHeight != defaultAdvanceHeight) { - pdf_add_array(w2_array, pdf_new_number(cid)); - pdf_add_array(w2_array, pdf_new_number(cid)); - pdf_add_array(w2_array, pdf_new_number(-advanceHeight)); - pdf_add_array(w2_array, pdf_new_number(vertOriginX)); - pdf_add_array(w2_array, pdf_new_number(vertOriginY)); - empty = 0; - } -#endif - } - -#if 0 - if (an_array) { - pdf_add_array(w2_array, pdf_new_number(start)); - pdf_add_array(w2_array, an_array); - empty = 0; - } -#endif - - if (defaultVertOriginY != 880 || defaultAdvanceHeight != 1000) { - an_array = pdf_new_array(); - pdf_add_array(an_array, pdf_new_number(defaultVertOriginY)); - pdf_add_array(an_array, pdf_new_number(-defaultAdvanceHeight)); - pdf_add_dict(fontdict, pdf_new_name ("DW2"), an_array); - } - if (!empty) { - pdf_add_dict(fontdict, - pdf_new_name("W2"), - pdf_ref_obj(w2_array)); - } - pdf_release_obj(w2_array); - - return; -} - -/* - * The following routine fixes few problems caused by vendor specific - * Unicode mappings. - */ - -#define FIX_CJK_UNIOCDE_SYMBOLS 1 - -static unsigned short -fix_CJK_symbols (unsigned short code) -{ - unsigned short alt_code; - static struct - { - unsigned short alt1; - unsigned short alt2; - } CJK_Uni_symbols[] = { - /* - * Microsoft/Apple Unicode mapping difference: - * They are taken from SJIS-Unicode mapping difference but nearly - * same thing might be applied to Chinese (e.g., Big5) too. - */ - {0x2014, 0x2015}, /* EM DASH <-> HORIZONTAL BAR */ - {0x2016, 0x2225}, /* DOUBLE VERTICAL LINE <-> PARALLEL TO */ - {0x203E, 0xFFE3}, /* OVERLINE <-> FULLWIDTH MACRON */ - {0x2026, 0x22EF}, /* HORIZONTAL ELLIPSIS <-> MIDLINE HORIZONTAL ELLIPSIS */ - {0x2212, 0xFF0D}, /* MINUS SIGN <-> FULLWIDTH HYPHEN-MINUS */ - {0x301C, 0xFF5E}, /* WAVE DASH <-> FULLWIDTH TILDE */ - {0xFFE0, 0x00A2}, /* FULLWIDTH CENT SIGN <-> CENT SIGN */ - {0xFFE1, 0x00A3}, /* FULLWIDTH POUND SIGN <-> POUND SIGN */ - {0xFFE2, 0x00AC}, /* FULLWIDTH NOT SIGN <-> NOT SIGN */ - {0xFFFF, 0xFFFF}, /* EOD */ - }; -#define NUM_CJK_SYMBOLS (sizeof(CJK_Uni_symbols)/sizeof(CJK_Uni_symbols[0])) - int i; - - alt_code = code; - for (i = 0; i < NUM_CJK_SYMBOLS; i++) { - if (CJK_Uni_symbols[i].alt1 == code) { - alt_code = CJK_Uni_symbols[i].alt2; - break; - } else if (CJK_Uni_symbols[i].alt2 == code) { - alt_code = CJK_Uni_symbols[i].alt1; - break; - } - } - - return alt_code; -} - -static long -cid_to_code (CMap *cmap, CID cid) -{ - unsigned char inbuf[2], outbuf[32]; - long inbytesleft = 2, outbytesleft = 32; - const unsigned char *p; - unsigned char *q; - - if (!cmap) - return cid; - - inbuf[0] = (cid >> 8) & 0xff; - inbuf[1] = cid & 0xff; - p = inbuf; q = outbuf; - - CMap_decode_char(cmap, &p, &inbytesleft, &q, &outbytesleft); - - if (inbytesleft != 0) - return 0; - else if (outbytesleft == 31) - return (long) outbuf[0]; - else if (outbytesleft == 30) - return (long) (outbuf[0] << 8|outbuf[1]); - else if (outbytesleft == 28) { /* We assume the output encoding is UTF-16. */ - CID hi, lo; - hi = outbuf[0] << 8|outbuf[1]; - lo = outbuf[2] << 8|outbuf[3]; - if (hi >= 0xd800 && hi <= 0xdbff && lo >= 0xdc00 && lo <= 0xdfff) - return (long) ((hi - 0xd800) * 0x400 + 0x10000 + lo - 0xdc00); - else - return (long) (hi << 16|lo); - } - - return 0; -} - -/* #define NO_GHOSTSCRIPT_BUG 1 */ - -void -CIDFont_type2_dofont (CIDFont *font) -{ - pdf_obj *fontfile; - sfnt *sfont; - char *h_used_chars, *v_used_chars, *used_chars; - struct tt_glyphs *glyphs; - CMap *cmap = NULL; - tt_cmap *ttcmap = NULL; - unsigned long offset = 0; - CID cid, last_cid; - unsigned char *cidtogidmap; - USHORT num_glyphs; - int i, glyph_ordering = 0, unicode_cmap = 0; - FILE *fp = NULL; - - if (!font->indirect) - return; - - pdf_add_dict(font->fontdict, - pdf_new_name("FontDescriptor"), pdf_ref_obj(font->descriptor)); - - if (CIDFont_is_BaseFont(font)) - return; - - /* - * CIDSystemInfo comes here since Supplement can be increased. - */ - { - pdf_obj *tmp; - - tmp = pdf_new_dict (); - pdf_add_dict(tmp, - pdf_new_name("Registry"), - pdf_new_string(font->csi->registry, strlen(font->csi->registry))); - pdf_add_dict(tmp, - pdf_new_name("Ordering"), - pdf_new_string(font->csi->ordering, strlen(font->csi->ordering))); - pdf_add_dict(tmp, - pdf_new_name("Supplement"), - pdf_new_number(font->csi->supplement)); - pdf_add_dict(font->fontdict, pdf_new_name("CIDSystemInfo"), tmp); - } - - /* Quick exit for non-embedded & fixed-pitch font. */ - if (!CIDFont_get_embedding(font) && - (opt_flags & CIDFONT_FORCE_FIXEDPITCH)) { - pdf_add_dict(font->fontdict, - pdf_new_name("DW"), pdf_new_number(1000.0)); - return; - } - -#ifdef XETEX - sfont = sfnt_open(font->ft_face, SFNT_TYPE_TTC | SFNT_TYPE_TRUETYPE); -#else - fp = DPXFOPEN(font->ident, DPX_RES_TYPE_TTFONT); - if (!fp) { - fp = DPXFOPEN(font->ident, DPX_RES_TYPE_DFONT); - if (!fp) ERROR("Could not open TTF/dfont file: %s", font->ident); - sfont = dfont_open(fp, font->options->index); - } else { - sfont = sfnt_open(fp); - } -#endif - - if (!sfont) { - ERROR("Could not open TTF file: %s", font->ident); - } - - switch (sfont->type) { - case SFNT_TYPE_TTC: - offset = ttc_read_offset(sfont, font->options->index); - if (offset == 0) - ERROR("Invalid TTC index in %s.", font->ident); - break; - case SFNT_TYPE_TRUETYPE: -#ifdef XETEX - /* disable the check here becuase sfnt_open() does not distinguish dfont - * from regular trutype */ -#else - if (font->options->index > 0) - ERROR("Found TrueType font file while expecting TTC file (%s).", font->ident); -#endif - offset = 0; - break; - case SFNT_TYPE_DFONT: - offset = sfont->offset; - break; - default: - ERROR("Not a TrueType/TTC font (%s)?", font->ident); - break; - } - - if (sfnt_read_table_directory(sfont, offset) < 0) - ERROR("Could not read TrueType table directory (%s).", font->ident); - - /* - * Adobe-Identity means font's internal glyph ordering here. - */ - if (!strcmp(font->csi->registry, "Adobe") && - !strcmp(font->csi->ordering, "Identity")) { - glyph_ordering = 1; - } else { - glyph_ordering = 0; - } - - /* - * Select TrueType cmap table, find ToCode CMap for each TrueType encodings. - */ - if (glyph_ordering) { - ttcmap = NULL; - cmap = NULL; - } else { - /* - * This part contains a bug. It may choose SJIS encoding TrueType cmap - * table for Adobe-GB1. - */ - for (i = 0; i <= KNOWN_ENCODINGS_MAX; i++) { - ttcmap = tt_cmap_read(sfont, - known_encodings[i].platform, - known_encodings[i].encoding); - if (ttcmap) - break; - } - if (!ttcmap) { - WARN("No usable TrueType cmap table found for font \"%s\".", font->ident); - WARN("CID character collection for this font is set to \"%s-%s\"", - font->csi->registry, font->csi->ordering); - ERROR("Cannot continue without this..."); - } else if (i <= WIN_UCS_INDEX_MAX) { - unicode_cmap = 1; - } else { - unicode_cmap = 0; - } - - /* - * NULL is returned if CMap is Identity CMap. - */ - cmap = find_tocode_cmap(font->csi->registry, - font->csi->ordering, i); - } - - glyphs = tt_build_init(); - - last_cid = 0; - num_glyphs = 1; /* .notdef */ - used_chars = h_used_chars = v_used_chars = NULL; - { - Type0Font *parent; - int parent_id, c; - - if ((parent_id = CIDFont_get_parent_id(font, 0)) >= 0) { - parent = Type0Font_cache_get(parent_id); - h_used_chars = Type0Font_get_usedchars(parent); - } - if ((parent_id = CIDFont_get_parent_id(font, 1)) >= 0) { - parent = Type0Font_cache_get(parent_id); - v_used_chars = Type0Font_get_usedchars(parent); - } - if (!h_used_chars && !v_used_chars) - ERROR("Unexpected error."); - - /* - * Quick check of max CID. - */ - c = 0; - for (i = 8191; i >= 0; i--) { - if (h_used_chars && h_used_chars[i] != 0) { - last_cid = i * 8 + 7; - c = h_used_chars[i]; - break; - } - if (v_used_chars && v_used_chars[i] != 0) { - last_cid = i * 8 + 7; - c = v_used_chars[i]; - break; - } - } - if (last_cid > 0) { - for (i = 0; i < 8; i++) { - if ((c >> i) & 1) - break; - last_cid--; - } - } - if (last_cid >= 0xFFFFu) { - ERROR("CID count > 65535"); - } - } - -#ifndef NO_GHOSTSCRIPT_BUG - cidtogidmap = NULL; -#else - cidtogidmap = NEW((last_cid + 1) * 2, unsigned char); - memset(cidtogidmap, 0, (last_cid + 1) * 2); -#endif /* !NO_GHOSTSCRIPT_BUG */ - - /* - * Map CIDs to GIDs. - * Horizontal and vertical used_chars are merged. - */ - - /* - * Horizontal - */ - if (h_used_chars) { - used_chars = h_used_chars; - for (cid = 1; cid <= last_cid; cid++) { - long code; - unsigned short gid; - - if (!is_used_char2(h_used_chars, cid)) - continue; - - if (glyph_ordering) { - gid = cid; - code = cid; - } else { - code = cid_to_code(cmap, cid); - gid = tt_cmap_lookup(ttcmap, code); -#ifdef FIX_CJK_UNIOCDE_SYMBOLS - if (gid == 0 && unicode_cmap) { - long alt_code; - - alt_code = fix_CJK_symbols((unsigned short)code); - if (alt_code != code) { - gid = tt_cmap_lookup(ttcmap, alt_code); - if (gid != 0) { - WARN("Unicode char U+%04x replaced with U+%04x.", - code, alt_code); - } - } - } -#endif /* FIX_CJK_UNIOCDE_SYMBOLS */ - } - - if (gid == 0) { - WARN("Glyph missing in font. (CID=%u, code=0x%04x)", cid, code); - } - - /* TODO: duplicated glyph */ -#ifndef NO_GHOSTSCRIPT_BUG - gid = tt_add_glyph(glyphs, gid, cid); -#else - gid = tt_add_glyph(glyphs, gid, num_glyphs); - cidtogidmap[2*cid ] = gid >> 8; - cidtogidmap[2*cid+1] = gid & 0xff; -#endif /* !NO_GHOSTSCRIPT_BUG */ - - num_glyphs++; - } - } - - /* - * Vertical - */ - if (v_used_chars) { - otl_gsub *gsub_list = NULL; - - /* - * Require `vrt2' or `vert'. - */ - if (glyph_ordering) { - gsub_list = NULL; - } else { - gsub_list = otl_gsub_new(); - if (otl_gsub_add_feat(gsub_list, - "*", "*", "vrt2", sfont) < 0) { - if (otl_gsub_add_feat(gsub_list, - "*", "*", "vert", sfont) < 0) { - WARN("GSUB feature vrt2/vert not found."); - otl_gsub_release(gsub_list); - gsub_list = NULL; - } else { - otl_gsub_select(gsub_list, "*", "*", "vert"); - } - } else { - otl_gsub_select(gsub_list, "*", "*", "vrt2"); - } - } - - for (cid = 1; cid <= last_cid; cid++) { - long code; - unsigned short gid; - - if (!is_used_char2(v_used_chars, cid)) - continue; - - /* There may be conflict of horizontal and vertical glyphs - * when font is used with /UCS. However, we simply ignore - * that... - */ - if (h_used_chars && is_used_char2(h_used_chars, cid)) { - continue; - } - - if (glyph_ordering) { - gid = cid; - code = cid; - } else { - code = cid_to_code(cmap, cid); - gid = tt_cmap_lookup(ttcmap, code); -#ifdef FIX_CJK_UNIOCDE_SYMBOLS - if (gid == 0 && unicode_cmap) { - long alt_code; - - alt_code = fix_CJK_symbols((unsigned short)code); - if (alt_code != code) { - gid = tt_cmap_lookup(ttcmap, alt_code); - if (gid != 0) { - WARN("Unicode char U+%04x replaced with U+%04x.", - code, alt_code); - } - } - } -#endif /* FIX_CJK_UNIOCDE_SYMBOLS */ - } - if (gid == 0) { - WARN("Glyph missing in font. (CID=%u, code=0x%04x)", cid, code); - } else if (gsub_list) { - otl_gsub_apply(gsub_list, &gid); - } - -#ifndef NO_GHOSTSCRIPT_BUG - gid = tt_add_glyph(glyphs, gid, cid); -#else - gid = tt_add_glyph(glyphs, gid, num_glyphs); - cidtogidmap[2*cid ] = gid >> 8; - cidtogidmap[2*cid+1] = gid & 0xff; -#endif /* !NO_GHOSTSCRIPT_BUG */ - - if (used_chars) /* merge vertical used_chars to horizontal */ - add_to_used_chars2(used_chars, cid); - - num_glyphs++; - } - - if (gsub_list) - otl_gsub_release(gsub_list); - - if (!used_chars) /* We have no horizontal. */ - used_chars = v_used_chars; - } - - if (!used_chars) - ERROR("Unexpected error."); - - tt_cmap_release(ttcmap); - - if (CIDFont_get_embedding(font)) { - if (tt_build_tables(sfont, glyphs) < 0) - ERROR("Could not created FontFile stream."); - if (verbose > 1) - MESG("[%u glyphs (Max CID: %u)]", glyphs->num_glyphs, last_cid); - } else { - if (tt_get_metrics(sfont, glyphs) < 0) - ERROR("Reading glyph metrics failed..."); - } - - /* - * DW, W, DW2, and W2 - */ - if (opt_flags & CIDFONT_FORCE_FIXEDPITCH) { - pdf_add_dict(font->fontdict, - pdf_new_name("DW"), pdf_new_number(1000.0)); - } else { - add_TTCIDHMetrics(font->fontdict, glyphs, used_chars, cidtogidmap, last_cid); - if (v_used_chars) - add_TTCIDVMetrics(font->fontdict, glyphs, used_chars, cidtogidmap, last_cid); - } - - tt_build_finish(glyphs); - - /* Finish here if not embedded. */ - if (!CIDFont_get_embedding(font)) { - if (cidtogidmap) - RELEASE(cidtogidmap); - sfnt_close(sfont); - if (fp) - DPXFCLOSE(fp); - - return; - } - - /* Create font file */ - for (i = 0; required_table[i].name; i++) { - if (sfnt_require_table(sfont, - required_table[i].name, - required_table[i].must_exist) < 0) { - ERROR("Some required TrueType table (%s) does not exist.", required_table[i].name); - } - } - - /* - * FontFile2 - */ - fontfile = sfnt_create_FontFile_stream(sfont); - - sfnt_close(sfont); - if (fp) - DPXFCLOSE(fp); - - if (!fontfile) - ERROR("Could not created FontFile stream for \"%s\".", font->ident); - - if (verbose > 1) { - MESG("[%ld bytes]", pdf_stream_length(fontfile)); - } - - pdf_add_dict(font->descriptor, - pdf_new_name("FontFile2"), - pdf_ref_obj (fontfile)); - pdf_release_obj(fontfile); - - /* - * CIDSet - */ - { - pdf_obj *cidset; - - cidset = pdf_new_stream(STREAM_COMPRESS); - pdf_add_stream(cidset, used_chars, last_cid/8 + 1); - pdf_add_dict(font->descriptor, - pdf_new_name("CIDSet"), - pdf_ref_obj(cidset)); - pdf_release_obj(cidset); - } - - /* - * CIDToGIDMap - */ - if (cidtogidmap) { - pdf_obj *c2gmstream; - - c2gmstream = pdf_new_stream(STREAM_COMPRESS); - pdf_add_stream(c2gmstream, cidtogidmap, (last_cid + 1) * 2); - pdf_add_dict(font->fontdict, - pdf_new_name("CIDToGIDMap"), - pdf_ref_obj (c2gmstream)); - pdf_release_obj(c2gmstream); - RELEASE(cidtogidmap); - } - - return; -} - -int -CIDFont_type2_open (CIDFont *font, const char *name, - CIDSysInfo *cmap_csi, cid_opt *opt) -{ - char *fontname; - sfnt *sfont; - unsigned long offset = 0; - FILE *fp = NULL; - - ASSERT(font && opt); - -#ifdef XETEX - sfont = sfnt_open(font->ft_face, SFNT_TYPE_TTC | SFNT_TYPE_TRUETYPE); - if (!sfont) - return -1; -#else - fp = DPXFOPEN(name, DPX_RES_TYPE_TTFONT); - if (!fp) { - fp = DPXFOPEN(name, DPX_RES_TYPE_DFONT); - if (!fp) return -1; - sfont = dfont_open(fp, opt->index); - } else { - sfont = sfnt_open(fp); - } - - if (!sfont) { - DPXFCLOSE(fp); - return -1; - } -#endif - - switch (sfont->type) { - case SFNT_TYPE_TTC: - offset = ttc_read_offset(sfont, opt->index); - break; - case SFNT_TYPE_TRUETYPE: -#ifdef XETEX - /* disable the check here becuase sfnt_open() does not distinguish dfont - * from regular trutype */ -#else - if (opt->index > 0) - ERROR("Invalid TTC index (not TTC font): %s", name); -#endif - offset = 0; - break; - case SFNT_TYPE_DFONT: - offset = sfont->offset; - break; - default: - sfnt_close(sfont); - if (fp) - DPXFCLOSE(fp); - return -1; - break; - } - - if (sfnt_read_table_directory(sfont, offset) < 0) { - ERROR("Reading TrueType table directory failed."); - } - - { - char *shortname; - long namelen; - - /* MAC-ROMAN-EN-POSTSCRIPT or WIN-UNICODE-EN(US)-POSTSCRIPT */ - shortname = NEW(PDF_NAME_LEN_MAX, char); - namelen = tt_get_ps_fontname(sfont, shortname, PDF_NAME_LEN_MAX); - if (namelen == 0) { - memset(shortname, 0, PDF_NAME_LEN_MAX); - strncpy(shortname, name, PDF_NAME_LEN_MAX); - namelen = strlen(shortname); - } - validate_name(shortname, namelen); /* for SJIS, UTF-16, ... string */ - /* - * Strlen works, after validate_named string. - * Mangled name requires more 7 bytes. - * Style requires more 11 bytes. - */ - fontname = NEW(strlen(shortname)+19, char); - strcpy(fontname, shortname); - RELEASE(shortname); - } - - if (opt->embed && opt->style != FONT_STYLE_NONE) { - WARN("Embedding disabled due to style option for %s.", name); - opt->embed = 0; - } - switch (opt->style) { - case FONT_STYLE_BOLD: - strcat(fontname, ",Bold"); - break; - case FONT_STYLE_ITALIC: - strcat(fontname, ",Italic"); - break; - case FONT_STYLE_BOLDITALIC: - strcat(fontname, ",BoldItalic"); - break; - } - /* - * CIDSystemInfo is determined from CMap or from map record option. - */ - font->fontname = fontname; - font->subtype = CIDFONT_TYPE2; - font->csi = NEW(1, CIDSysInfo); - if (opt->csi) { - if (cmap_csi) { - if (strcmp(opt->csi->registry, cmap_csi->registry) || - strcmp(opt->csi->ordering, cmap_csi->ordering)) { - WARN("CID character collection mismatched:\n"); - MESG("\tFont: %s-%s-%d\n", - opt->csi->registry, opt->csi->ordering, opt->csi->supplement); - MESG("\tCMap: %s-%s-%d\n", - cmap_csi->registry, cmap_csi->ordering, cmap_csi->supplement); - ERROR("Incompatible CMap specified for this font."); - } - if (opt->csi->supplement < cmap_csi->supplement) { - WARN("Supplmement value in CIDSystemInfo increased."); - WARN("Some characters may not shown."); - opt->csi->supplement = cmap_csi->supplement; - } - } - font->csi->registry = NEW(strlen(opt->csi->registry)+1, char); - strcpy(font->csi->registry, opt->csi->registry); - font->csi->ordering = NEW(strlen(opt->csi->ordering)+1, char); - strcpy(font->csi->ordering, opt->csi->ordering); - font->csi->supplement = opt->csi->supplement; - } else if (cmap_csi) { - font->csi->registry = NEW(strlen(cmap_csi->registry)+1, char); - strcpy(font->csi->registry, cmap_csi->registry); - font->csi->ordering = NEW(strlen(cmap_csi->ordering)+1, char); - strcpy(font->csi->ordering, cmap_csi->ordering); - font->csi->supplement = cmap_csi->supplement; - } else { /* This means font's internal glyph ordering. */ - font->csi->registry = NEW(strlen("Adobe")+1, char); - strcpy(font->csi->registry, "Adobe"); - font->csi->ordering = NEW(strlen("Identity")+1, char); - strcpy(font->csi->ordering, "Identity"); - font->csi->supplement = 0; - } - - font->fontdict = pdf_new_dict(); - pdf_add_dict(font->fontdict, - pdf_new_name("Type"), - pdf_new_name("Font")); - pdf_add_dict(font->fontdict, - pdf_new_name("Subtype"), - pdf_new_name("CIDFontType2")); - - font->descriptor = tt_get_fontdesc(sfont, &(opt->embed), opt->stemv, 0, NULL); - if (!font->descriptor) { - ERROR("Could not obtain necessary font info."); - } - - if (opt->embed) { - memmove(fontname + 7, fontname, strlen(fontname) + 1); - pdf_font_make_uniqueTag(fontname); - fontname[6] = '+'; - } - - pdf_add_dict(font->descriptor, - pdf_new_name("FontName"), - pdf_new_name(fontname)); - pdf_add_dict(font->fontdict, - pdf_new_name("BaseFont"), - pdf_new_name(fontname)); - - sfnt_close(sfont); - if (fp) - DPXFCLOSE(fp); - - /* - * Don't write fontdict here. - * /Supplement in /CIDSystemInfo may change. - */ - - return 0; -} - -void -CIDFont_type2_release (CIDFont *font) -{ - return; -} diff --git a/Build/source/texk/dvipdfm-x/src/epdf.c b/Build/source/texk/dvipdfm-x/src/epdf.c index 05960f8fb9c..edb4ee6f5e4 100644 --- a/Build/source/texk/dvipdfm-x/src/epdf.c +++ b/Build/source/texk/dvipdfm-x/src/epdf.c @@ -40,16 +40,366 @@ #include "mfileio.h" #include "error.h" +#ifndef XETEX #include "dvipdfmx.h" +#endif #include "pdfobj.h" #include "pdfdev.h" #include "pdfdoc.h" +#ifdef XETEX +#include "pdfdraw.h" +#include "pdfparse.h" +#endif + #include "pdfximage.h" #include "epdf.h" +#ifdef XETEX +#if HAVE_ZLIB +#include <zlib.h> +static int add_stream_flate (pdf_obj *dst, const void *data, long len); +#endif +static int rect_equal (pdf_obj *rect1, pdf_obj *rect2); + +static int concat_stream (pdf_obj *dst, pdf_obj *src); + +/* + * From PDFReference15_v6.pdf (p.119 and p.834) + * + * MediaBox rectangle (Required; inheritable) + * + * The media box defines the boundaries of the physical medium on which the + * page is to be printed. It may include any extended area surrounding the + * finished page for bleed, printing marks, or other such purposes. It may + * also include areas close to the edges of the medium that cannot be marked + * because of physical limitations of the output device. Content falling + * outside this boundary can safely be discarded without affecting the + * meaning of the PDF file. + * + * CropBox rectangle (Optional; inheritable) + * + * The crop box defines the region to which the contents of the page are to be + * clipped (cropped) when displayed or printed. Unlike the other boxes, the + * crop box has no defined meaning in terms of physical page geometry or + * intended use; it merely imposes clipping on the page contents. However, + * in the absence of additional information (such as imposition instructions + * specified in a JDF or PJTF job ticket), the crop box will determine how + * the page’s contents are to be positioned on the output medium. The default + * value is the page’s media box. + * + * BleedBox rectangle (Optional; PDF 1.3) + * + * The bleed box (PDF 1.3) defines the region to which the contents of the + * page should be clipped when output in a production environment. This may + * include any extra “bleed area†needed to accommodate the physical + * limitations of cutting, folding, and trimming equipment. The actual printed + * page may include printing marks that fall outside the bleed box. + * The default value is the page’s crop box. + * + * TrimBox rectangle (Optional; PDF 1.3) + * + * The trim box (PDF 1.3) defines the intended dimensions of the finished page + * after trimming. It may be smaller than the media box, to allow for + * production-related content such as printing instructions, cut marks, or + * color bars. The default value is the page’s crop box. + * + * ArtBox rectangle (Optional; PDF 1.3) + * + * The art box (PDF 1.3) defines the extent of the page’s meaningful content + * (including potential white space) as intended by the page’s creator. + * The default value is the page’s crop box. + * + * Rotate integer (Optional; inheritable) + * + * The number of degrees by which the page should be rotated clockwise when + * displayed or printed. The value must be a multiple of 90. Default value: 0. + */ + +static int +rect_equal (pdf_obj *rect1, pdf_obj *rect2) +{ + int i; + + if (!rect1 || !rect2) + return 0; + for (i = 0; i < 4; i++) { + if (pdf_number_value(pdf_get_array(rect1, i)) != + pdf_number_value(pdf_get_array(rect2, i))) + return 0; + } + + return 1; +} + +static pdf_obj* +pdf_get_page_obj (pdf_file *pf, long page_no, + pdf_obj **ret_bbox, pdf_obj **ret_resources) +{ + pdf_obj *page_tree; + pdf_obj *bbox = NULL, *resources = NULL, *rotate = NULL; + long page_idx; + + /* + * Get Page Tree. + */ + page_tree = NULL; + { + pdf_obj *trailer, *catalog; + pdf_obj *markinfo, *tmp; + + trailer = pdf_file_get_trailer(pf); + + if (pdf_lookup_dict(trailer, "Encrypt")) { + WARN("This PDF document is encrypted."); + pdf_release_obj(trailer); + return NULL; + } + + catalog = pdf_deref_obj(pdf_lookup_dict(trailer, "Root")); + if (!PDF_OBJ_DICTTYPE(catalog)) { + WARN("Can't read document catalog."); + pdf_release_obj(trailer); + if (catalog) + pdf_release_obj(catalog); + return NULL; + } + pdf_release_obj(trailer); + + markinfo = pdf_deref_obj(pdf_lookup_dict(catalog, "MarkInfo")); + if (markinfo) { + tmp = pdf_lookup_dict(markinfo, "Marked"); + if (PDF_OBJ_BOOLEANTYPE(tmp) && pdf_boolean_value(tmp)) + WARN("File contains tagged PDF. Ignoring tags."); + pdf_release_obj(markinfo); + } + + page_tree = pdf_deref_obj(pdf_lookup_dict(catalog, "Pages")); + pdf_release_obj(catalog); + } + if (!page_tree) { + WARN("Page tree not found."); + return NULL; + } + + /* + * Negative page numbers are counted from the back. + */ + { + long count = pdf_number_value(pdf_lookup_dict(page_tree, "Count")); + page_idx = page_no + (page_no >= 0 ? -1 : count); + if (page_idx < 0 || page_idx >= count) { + WARN("Page %ld does not exist.", page_no); + pdf_release_obj(page_tree); + return NULL; + } + page_no = page_idx+1; + } + + /* + * Seek correct page. Get Media/Crop Box. + * Media box and resources can be inherited. + */ + { + pdf_obj *kids_ref, *kids; + pdf_obj *crop_box = NULL; + pdf_obj *tmp; + + tmp = pdf_lookup_dict(page_tree, "Resources"); + resources = tmp ? pdf_deref_obj(tmp) : pdf_new_dict(); + + while (1) { + long kids_length, i; + + if ((tmp = pdf_deref_obj(pdf_lookup_dict(page_tree, "MediaBox")))) { + if (bbox) + pdf_release_obj(bbox); + bbox = tmp; + } + if ((tmp = pdf_deref_obj(pdf_lookup_dict(page_tree, "BleedBox")))) { + if (!rect_equal(tmp, bbox)) { + if (bbox) + pdf_release_obj(bbox); + bbox = tmp; + } else + pdf_release_obj(tmp); + } + if ((tmp = pdf_deref_obj(pdf_lookup_dict(page_tree, "TrimBox")))) { + if (!rect_equal(tmp, bbox)) { + if (bbox) + pdf_release_obj(bbox); + bbox = tmp; + } else + pdf_release_obj(tmp); + } + if ((tmp = pdf_deref_obj(pdf_lookup_dict(page_tree, "ArtBox")))) { + if (!rect_equal(tmp, bbox)) { + if (bbox) + pdf_release_obj(bbox); + bbox = tmp; + } else + pdf_release_obj(tmp); + } + if ((tmp = pdf_deref_obj(pdf_lookup_dict(page_tree, "CropBox")))) { + if (crop_box) + pdf_release_obj(crop_box); + crop_box = tmp; + } + if ((tmp = pdf_deref_obj(pdf_lookup_dict(page_tree, "Rotate")))) { + if (rotate) + pdf_release_obj(rotate); + rotate = tmp; + } + if ((tmp = pdf_deref_obj(pdf_lookup_dict(page_tree, "Resources")))) { +#if 0 + pdf_merge_dict(tmp, resources); +#endif + if (resources) + pdf_release_obj(resources); + resources = tmp; + } + + kids_ref = pdf_lookup_dict(page_tree, "Kids"); + if (!kids_ref) + break; + kids = pdf_deref_obj(kids_ref); + kids_length = pdf_array_length(kids); + + for (i = 0; i < kids_length; i++) { + long count; + + pdf_release_obj(page_tree); + page_tree = pdf_deref_obj(pdf_get_array(kids, i)); + + tmp = pdf_deref_obj(pdf_lookup_dict(page_tree, "Count")); + if (tmp) { + /* Pages object */ + count = pdf_number_value(tmp); + pdf_release_obj(tmp); + } else + /* Page object */ + count = 1; + + if (page_idx < count) + break; + + page_idx -= count; + } + + pdf_release_obj(kids); + + if (i == kids_length) { + WARN("Page %ld not found! Broken PDF file?", page_no); + if (bbox) + pdf_release_obj(bbox); + if (crop_box) + pdf_release_obj(crop_box); + if (rotate) + pdf_release_obj(rotate); + pdf_release_obj(resources); + pdf_release_obj(page_tree); + return NULL; + } + } + if (crop_box) { + pdf_release_obj(bbox); + bbox = crop_box; + } + } + + if (!bbox) { + WARN("No BoundingBox information available."); + pdf_release_obj(page_tree); + pdf_release_obj(resources); + if (rotate) + pdf_release_obj(rotate); + return NULL; + } + + if (rotate) { + if (pdf_number_value(rotate) != 0.0) + WARN("<< /Rotate %d >> found. (Not supported yet)", (int)pdf_number_value(rotate)); + pdf_release_obj(rotate); + rotate = NULL; + } + + if (ret_bbox != NULL) + *ret_bbox = bbox; + if (ret_resources != NULL) + *ret_resources = resources; + + return page_tree; +} + +static pdf_obj* +pdf_get_page_content (pdf_obj* page) +{ + pdf_obj *contents, *content_new; + + contents = pdf_deref_obj(pdf_lookup_dict(page, "Contents")); + if (!contents) + return NULL; + + if (pdf_obj_typeof(contents) == PDF_NULL) { + /* empty page */ + pdf_release_obj(contents); + /* TODO: better don't include anything if the page is empty */ + contents = pdf_new_stream(0); + } else if (PDF_OBJ_ARRAYTYPE(contents)) { + /* + * Concatenate all content streams. + */ + pdf_obj *content_seg; + int idx = 0; + content_new = pdf_new_stream(STREAM_COMPRESS); + for (;;) { + content_seg = pdf_deref_obj(pdf_get_array(contents, idx)); + if (!content_seg) + break; + else if (PDF_OBJ_NULLTYPE(content_seg)) { + /* Silently ignore. */ + } else if (!PDF_OBJ_STREAMTYPE(content_seg)) { + WARN("Page content not a stream object. Broken PDF file?"); + pdf_release_obj(content_seg); + pdf_release_obj(content_new); + pdf_release_obj(contents); + return NULL; + } else if (concat_stream(content_new, content_seg) < 0) { + WARN("Could not handle content stream with multiple segments."); + pdf_release_obj(content_seg); + pdf_release_obj(content_new); + pdf_release_obj(contents); + return NULL; + } + pdf_release_obj(content_seg); + idx++; + } + pdf_release_obj(contents); + contents = content_new; + } else { + if (!PDF_OBJ_STREAMTYPE(contents)) { + WARN("Page content not a stream object. Broken PDF file?"); + pdf_release_obj(contents); + return NULL; + } + /* Flate the contents if necessary. */ + content_new = pdf_new_stream(STREAM_COMPRESS); + if (concat_stream(content_new, contents) < 0) { + WARN("Could not handle a content stream."); + pdf_release_obj(contents); + pdf_release_obj(content_new); + return NULL; + } + pdf_release_obj(contents); + contents = content_new; + } + + return contents; +} +#endif + int pdf_include_page (pdf_ximage *ximage, FILE *image_file, const char *filename) { @@ -206,3 +556,416 @@ pdf_include_page (pdf_ximage *ximage, FILE *image_file, const char *filename) return -1; } } + +#ifdef XETEX +typedef enum { + OP_SETCOLOR = 1, + OP_CLOSEandCLIP = 2, + OP_CLIP = 3, + OP_CONCATMATRIX = 4, + OP_SETCOLORSPACE = 5, + OP_RECTANGLE = 6, + OP_CURVETO = 7, + OP_CLOSEPATH = 8, + OP_LINETO = 9, + OP_MOVETO = 10, + OP_NOOP = 11, + OP_GSAVE = 12, + OP_GRESTORE = 13, + OP_CURVETO1 = 14, + OP_CURVETO2 = 15, + OP_UNKNOWN = 16 +} pdf_opcode; + +static struct operator +{ + const char *token; + int opcode; +} pdf_operators[] = { + {"SCN", OP_SETCOLOR}, + {"b*", OP_CLOSEandCLIP}, + {"B*", OP_CLIP}, + {"cm", OP_CONCATMATRIX}, + {"CS", OP_SETCOLORSPACE}, + {"f*", 0}, + {"gs", -1}, + {"re", OP_RECTANGLE}, + {"rg", -3}, + {"RG", -3}, + {"sc", OP_SETCOLOR}, + {"SC", OP_SETCOLOR}, + {"W*", OP_CLIP}, + {"b", OP_CLOSEandCLIP}, + {"B", OP_CLIP}, + {"c", OP_CURVETO}, + {"d", -2}, + {"f", 0}, + {"F", 0}, + {"g", -1}, + {"G", -1}, + {"h", OP_CLOSEPATH}, + {"i", -1}, + {"j", -1}, + {"J", -1}, + {"k", -4}, + {"K", -4}, + {"l", OP_LINETO}, + {"m", OP_MOVETO}, + {"M", -1}, + {"n", OP_NOOP}, + {"q", OP_GSAVE}, + {"Q", OP_GRESTORE}, + {"s", OP_CLOSEandCLIP}, + {"S", OP_CLIP}, + {"v", OP_CURVETO1}, + {"w", -1}, + {"W", OP_CLIP}, + {"y", OP_CURVETO2} +}; + + +int +pdf_copy_clip (FILE *image_file, int pageNo, double x_user, double y_user) +{ + pdf_obj *page_tree, *contents; + int depth = 0, top = -1; + const char *clip_path, *end_path; + char *save_path, *temp; + pdf_tmatrix M; + double stack[6]; + pdf_file *pf; + + pf = pdf_open(NULL, image_file); + if (!pf) + return -1; + + pdf_dev_currentmatrix(&M); + pdf_invertmatrix(&M); + M.e += x_user; M.f += y_user; + page_tree = pdf_get_page_obj (pf, pageNo, NULL, NULL); + if (!page_tree) { + pdf_close(pf); + return -1; + } + + contents = pdf_get_page_content(page_tree); + pdf_release_obj(page_tree); + if (!contents) { + pdf_close(pf); + return -1; + } + + pdf_doc_add_page_content(" ", 1); + + save_path = malloc(pdf_stream_length(contents) + 1); + strncpy(save_path, (const char *) pdf_stream_dataptr(contents), pdf_stream_length(contents)); + clip_path = save_path; + end_path = clip_path + pdf_stream_length(contents); + depth = 0; + + for (; clip_path < end_path; clip_path++) { + int color_dimen = 0; /* silence uninitialized warning */ + char *token; + skip_white(&clip_path, end_path); + if (clip_path == end_path) + break; + if (depth > 1) { + if (*clip_path == 'q') + depth++; + if (*clip_path == 'Q') + depth--; + parse_ident(&clip_path, end_path); + continue; + } else if (*clip_path == '-' + || *clip_path == '+' + || *clip_path == '.' + || isdigit(*clip_path)) { + stack[++top] = strtod(clip_path, &temp); + clip_path = temp; + } else if (*clip_path == '[') { + /* Ignore, but put a dummy value on the stack (in case of d operator) */ + parse_pdf_array(&clip_path, end_path, pf); + stack[++top] = 0; + } else if (*clip_path == '/') { + if (strncmp("/DeviceGray", clip_path, 11) == 0 + || strncmp("/Indexed", clip_path, 8) == 0 + || strncmp("/CalGray", clip_path, 8) == 0) { + color_dimen = 1; + continue; + } + else if (strncmp("/DeviceRGB", clip_path, 10) == 0 + || strncmp("/CalRGB", clip_path, 7) == 0 + || strncmp("/Lab", clip_path, 4) == 0) { + color_dimen = 3; + continue; + } + else if (strncmp("/DeviceCMYK", clip_path, 11) == 0) { + color_dimen = 4; + continue; + } + else { + clip_path++; + parse_ident(&clip_path, end_path); + skip_white(&clip_path, end_path); + token = parse_ident(&clip_path, end_path); + if (strcmp(token, "gs") == 0) { + continue; + } + return -1; + } + } else { + int j; + pdf_tmatrix T; + pdf_coord p0, p1, p2, p3; + + token = parse_ident(&clip_path, end_path); + for (j = 0; j < sizeof(pdf_operators) / sizeof(pdf_operators[0]); j++) + if (strcmp(token, pdf_operators[j].token) == 0) + break; + if (j == sizeof(pdf_operators) / sizeof(pdf_operators[0])) { + return -1; + } + switch (pdf_operators[j].opcode) { + case 0: + case -1: + case -2: + case -3: + case -4: + /* Just pop the stack and do nothing. */ + top += pdf_operators[j].opcode; + if (top < -1) + return -1; + break; + case OP_SETCOLOR: + top -= color_dimen; + if (top < -1) + return -1; + break; + case OP_CLOSEandCLIP: + pdf_dev_closepath(); + case OP_CLIP: +#if 0 + pdf_dev_clip(); +#else + pdf_dev_flushpath('W', PDF_FILL_RULE_NONZERO); +#endif + break; + case OP_CONCATMATRIX: + if (top < 5) + return -1; + T.f = stack[top--]; + T.e = stack[top--]; + T.d = stack[top--]; + T.c = stack[top--]; + T.b = stack[top--]; + T.a = stack[top--]; + pdf_concatmatrix(&M, &T); + break; + case OP_SETCOLORSPACE: + /* Do nothing. */ + break; + case OP_RECTANGLE: + if (top < 3) + return -1; + p1.y = stack[top--]; + p1.x = stack[top--]; + p0.y = stack[top--]; + p0.x = stack[top--]; + if (M.b == 0 && M.c == 0) { + pdf_tmatrix M0; + M0.a = M.a; M0.b = M.b; M0.c = M.c; M0.d = M.d; + M0.e = 0; M0.f = 0; + pdf_dev_transform(&p0, &M); + pdf_dev_transform(&p1, &M0); + pdf_dev_rectadd(p0.x, p0.y, p1.x, p1.y); + } else { + p2.x = p0.x + p1.x; p2.y = p0.y + p1.y; + p3.x = p0.x; p3.y = p0.y + p1.y; + p1.x += p0.x; p1.y = p0.y; + pdf_dev_transform(&p0, &M); + pdf_dev_transform(&p1, &M); + pdf_dev_transform(&p2, &M); + pdf_dev_transform(&p3, &M); + pdf_dev_moveto(p0.x, p0.y); + pdf_dev_lineto(p1.x, p1.y); + pdf_dev_lineto(p2.x, p2.y); + pdf_dev_lineto(p3.x, p3.y); + pdf_dev_closepath(); + } + break; + case OP_CURVETO: + if (top < 5) + return -1; + p0.y = stack[top--]; + p0.x = stack[top--]; + pdf_dev_transform(&p0, &M); + p1.y = stack[top--]; + p1.x = stack[top--]; + pdf_dev_transform(&p1, &M); + p2.y = stack[top--]; + p2.x = stack[top--]; + pdf_dev_transform(&p2, &M); + pdf_dev_curveto(p2.x, p2.y, p1.x, p1.y, p0.x, p0.y); + break; + case OP_CLOSEPATH: + pdf_dev_closepath(); + break; + case OP_LINETO: + if (top < 1) + return -1; + p0.y = stack[top--]; + p0.x = stack[top--]; + pdf_dev_transform(&p0, &M); + pdf_dev_lineto(p0.x, p0.y); + break; + case OP_MOVETO: + if (top < 1) + return -1; + p0.y = stack[top--]; + p0.x = stack[top--]; + pdf_dev_transform(&p0, &M); + pdf_dev_moveto(p0.x, p0.y); + break; + case OP_NOOP: + pdf_doc_add_page_content(" n", 2); + break; + case OP_GSAVE: + depth++; + break; + case OP_GRESTORE: + depth--; + break; + case OP_CURVETO1: + if (top < 3) + return -1; + p0.y = stack[top--]; + p0.x = stack[top--]; + pdf_dev_transform(&p0, &M); + p1.y = stack[top--]; + p1.x = stack[top--]; + pdf_dev_transform(&p1, &M); + pdf_dev_vcurveto(p1.x, p1.y, p0.x, p0.y); + break; + case OP_CURVETO2: + if (top < 3) + return -1; + p0.y = stack[top--]; + p0.x = stack[top--]; + pdf_dev_transform(&p0, &M); + p1.y = stack[top--]; + p1.x = stack[top--]; + pdf_dev_transform(&p1, &M); + pdf_dev_ycurveto(p1.x, p1.y, p0.x, p0.y); + break; + default: + return -1; + } + } + } + free(save_path); + + pdf_release_obj(contents); + pdf_close(pf); + + return 0; +} + +#define WBUF_SIZE 4096 +#if HAVE_ZLIB +static int +add_stream_flate (pdf_obj *dst, const void *data, long len) +{ + z_stream z; + Bytef wbuf[WBUF_SIZE]; + + z.zalloc = Z_NULL; z.zfree = Z_NULL; z.opaque = Z_NULL; + + z.next_in = (Bytef *) data; z.avail_in = len; + z.next_out = (Bytef *) wbuf; z.avail_out = WBUF_SIZE; + + if (inflateInit(&z) != Z_OK) { + WARN("inflateInit() failed."); + return -1; + } + + for (;;) { + int status; + status = inflate(&z, Z_NO_FLUSH); + if (status == Z_STREAM_END) + break; + else if (status != Z_OK) { + WARN("inflate() failed. Broken PDF file?"); + inflateEnd(&z); + return -1; + } + + if (z.avail_out == 0) { + pdf_add_stream(dst, wbuf, WBUF_SIZE); + z.next_out = wbuf; + z.avail_out = WBUF_SIZE; + } + } + + if (WBUF_SIZE - z.avail_out > 0) + pdf_add_stream(dst, wbuf, WBUF_SIZE - z.avail_out); + + return (inflateEnd(&z) == Z_OK ? 0 : -1); +} +#endif + +static int +concat_stream (pdf_obj *dst, pdf_obj *src) +{ + const char *stream_data; + long stream_length; + pdf_obj *stream_dict; + pdf_obj *filter; + + if (!PDF_OBJ_STREAMTYPE(dst) || !PDF_OBJ_STREAMTYPE(src)) + ERROR("Invalid type."); + + stream_data = pdf_stream_dataptr(src); + stream_length = pdf_stream_length (src); + stream_dict = pdf_stream_dict (src); + + if (pdf_lookup_dict(stream_dict, "DecodeParms")) { + WARN("DecodeParams not supported."); + return -1; + } + + filter = pdf_lookup_dict(stream_dict, "Filter"); + if (!filter) { + pdf_add_stream(dst, stream_data, stream_length); + return 0; +#if HAVE_ZLIB + } else { + char *filter_name; + if (PDF_OBJ_NAMETYPE(filter)) { + filter_name = pdf_name_value(filter); + if (filter_name && !strcmp(filter_name, "FlateDecode")) + return add_stream_flate(dst, stream_data, stream_length); + else { + WARN("DecodeFilter \"%s\" not supported.", filter_name); + return -1; + } + } else if (PDF_OBJ_ARRAYTYPE(filter)) { + if (pdf_array_length(filter) > 1) { + WARN("Multiple DecodeFilter not supported."); + return -1; + } else { + filter_name = pdf_name_value(pdf_get_array(filter, 0)); + if (filter_name && !strcmp(filter_name, "FlateDecode")) + return add_stream_flate(dst, stream_data, stream_length); + else { + WARN("DecodeFilter \"%s\" not supported.", filter_name); + return -1; + } + } + } else + ERROR("Broken PDF file?"); +#endif /* HAVE_ZLIB */ + } + + return -1; +} +#endif diff --git a/Build/source/texk/dvipdfm-x/src/epdf.h b/Build/source/texk/dvipdfm-x/src/epdf.h deleted file mode 100644 index 885a6135f6a..00000000000 --- a/Build/source/texk/dvipdfm-x/src/epdf.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - - This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. - - Copyright (C) 2002-2012 by Jin-Hwan Cho and Shunsaku Hirata, - the dvipdfmx project team. - - Copyright (C) 1998, 1999 by Mark A. Wicks <mwicks@kettering.edu> - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. -*/ - -#ifndef _EPDF_H_ -#define _EPDF_H_ - -#include "mfileio.h" -#include "pdfximage.h" - -extern int pdf_include_page (pdf_ximage *ximage, FILE *file, - const char *filename); - -#endif /* _EPDF_H_ */ diff --git a/Build/source/texk/dvipdfm-x/src/fontmap.c b/Build/source/texk/dvipdfm-x/src/fontmap.c deleted file mode 100644 index f256b173ce5..00000000000 --- a/Build/source/texk/dvipdfm-x/src/fontmap.c +++ /dev/null @@ -1,1528 +0,0 @@ -/* - - This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. - - Copyright (C) 2002-2012 by Jin-Hwan Cho and Shunsaku Hirata, - the dvipdfmx project team. - - Copyright (C) 1998, 1999 by Mark A. Wicks <mwicks@kettering.edu> - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. -*/ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include "system.h" -#include "mem.h" -#include "error.h" - -#include "dpxfile.h" -#include "dpxutil.h" - -#include "subfont.h" - -#include "fontmap.h" - -#ifdef XETEX -#include "ft2build.h" -#include FT_FREETYPE_H -#endif - -/* CIDFont */ -static char *strip_options (const char *map_name, fontmap_opt *opt); - -static int verbose = 0; -void -pdf_fontmap_set_verbose (void) -{ - verbose++; -} - - -void -pdf_init_fontmap_record (fontmap_rec *mrec) -{ - ASSERT(mrec); - - mrec->map_name = NULL; - - /* SFD char mapping */ - mrec->charmap.sfd_name = NULL; - mrec->charmap.subfont_id = NULL; - /* for OFM */ - mrec->opt.mapc = -1; /* compatibility */ - - mrec->font_name = NULL; - mrec->enc_name = NULL; - - mrec->opt.slant = 0.0; - mrec->opt.extend = 1.0; - mrec->opt.bold = 0.0; - - mrec->opt.flags = 0; - - mrec->opt.design_size = -1.0; - - mrec->opt.tounicode = NULL; - mrec->opt.otl_tags = NULL; /* deactivated */ - mrec->opt.index = 0; - mrec->opt.charcoll = NULL; - mrec->opt.style = FONTMAP_STYLE_NONE; - mrec->opt.stemv = -1; /* not given explicitly by an option */ - -#ifdef XETEX - mrec->opt.ft_face = NULL; -#endif -} - -void -pdf_clear_fontmap_record (fontmap_rec *mrec) -{ - ASSERT(mrec); - - if (mrec->map_name) - RELEASE(mrec->map_name); - if (mrec->charmap.sfd_name) - RELEASE(mrec->charmap.sfd_name); - if (mrec->charmap.subfont_id) - RELEASE(mrec->charmap.subfont_id); - if (mrec->enc_name) - RELEASE(mrec->enc_name); - if (mrec->font_name) - RELEASE(mrec->font_name); - - if (mrec->opt.tounicode) - RELEASE(mrec->opt.tounicode); - if (mrec->opt.otl_tags) - RELEASE(mrec->opt.otl_tags); - if (mrec->opt.charcoll) - RELEASE(mrec->opt.charcoll); - pdf_init_fontmap_record(mrec); -} - -/* strdup: just returns NULL for NULL */ -static char * -mstrdup (const char *s) -{ - char *r; - if (!s) - return NULL; - r = NEW(strlen(s) + 1, char); - strcpy(r, s); - return r; -} - -static void -pdf_copy_fontmap_record (fontmap_rec *dst, const fontmap_rec *src) -{ - ASSERT( dst && src ); - - dst->map_name = mstrdup(src->map_name); - - dst->charmap.sfd_name = mstrdup(src->charmap.sfd_name); - dst->charmap.subfont_id = mstrdup(src->charmap.subfont_id); - - dst->font_name = mstrdup(src->font_name); - dst->enc_name = mstrdup(src->enc_name); - - dst->opt.slant = src->opt.slant; - dst->opt.extend = src->opt.extend; - dst->opt.bold = src->opt.bold; - - dst->opt.flags = src->opt.flags; - dst->opt.mapc = src->opt.mapc; - - dst->opt.tounicode = mstrdup(src->opt.tounicode); - dst->opt.otl_tags = mstrdup(src->opt.otl_tags); - dst->opt.index = src->opt.index; - dst->opt.charcoll = mstrdup(src->opt.charcoll); - dst->opt.style = src->opt.style; - dst->opt.stemv = src->opt.stemv; - -#ifdef XETEX - dst->opt.ft_face = src->opt.ft_face; -#endif -} - - -static void -hval_free (void *vp) -{ - fontmap_rec *mrec = (fontmap_rec *) vp; - pdf_clear_fontmap_record(mrec); - RELEASE(mrec); -} - - -static void -fill_in_defaults (fontmap_rec *mrec, const char *tex_name) -{ - if (mrec->enc_name && - (!strcmp(mrec->enc_name, "default") || - !strcmp(mrec->enc_name, "none"))) { - RELEASE(mrec->enc_name); - mrec->enc_name = NULL; - } - if (mrec->font_name && - (!strcmp(mrec->font_name, "default") || - !strcmp(mrec->font_name, "none"))) { - RELEASE(mrec->font_name); - mrec->font_name = NULL; - } - /* We *must* fill font_name either explicitly or by default */ - if (!mrec->font_name) { - mrec->font_name = NEW(strlen(tex_name)+1, char); - strcpy(mrec->font_name, tex_name); - } - - mrec->map_name = NEW(strlen(tex_name)+1, char); - strcpy(mrec->map_name, tex_name); - -#ifndef WITHOUT_COMPAT - /* Use "UCS" character collection for Unicode SFD - * and Identity CMap combination. For backward - * compatibility. - */ - if (mrec->charmap.sfd_name && mrec->enc_name && - !mrec->opt.charcoll) { - if ((!strcmp(mrec->enc_name, "Identity-H") || - !strcmp(mrec->enc_name, "Identity-V")) - && - (strstr(mrec->charmap.sfd_name, "Uni") || - strstr(mrec->charmap.sfd_name, "UBig") || - strstr(mrec->charmap.sfd_name, "UBg") || - strstr(mrec->charmap.sfd_name, "UGB") || - strstr(mrec->charmap.sfd_name, "UKS") || - strstr(mrec->charmap.sfd_name, "UJIS"))) { - mrec->opt.charcoll = NEW(strlen("UCS")+1, char); - strcpy(mrec->opt.charcoll, "UCS"); - } - } -#endif /* WITHOUT_COMPAT */ - - return; -} - -static char * -readline (char *buf, int buf_len, FILE *fp) -{ - char *p, *q; - ASSERT( buf && buf_len > 0 && fp ); - p = mfgets(buf, buf_len, fp); - if (!p) - return NULL; - q = strchr(p, '%'); /* we don't have quoted string */ - if (q) - *q = '\0'; - return p; -} - -#ifndef ISBLANK -# define ISBLANK(c) ((c) == ' ' || (c) == '\t') -#endif -static void -skip_blank (const char **pp, const char *endptr) -{ - const char *p = *pp; - if (!p || p >= endptr) - return; - for ( ; p < endptr && ISBLANK(*p); p++); - *pp = p; -} - -static char * -parse_string_value (const char **pp, const char *endptr) -{ - char *q = NULL; - const char *p = *pp; - int n; - - if (!p || p >= endptr) - return NULL; - if (*p == '"') - q = parse_c_string(&p, endptr); - else { - for (n = 0; p < endptr && !isspace(*p); p++, n++); - if (n == 0) - return NULL; - q = NEW(n + 1, char); - memcpy(q, *pp, n); q[n] = '\0'; - } - - *pp = p; - return q; -} - -/* no preceeding spaces allowed */ -static char * -parse_integer_value (const char **pp, const char *endptr, int base) -{ - char *q; - const char *p = *pp; - int has_sign = 0, has_prefix = 0, n; - - ASSERT( base == 0 || (base >= 2 && base <= 36) ); - - if (!p || p >= endptr) - return NULL; - - if (*p == '-' || *p == '+') { - p++; has_sign = 1; - } - if ((base == 0 || base == 16) && - p + 2 <= endptr && - p[0] == '0' && p[1] == 'x') { - p += 2; has_prefix = 1; - } - if (base == 0) { - if (has_prefix) - base = 16; - else if (p < endptr && *p == '0') - base = 8; - else { - base = 10; - } - } -#define ISDIGIT_WB(c,b) ( \ - ((b) <= 10 && (c) >= '0' && (c) < '0' + (b)) || \ - ((b) > 10 && ( \ - ((c) >= '0' && (c) <= '9') || \ - ((c) >= 'a' && (c) < 'a' + ((b) - 10)) || \ - ((c) >= 'A' && (c) < 'A' + ((b) - 10)) \ - ) \ - ) \ -) - for (n = 0; p < endptr && ISDIGIT_WB(*p, base); p++, n++); - if (n == 0) - return NULL; - if (has_sign) - n += 1; - if (has_prefix) - n += 2; - - q = NEW(n + 1, char); - memcpy(q, *pp, n); q[n] = '\0'; - - *pp = p; - return q; -} - -static int -fontmap_parse_mapdef_dpm (fontmap_rec *mrec, - const char *mapdef, const char *endptr) -{ - const char *p = mapdef; - - /* - * Parse record line in map file. First two fields (after TeX font - * name) are position specific. Arguments start at the first token - * beginning with a '-'. - * - * NOTE: - * Dvipdfm basically uses parse_ident() for parsing enc_name, - * font_name, and other string values which assumes PostScript-like - * syntax. - * skip_white() skips '\r' and '\n' but they should terminate - * fontmap line here. - */ - - skip_blank(&p, endptr); - /* encoding field */ - if (p < endptr && *p != '-') { /* May be NULL */ - mrec->enc_name = parse_string_value(&p, endptr); - skip_blank(&p, endptr); - } - - /* fontname or font filename field */ - if (p < endptr && *p != '-') { /* May be NULL */ - mrec->font_name = parse_string_value(&p, endptr); - skip_blank(&p, endptr); - } - if (mrec->font_name) { - char *tmp; - /* Several options are encoded in font_name for - * compatibility with dvipdfm. - */ - tmp = strip_options(mrec->font_name, &mrec->opt); - if (tmp) { - RELEASE(mrec->font_name); - mrec->font_name = tmp; - } - } - - skip_blank(&p, endptr); - /* Parse any remaining arguments */ - while (p + 1 < endptr && - *p != '\r' && *p != '\n' && *p == '-') { - char *q, mopt = p[1]; - long v; - - p += 2; skip_blank(&p, endptr); - switch (mopt) { - - case 's': /* Slant option */ - q = parse_float_decimal(&p, endptr); - if (!q) { - WARN("Missing a number value for 's' option."); - return -1; - } - mrec->opt.slant = atof(q); - RELEASE(q); - break; - - case 'e': /* Extend option */ - q = parse_float_decimal(&p, endptr); - if (!q) { - WARN("Missing a number value for 'e' option."); - return -1; - } - mrec->opt.extend = atof(q); - if (mrec->opt.extend <= 0.0) { - WARN("Invalid value for 'e' option: %s", q); - return -1; - } - RELEASE(q); - break; - - case 'b': /* Fake-bold option */ - q = parse_float_decimal(&p, endptr); - if (!q) { - WARN("Missing a number value for 'b' option."); - return -1; - } - mrec->opt.bold = atof(q); - if (mrec->opt.bold <= 0.0) { - WARN("Invalid value for 'b' option: %s", q); - return -1; - } - RELEASE(q); - break; - - case 'r': /* Remap option; obsolete; just ignore */ - break; - - case 'i': /* TTC index */ - q = parse_integer_value(&p, endptr, 10); - if (!q) { - WARN("Missing TTC index number..."); - return -1; - } - mrec->opt.index = atoi(q); - if (mrec->opt.index < 0) { - WARN("Invalid TTC index number: %s", q); - return -1; - } - RELEASE(q); - break; - - case 'p': /* UCS plane: just for testing */ - q = parse_integer_value(&p, endptr, 0); - if (!q) { - WARN("Missing a number for 'p' option."); - return -1; - } - v = strtol(q, NULL, 0); - if (v < 0 || v > 16) - WARN("Invalid value for option 'p': %s", q); - else { - mrec->opt.mapc = v << 16; - } - RELEASE(q); - break; - - case 'u': /* ToUnicode */ - q = parse_string_value(&p, endptr); - if (q) - mrec->opt.tounicode = q; - else { - WARN("Missing string value for option 'u'."); - return -1; - } - break; - - case 'v': /* StemV */ - q = parse_integer_value(&p, endptr, 10); - if (!q) { - WARN("Missing a number for 'v' option."); - return -1; - } - mrec->opt.stemv = strtol(q, NULL, 0); - RELEASE(q); - break; - - /* Omega uses both single-byte and double-byte set_char command - * even for double-byte OFMs. This confuses CMap decoder. - */ - case 'm': - /* Map single bytes char 0xab to double byte char 0xcdab */ - if (p + 4 <= endptr && - p[0] == '<' && p[3] == '>') { - p++; - q = parse_integer_value(&p, endptr, 16); - if (!q) { - WARN("Invalid value for option 'm'."); - return -1; - } else if (p < endptr && *p != '>') { - WARN("Invalid value for option 'm': %s", q); - RELEASE(q); - return -1; - } - v = strtol(q, NULL, 16); - mrec->opt.mapc = ((v << 8) & 0x0000ff00L); - RELEASE(q); p++; - } else if (p + 4 <= endptr && - !memcmp(p, "sfd:", strlen("sfd:"))) { - char *r; - const char *rr; - /* SFD mapping: sfd:Big5,00 */ - p += 4; skip_blank(&p, endptr); - q = parse_string_value(&p, endptr); - if (!q) { - WARN("Missing value for option 'm'."); - return -1; - } - r = strchr(q, ','); - if (!r) { - WARN("Invalid value for option 'm': %s", q); - RELEASE(q); - return -1; - } - *r = 0; rr = ++r; skip_blank(&rr, r + strlen(r)); - if (*rr == '\0') { - WARN("Invalid value for option 'm': %s,", q); - RELEASE(q); - return -1; - } - mrec->charmap.sfd_name = mstrdup(q); - mrec->charmap.subfont_id = mstrdup(rr); - RELEASE(q); - } else if (p + 4 < endptr && - !memcmp(p, "pad:", strlen("pad:"))) { - p += 4; skip_blank(&p, endptr); - q = parse_integer_value(&p, endptr, 16); - if (!q) { - WARN("Invalid value for option 'm'."); - return -1; - } else if (p < endptr && !isspace(*p)) { - WARN("Invalid value for option 'm': %s", q); - RELEASE(q); - return -1; - } - v = strtol(q, NULL, 16); - mrec->opt.mapc = ((v << 8) & 0x0000ff00L); - RELEASE(q); - } else { - WARN("Invalid value for option 'm'."); - return -1; - } - break; - - case 'w': /* Writing mode (for unicode encoding) */ - if (!mrec->enc_name || - strcmp(mrec->enc_name, "unicode")) { - WARN("Fontmap option 'w' meaningless for encoding other than \"unicode\"."); - return -1; - } - q = parse_integer_value(&p, endptr, 10); - if (!q) { - WARN("Missing wmode value..."); - return -1; - } - if (atoi(q) == 1) - mrec->opt.flags |= FONTMAP_OPT_VERT; - else if (atoi(q) == 0) - mrec->opt.flags &= ~FONTMAP_OPT_VERT; - else { - WARN("Invalid value for option 'w': %s", q); - } - RELEASE(q); - break; - - default: - WARN("Unrecognized font map option: '%c'", mopt); - return -1; - break; - } - skip_blank(&p, endptr); - } - - if (p < endptr && *p != '\r' && *p != '\n') { - WARN("Invalid char in fontmap line: %c", *p); - return -1; - } - - return 0; -} - - -/* Parse record line in map file of DVIPS/pdfTeX format. */ -static int -fontmap_parse_mapdef_dps (fontmap_rec *mrec, - const char *mapdef, const char *endptr) -{ - const char *p = mapdef; - char *q; - - skip_blank(&p, endptr); - - /* The first field (after TFM name) must be PostScript name. */ - /* However, pdftex.map allows a line without PostScript name. */ - - if (*p != '"' && *p != '<') { - if (p < endptr) { - q = parse_string_value(&p, endptr); - if (q) RELEASE(q); - skip_blank(&p, endptr); - } else { - WARN("Missing a PostScript font name."); - return -1; - } - } - - if (p >= endptr) return 0; - - /* Parse any remaining arguments */ - while (p < endptr && *p != '\r' && *p != '\n' && (*p == '<' || *p == '"')) { - switch (*p) { - case '<': /* encoding or fontfile field */ - if (++p < endptr && *p == '[') p++; /*skip */ - skip_blank(&p, endptr); - if ((q = parse_string_value(&p, endptr))) { - int n = strlen(q); - if (n > 4 && strncmp(q+n-4, ".enc", 4) == 0) - mrec->enc_name = q; - else - mrec->font_name = q; - } - skip_blank(&p, endptr); - break; - - case '"': /* Options */ - if ((q = parse_string_value(&p, endptr))) { - const char *r = q, *e = q+strlen(q); - char *s, *t; - skip_blank(&r, e); - while (r < e) { - if ((s = parse_float_decimal(&r, e))) { - skip_blank(&r, e); - if ((t = parse_string_value(&r, e))) { - if (strcmp(t, "SlantFont") == 0) - mrec->opt.slant = atof(s); - else if (strcmp(t, "ExtendFont") == 0) - mrec->opt.extend = atof(s); - RELEASE(t); - } - RELEASE(s); - } else if ((s = parse_string_value(&r, e))) { /* skip */ - RELEASE(s); - } - skip_blank(&r, e); - } - RELEASE(q); - } - skip_blank(&p, endptr); - break; - - default: - WARN("Found an invalid entry: %s", p); - return -1; - break; - } - skip_blank(&p, endptr); - } - - if (p < endptr && *p != '\r' && *p != '\n') { - WARN("Invalid char in fontmap line: %c", *p); - return -1; - } - - return 0; -} - - -static struct ht_table *fontmap = NULL; - -#define fontmap_invalid(m) (!(m) || !(m)->map_name || !(m)->font_name) -static char * -chop_sfd_name (const char *tex_name, char **sfd_name) -{ - char *fontname; - char *p, *q; - int m, n, len; - - *sfd_name = NULL; - - p = strchr(tex_name, '@'); - if (!p || - p[1] == '\0' || p == tex_name) { - return NULL; - } - m = (int) (p - tex_name); - p++; - q = strchr(p, '@'); - if (!q || q == p) { - return NULL; - } - n = (int) (q - p); - q++; - - len = strlen(tex_name) - n; - fontname = NEW(len+1, char); - memcpy(fontname, tex_name, m); - fontname[m] = '\0'; - if (*q) - strcat(fontname, q); - - *sfd_name = NEW(n+1, char); - memcpy(*sfd_name, p, n); - (*sfd_name)[n] = '\0'; - - return fontname; -} - -static char * -make_subfont_name (const char *map_name, const char *sfd_name, const char *sub_id) -{ - char *tfm_name; - int n, m; - char *p, *q; - - p = strchr(map_name, '@'); - if (!p || p == map_name) - return NULL; - m = (int) (p - map_name); - q = strchr(p + 1, '@'); - if (!q || q == p + 1) - return NULL; - n = (int) (q - p) + 1; /* including two '@' */ - if (strlen(sfd_name) != n - 2 || - memcmp(p + 1, sfd_name, n - 2)) - return NULL; - tfm_name = NEW(strlen(map_name) - n + strlen(sub_id) + 1, char); - memcpy(tfm_name, map_name, m); - tfm_name[m] = '\0'; - strcat(tfm_name, sub_id); - if (q[1]) /* not ending with '@' */ - strcat(tfm_name, q + 1); - - return tfm_name; -} - -/* "foo@A@ ..." is expanded to - * fooab ... -m sfd:A,ab - * ... - * fooyz ... -m sfd:A,yz - * where 'ab' ... 'yz' is subfont IDs in SFD 'A'. - */ -int -pdf_append_fontmap_record (const char *kp, const fontmap_rec *vp) -{ - fontmap_rec *mrec; - char *fnt_name, *sfd_name = NULL; - - if (!kp || fontmap_invalid(vp)) { - WARN("Invalid fontmap record..."); - return -1; - } - - if (verbose > 3) - MESG("fontmap>> append key=\"%s\"...", kp); - - fnt_name = chop_sfd_name(kp, &sfd_name); - if (fnt_name && sfd_name) { - char *tfm_name; - char **subfont_ids; - int n = 0; - subfont_ids = sfd_get_subfont_ids(sfd_name, &n); - if (!subfont_ids) - return -1; - while (n-- > 0) { - tfm_name = make_subfont_name(kp, sfd_name, subfont_ids[n]); - if (!tfm_name) - continue; - mrec = ht_lookup_table(fontmap, tfm_name, strlen(tfm_name)); - if (!mrec) { - mrec = NEW(1, fontmap_rec); - pdf_init_fontmap_record(mrec); - mrec->map_name = mstrdup(kp); /* link */ - mrec->charmap.sfd_name = mstrdup(sfd_name); - mrec->charmap.subfont_id = mstrdup(subfont_ids[n]); - ht_insert_table(fontmap, tfm_name, strlen(tfm_name), mrec); - } - RELEASE(tfm_name); - } - RELEASE(fnt_name); - RELEASE(sfd_name); - } - - mrec = ht_lookup_table(fontmap, kp, strlen(kp)); - if (!mrec) { - mrec = NEW(1, fontmap_rec); - pdf_copy_fontmap_record(mrec, vp); - if (mrec->map_name && !strcmp(kp, mrec->map_name)) { - RELEASE(mrec->map_name); - mrec->map_name = NULL; - } - ht_insert_table(fontmap, kp, strlen(kp), mrec); - } - if (verbose > 3) - MESG("\n"); - - return 0; -} - -int -pdf_remove_fontmap_record (const char *kp) -{ - char *fnt_name, *sfd_name = NULL; - - if (!kp) - return -1; - - if (verbose > 3) - MESG("fontmap>> remove key=\"%s\"...", kp); - - fnt_name = chop_sfd_name(kp, &sfd_name); - if (fnt_name && sfd_name) { - char *tfm_name; - char **subfont_ids; - int n = 0; - subfont_ids = sfd_get_subfont_ids(sfd_name, &n); - if (!subfont_ids) - return -1; - if (verbose > 3) - MESG("\nfontmap>> Expand @%s@:", sfd_name); - while (n-- > 0) { - tfm_name = make_subfont_name(kp, sfd_name, subfont_ids[n]); - if (!tfm_name) - continue; - if (verbose > 3) - MESG(" %s", tfm_name); - ht_remove_table(fontmap, tfm_name, strlen(tfm_name)); - RELEASE(tfm_name); - } - RELEASE(fnt_name); - RELEASE(sfd_name); - } - - ht_remove_table(fontmap, kp, strlen(kp)); - - if (verbose > 3) - MESG("\n"); - - return 0; -} - -int -pdf_insert_fontmap_record (const char *kp, const fontmap_rec *vp) -{ - fontmap_rec *mrec; - char *fnt_name, *sfd_name; - - if (!kp || fontmap_invalid(vp)) { - WARN("Invalid fontmap record..."); - return -1; - } - - if (verbose > 3) - MESG("fontmap>> insert key=\"%s\"...", kp); - - fnt_name = chop_sfd_name(kp, &sfd_name); - if (fnt_name && sfd_name) { - char *tfm_name; - char **subfont_ids; - int n = 0; - subfont_ids = sfd_get_subfont_ids(sfd_name, &n); - if (!subfont_ids) { - RELEASE(fnt_name); - RELEASE(sfd_name); - return -1; - } - if (verbose > 3) - MESG("\nfontmap>> Expand @%s@:", sfd_name); - while (n-- > 0) { - tfm_name = make_subfont_name(kp, sfd_name, subfont_ids[n]); - if (!tfm_name) - continue; - if (verbose > 3) - MESG(" %s", tfm_name); - mrec = NEW(1, fontmap_rec); - pdf_init_fontmap_record(mrec); - mrec->map_name = mstrdup(kp); /* link to this entry */ - mrec->charmap.sfd_name = mstrdup(sfd_name); - mrec->charmap.subfont_id = mstrdup(subfont_ids[n]); - ht_insert_table(fontmap, tfm_name, strlen(tfm_name), mrec); - RELEASE(tfm_name); - } - RELEASE(fnt_name); - RELEASE(sfd_name); - } - - mrec = NEW(1, fontmap_rec); - pdf_copy_fontmap_record(mrec, vp); - if (mrec->map_name && !strcmp(kp, mrec->map_name)) { - RELEASE(mrec->map_name); - mrec->map_name = NULL; - } - ht_insert_table(fontmap, kp, strlen(kp), mrec); - - if (verbose > 3) - MESG("\n"); - - return 0; -} - - -int -pdf_read_fontmap_line (fontmap_rec *mrec, const char *mline, long mline_len, int format) -{ - int error; - char *q; - const char *p, *endptr; - - ASSERT(mrec); - - p = mline; - endptr = p + mline_len; - - skip_blank(&p, endptr); - if (p >= endptr) - return -1; - - q = parse_string_value(&p, endptr); - if (!q) - return -1; - - if (format > 0) /* DVIPDFM format */ - error = fontmap_parse_mapdef_dpm(mrec, p, endptr); - else /* DVIPS/pdfTeX format */ - error = fontmap_parse_mapdef_dps(mrec, p, endptr); - if (!error) { - char *fnt_name, *sfd_name = NULL; - fnt_name = chop_sfd_name(q, &sfd_name); - if (fnt_name && sfd_name) { - if (!mrec->font_name) { - /* In the case of subfonts, the base name (before the character '@') - * will be used as a font_name by default. - * Otherwise tex_name will be used as a font_name by default. - */ - mrec->font_name = fnt_name; - } else { - RELEASE(fnt_name); - } - if (mrec->charmap.sfd_name) - RELEASE(mrec->charmap.sfd_name); - mrec->charmap.sfd_name = sfd_name ; - } - fill_in_defaults(mrec, q); - } - RELEASE(q); - - return error; -} - -/* DVIPS/pdfTeX fontmap line if one of the following three cases found: - * - * (1) any line including the character '"' - * (2) any line including the character '<' - * (3) if the line consists of two entries (tfmname and psname) - * - * DVIPDFM fontmap line otherwise. - */ -int -is_pdfm_mapline (const char *mline) /* NULL terminated. */ -{ - int n = 0; - const char *p, *endptr; - - if (strchr(mline, '"') || strchr(mline, '<')) - return -1; /* DVIPS/pdfTeX format */ - - p = mline; - endptr = p + strlen(mline); - - skip_blank(&p, endptr); - - while (p < endptr) { - /* Break if '-' preceeded by blanks is found. (DVIPDFM format) */ - if (*p == '-') return 1; - for (n++; p < endptr && !ISBLANK(*p); p++); - skip_blank(&p, endptr); - } - - /* Two entries: TFM_NAME PS_NAME only (DVIPS format) - * Otherwise (DVIPDFM format) */ - return (n == 2 ? 0 : 1); -} - -int -pdf_load_fontmap_file (const char *filename, int mode) -{ - fontmap_rec *mrec; - FILE *fp; - const char *p = NULL, *endptr; - long llen, lpos = 0; - int error = 0, format = 0; - - ASSERT(filename); - ASSERT(fontmap) ; - - if (verbose) - MESG("<FONTMAP:%s", filename); - - fp = DPXFOPEN(filename, DPX_RES_TYPE_FONTMAP); - if (!fp) { - WARN("Couldn't open font map file \"%s\".", filename); - return -1; - } - - while (!error && - (p = readline(work_buffer, WORK_BUFFER_SIZE, fp)) != NULL) { - int m; - - lpos++; - llen = strlen(work_buffer); - endptr = p + llen; - - skip_blank(&p, endptr); - if (p == endptr) - continue; - - m = is_pdfm_mapline(p); - - if (format * m < 0) { /* mismatch */ - WARN("Found a mismatched fontmap line %d from %s.", lpos, filename); - WARN("-- Ignore the current input buffer: %s", p); - continue; - } else - format += m; - - mrec = NEW(1, fontmap_rec); - pdf_init_fontmap_record(mrec); - - /* format > 0: DVIPDFM, format <= 0: DVIPS/pdfTeX */ - error = pdf_read_fontmap_line(mrec, p, llen, format); - if (error) { - WARN("Invalid map record in fontmap line %d from %s.", lpos, filename); - WARN("-- Ignore the current input buffer: %s", p); - pdf_clear_fontmap_record(mrec); - RELEASE(mrec); - continue; - } else { - switch (mode) { - case FONTMAP_RMODE_REPLACE: - pdf_insert_fontmap_record(mrec->map_name, mrec); - break; - case FONTMAP_RMODE_APPEND: - pdf_append_fontmap_record(mrec->map_name, mrec); - break; - case FONTMAP_RMODE_REMOVE: - pdf_remove_fontmap_record(mrec->map_name); - break; - } - } - pdf_clear_fontmap_record(mrec); - RELEASE(mrec); - } - DPXFCLOSE(fp); - - if (verbose) - MESG(">"); - - return error; -} - -#ifdef XETEX -static int -pdf_insert_native_fontmap_record (const char *name, const char *path, int index, FT_Face face, - int layout_dir, int extend, int slant, int embolden) -{ - char *fontmap_key; - fontmap_rec *mrec; - - ASSERT(name); - ASSERT(path || face); - - fontmap_key = malloc(strlen(name) + 40); // CHECK - sprintf(fontmap_key, "%s/%c/%d/%d/%d", name, layout_dir == 0 ? 'H' : 'V', extend, slant, embolden); - - if (verbose) - MESG("<NATIVE-FONTMAP:%s", fontmap_key); - - mrec = NEW(1, fontmap_rec); - pdf_init_fontmap_record(mrec); - - mrec->map_name = fontmap_key; - mrec->enc_name = mstrdup(layout_dir == 0 ? "Identity-H" : "Identity-V"); - mrec->font_name = (path != NULL) ? mstrdup(path) : NULL; - mrec->opt.index = index; - mrec->opt.ft_face = face; - if (layout_dir != 0) - mrec->opt.flags |= FONTMAP_OPT_VERT; - - fill_in_defaults(mrec, fontmap_key); - - mrec->opt.extend = extend / 65536.0; - mrec->opt.slant = slant / 65536.0; - mrec->opt.bold = embolden / 65536.0; - - pdf_insert_fontmap_record(mrec->map_name, mrec); - pdf_clear_fontmap_record(mrec); - RELEASE(mrec); - - if (verbose) - MESG(">"); - - return 0; -} - -static FT_Library ftLib; - -static int -pdf_load_native_font_from_path(const char *ps_name, int layout_dir, int extend, int slant, int embolden) -{ - const char *p; - char *filename = NEW(strlen(ps_name), char); - char *q = filename; - int index = 0; - FT_Face face = NULL; - int error = -1; - -#ifdef WIN32 - for (p = ps_name + 1; *p && *p != ']'; ++p) { - if (*p == ':') { - if (p == ps_name+2 && isalpha(*(p-1)) && (*(p+1) == '/' || *(p+1) == '\\')) - *q++ = *p; - else - break; - } - else - *q++ = *p; - } -#else - for (p = ps_name + 1; *p && *p != ':' && *p != ']'; ++p) - *q++ = *p; -#endif - *q = 0; - if (*p == ':') { - ++p; - while (*p && *p != ']') - index = index * 10 + *p++ - '0'; - } - - /* try loading the filename directly */ - error = FT_New_Face(ftLib, filename, index, &face); - - /* if failed, try locating the file in the TEXMF tree */ - if ( error && - ( (q = dpx_find_opentype_file(filename)) != NULL - || (q = dpx_find_truetype_file(filename)) != NULL - || (q = dpx_find_type1_file(filename)) != NULL - || (q = dpx_find_dfont_file(filename)) != NULL) ) { - error = FT_New_Face(ftLib, q, index, &face); - RELEASE(q); - } - - if (error == 0) - error = pdf_insert_native_fontmap_record(ps_name, filename, index, face, - layout_dir, extend, slant, embolden); - RELEASE(filename); - return error; -} - -int -pdf_load_native_font (const char *ps_name, - const char *fam_name, const char *sty_name, - int layout_dir, int extend, int slant, int embolden) -{ - static int sInitialized = 0; - int error = -1; - - if (!sInitialized) { - if (FT_Init_FreeType(&ftLib) != 0) { - WARN("FreeType initialization failed."); - return error; - } - sInitialized = 1; - } - - if (ps_name[0] == '[') { - error = pdf_load_native_font_from_path(ps_name, layout_dir, extend, slant, embolden); - } - else { - ERROR("Loading fonts by font name is not supported: %s", ps_name); - } - - return error; -} -#endif /* XETEX */ - -#if 0 -/* tfm_name="dmjhira10", map_name="dmj@DNP@10", sfd_name="DNP" - * --> sub_id="hira" - * Test if tfm_name can be really considered as subfont. - */ -static int -test_subfont (const char *tfm_name, const char *map_name, const char *sfd_name) -{ - int r = 0; - char **ids; - int n, m; - char *p = (char *) map_name; - char *q = (char *) tfm_name; - - ASSERT( tfm_name && map_name && sfd_name ); - - /* until first occurence of '@' */ - for ( ; *p && *q && *p == *q && *p != '@'; p++, q++); - if (*p != '@') - return 0; - p++; - /* compare sfd_name (should be always true here) */ - if (strlen(p) <= strlen(sfd_name) || - memcmp(p, sfd_name, strlen(sfd_name)) || - p[strlen(sfd_name)] != '@') - return 0; - /* check tfm_name follows second '@' */ - p += strlen(sfd_name) + 1; - if (*p) { - char *r = (char *) tfm_name; - r += strlen(tfm_name) - strlen(p); - if (strcmp(r, p)) - return 0; - } - /* Now 'p' is located at next to SFD name terminator - * (second '@') in map_name and 'q' is at first char - * of subfont_id substring in tfm_name. - */ - n = strlen(q) - strlen(p); /* length of subfont_id string */ - if (n <= 0) - return 0; - /* check if n-length substring 'q' is valid as subfont ID */ - ids = sfd_get_subfont_ids(sfd_name, &m); - if (!ids) - return 0; - while (!r && m-- > 0) { - if (strlen(ids[m]) == n && - !memcmp(q, ids[m], n)) { - r = 1; - } - } - - return r; -} -#endif /* 0 */ - - -fontmap_rec * -pdf_lookup_fontmap_record (const char *tfm_name) -{ - fontmap_rec *mrec = NULL; - - if (fontmap && tfm_name) - mrec = ht_lookup_table(fontmap, tfm_name, strlen(tfm_name)); - - return mrec; -} - - -void -pdf_init_fontmaps (void) -{ - fontmap = NEW(1, struct ht_table); - ht_init_table(fontmap, hval_free); -} - -void -pdf_close_fontmaps (void) -{ - if (fontmap) { - ht_clear_table(fontmap); - RELEASE(fontmap); - } - fontmap = NULL; - - release_sfd_record(); -} - -#if 0 -void -pdf_clear_fontmaps (void) -{ - pdf_close_fontmaps(); - pdf_init_fontmaps(); -} -#endif - -/* CIDFont options - * - * FORMAT: - * - * (:int:)?!?string(/string)?(,string)? - */ - -static char * -substr (const char **str, char stop) -{ - char *sstr; - const char *endptr; - - endptr = strchr(*str, stop); - if (!endptr || endptr == *str) - return NULL; - sstr = NEW(endptr-(*str)+1, char); - memcpy(sstr, *str, endptr-(*str)); - sstr[endptr-(*str)] = '\0'; - - *str = endptr+1; - return sstr; -} - -#include <ctype.h> -#define CID_MAPREC_CSI_DELIM '/' - -static char * -strip_options (const char *map_name, fontmap_opt *opt) -{ - char *font_name; - const char *p; - char *next = NULL; - int have_csi = 0, have_style = 0; - - ASSERT(opt); - - p = map_name; - font_name = NULL; - opt->charcoll = NULL; - opt->index = 0; - opt->style = FONTMAP_STYLE_NONE; - opt->flags = 0; - - if (*p == ':' && isdigit(*(p+1))) { - opt->index = (int) strtoul(p+1, &next, 10); - if (*next == ':') - p = next + 1; - else { - opt->index = 0; - } - } - if (*p == '!') { /* no-embedding */ - if (*(++p) == '\0') - ERROR("Invalid map record: %s (--> %s)", map_name, p); - opt->flags |= FONTMAP_OPT_NOEMBED; - } - - if ((next = strchr(p, CID_MAPREC_CSI_DELIM)) != NULL) { - if (next == p) - ERROR("Invalid map record: %s (--> %s)", map_name, p); - font_name = substr(&p, CID_MAPREC_CSI_DELIM); - have_csi = 1; - } else if ((next = strchr(p, ',')) != NULL) { - if (next == p) - ERROR("Invalid map record: %s (--> %s)", map_name, p); - font_name = substr(&p, ','); - have_style = 1; - } else { - font_name = NEW(strlen(p)+1, char); - strcpy(font_name, p); - } - - if (have_csi) { - if ((next = strchr(p, ',')) != NULL) { - opt->charcoll = substr(&p, ','); - have_style = 1; - } else if (p[0] == '\0') { - ERROR("Invalid map record: %s.", map_name); - } else { - opt->charcoll = NEW(strlen(p)+1, char); - strcpy(opt->charcoll, p); - } - } - - if (have_style) { - if (!strncmp(p, "BoldItalic", 10)) { - if (*(p+10)) - ERROR("Invalid map record: %s (--> %s)", map_name, p); - opt->style = FONTMAP_STYLE_BOLDITALIC; - } else if (!strncmp(p, "Bold", 4)) { - if (*(p+4)) - ERROR("Invalid map record: %s (--> %s)", map_name, p); - opt->style = FONTMAP_STYLE_BOLD; - } else if (!strncmp(p, "Italic", 6)) { - if (*(p+6)) - ERROR("Invalid map record: %s (--> %s)", map_name, p); - opt->style = FONTMAP_STYLE_ITALIC; - } - } - - return font_name; -} - -#if DPXTEST -static void -dump_fontmap_rec (const char *key, const fontmap_rec *mrec) -{ - fontmap_opt *opt = (fontmap_opt *) &mrec->opt; - - if (mrec->map_name) - fprintf(stdout, " <!-- subfont"); - else - fprintf(stdout, " <insert"); - fprintf(stdout, " id=\"%s\"", key); - if (mrec->map_name) - fprintf(stdout, " map-name=\"%s\"", mrec->map_name); - if (mrec->enc_name) - fprintf(stdout, " enc-name=\"%s\"", mrec->enc_name); - if (mrec->font_name) - fprintf(stdout, " font-name=\"%s\"", mrec->font_name); - if (mrec->charmap.sfd_name && mrec->charmap.subfont_id) { - fprintf(stdout, " charmap=\"sfd:%s,%s\"", - mrec->charmap.sfd_name, mrec->charmap.subfont_id); - } - if (opt->slant != 0.0) - fprintf(stdout, " font-slant=\"%g\"", opt->slant); - if (opt->extend != 1.0) - fprintf(stdout, " font-extend=\"%g\"", opt->extend); - if (opt->charcoll) - fprintf(stdout, " glyph-order=\"%s\"", opt->charcoll); - if (opt->tounicode) - fprintf(stdout, " tounicode=\"%s\"", opt->tounicode); - if (opt->index != 0) - fprintf(stdout, " ttc-index=\"%d\"", opt->index); - if (opt->flags & FONTMAP_OPT_NOEMBED) - fprintf(stdout, " embedding=\"no\""); - if (opt->mapc >= 0) { - fprintf(stdout, " charmap=\"pad:"); - if (opt->mapc > 0xffff) - fprintf(stdout, "%02x %02x", (opt->mapc >> 16) & 0xff, (opt->mapc >> 8) & 0xff); - else - fprintf(stdout, "%02x", (opt->mapc >> 8) & 0xff); - fprintf(stdout, "\""); - } - if (opt->flags & FONTMAP_OPT_VERT) - fprintf(stdout, " writing-mode=\"vertical\""); - if (opt->style != FONTMAP_STYLE_NONE) { - fprintf(stdout, " font-style=\""); - switch (opt->style) { - case FONTMAP_STYLE_BOLD: - fprintf(stdout, "bold"); - break; - case FONTMAP_STYLE_ITALIC: - fprintf(stdout, "italic"); - break; - case FONTMAP_STYLE_BOLDITALIC: - fprintf(stdout, "bolditalic"); - break; - } - fprintf(stdout, "\""); - } - if (mrec->map_name) - fprintf(stdout, " / -->\n"); - else - fprintf(stdout, " />\n"); -} - -void -dump_fontmaps (void) -{ - struct ht_iter iter; - fontmap_rec *mrec; - char key[128], *kp; - int kl; - - if (!fontmap) - return; - - fprintf(stdout, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"); - fprintf(stdout, "<!DOCTYPE fontmap SYSTEM \"fontmap.dtd\">\n"); - fprintf(stdout, "<fontmap id=\"%s\">\n", "foo"); - if (ht_set_iter(fontmap, &iter) == 0) { - do { - kp = ht_iter_getkey(&iter, &kl); - mrec = ht_iter_getval(&iter); - if (kl > 127) - continue; - memcpy(key, kp, kl); key[kl] = 0; - dump_fontmap_rec(key, mrec); - } while (!ht_iter_next(&iter)); - } - ht_clear_iter(&iter); - fprintf(stdout, "</fontmap>\n"); - - return; -} - -void -test_fontmap_help (void) -{ - fprintf(stdout, "usage: fontmap [options] [mapfile...]\n"); - fprintf(stdout, "-l, --lookup string\n"); - fprintf(stdout, " Lookup fontmap entry for 'string' after loading mapfile(s).\n"); -} - -int -test_fontmap_main (int argc, char *argv[]) -{ - int i; - char *key = NULL; - - for (;;) { - int c, optidx = 0; - static struct option long_options[] = { - {"lookup", 1, 0, 'l'}, - {"help", 0, 0, 'h'}, - {0, 0, 0, 0} - }; - c = getopt_long(argc, argv, "l:h", long_options, &optidx); - if (c == -1) - break; - - switch (c) { - case 'l': - key = optarg; - break; - case 'h': - test_fontmap_help(); - return 0; - break; - default: - test_fontmap_help(); - return -1; - break; - } - } - - pdf_init_fontmaps(); - for (i = optind; i < argc; i++) - pdf_load_fontmap_file(argv[i], FONTMAP_RMODE_REPLACE); - - if (key == NULL) - dump_fontmaps(); - else { - fontmap_rec *mrec; - mrec = pdf_lookup_fontmap_record(key); - if (mrec) - dump_fontmap_rec(key, mrec); - else { - WARN("Fontmap entry \"%s\" not found.", key); - } - } - pdf_close_fontmaps(); - - return 0; -} -#endif /* DPXTEST */ diff --git a/Build/source/texk/dvipdfm-x/src/pdfcolor.c b/Build/source/texk/dvipdfm-x/src/pdfcolor.c index 693998a45d6..988f4ec6e4a 100644 --- a/Build/source/texk/dvipdfm-x/src/pdfcolor.c +++ b/Build/source/texk/dvipdfm-x/src/pdfcolor.c @@ -48,6 +48,7 @@ pdf_color_set_verbose (void) verbose++; } +#ifndef XETEX /* This function returns PDF_COLORSPACE_TYPE_GRAY, * PDF_COLORSPACE_TYPE_RGB or PDF_COLORSPACE_TYPE_CMYK. */ @@ -58,6 +59,7 @@ pdf_color_type (const pdf_color *color) return -color->num_components; } +#endif int pdf_color_rgbcolor (pdf_color *color, double r, double g, double b) @@ -144,6 +146,7 @@ pdf_color_copycolor (pdf_color *color1, const pdf_color *color2) memcpy(color1, color2, sizeof(pdf_color)); } +#ifndef XETEX /* Brighten up a color. f == 0 means no change, f == 1 means white. */ void pdf_color_brighten_color (pdf_color *dst, const pdf_color *src, double f) @@ -164,6 +167,7 @@ pdf_color_brighten_color (pdf_color *dst, const pdf_color *src, double f) dst->values[n] = f0 * src->values[n] + f1; } } +#endif int pdf_color_is_white (const pdf_color *color) @@ -174,7 +178,17 @@ pdf_color_is_white (const pdf_color *color) ASSERT(color); n = color->num_components; - f = n == 4 ? 0.0 : 1.0; /* n == 4 is CMYK, others are RGB and Gray */ + switch (n) { + case 1: /* Gray */ + case 3: /* RGB */ + f = 1.0; + break; + case 4: /* CMYK */ + f = 0.0; + break; + default: + return 0; + } while (n--) if (color->values[n] != f) @@ -183,6 +197,7 @@ pdf_color_is_white (const pdf_color *color) return 1; } +#ifndef XETEX int pdf_color_to_string (const pdf_color *color, char *buffer) { @@ -193,6 +208,7 @@ pdf_color_to_string (const pdf_color *color, char *buffer) } return len; } +#endif pdf_color current_fill = { 1, @@ -204,13 +220,24 @@ pdf_color current_stroke = { {0.0, 0.0, 0.0, 0.0} }; +#ifndef XETEX /* * This routine is not a real color matching. */ int pdf_color_compare (const pdf_color *color1, const pdf_color *color2) { - int n = color1->num_components; + int n; + + n = color1->num_components; + switch (n) { + case 1: /* Gray */ + case 3: /* RGB */ + case 4: /* CMYK */ + break; + default: + return -1; + } if (n != color2->num_components) return -1; @@ -221,6 +248,7 @@ pdf_color_compare (const pdf_color *color1, const pdf_color *color2) return 0; } +#endif int pdf_color_is_valid (const pdf_color *color) @@ -228,12 +256,20 @@ pdf_color_is_valid (const pdf_color *color) int n; n = color->num_components; - if (n != 1 && n != 3 && n != 4) + switch (n) { + case 1: /* Gray */ + case 3: /* RGB */ + case 4: /* CMYK */ + break; + default: return 0; + } while (n--) - if (color->values[n] < 0.0 || color->values[n] > 1.0) + if (color->values[n] < 0.0 || color->values[n] > 1.0) { + WARN("Invalid color value: %g", color->values[n]); return 0; + } return 1; } @@ -270,6 +306,7 @@ pdf_color_clear_stack (void) return; } +#ifndef XETEX void pdf_color_set (pdf_color *sc, pdf_color *fc) { @@ -277,6 +314,7 @@ pdf_color_set (pdf_color *sc, pdf_color *fc) pdf_color_copycolor(&color_stack.fill[color_stack.current], fc); pdf_dev_reset_color(0); } +#endif void pdf_color_push (pdf_color *sc, pdf_color *fc) @@ -310,6 +348,22 @@ pdf_color_get_current (pdf_color **sc, pdf_color **fc) return; } +#ifdef XETEX +/* BUG (20060330): color change does not effect on the next page. + * The problem is due to the part of grestore because it restores + * the color values in the state of gsave which are not correct + * if the color values are changed inside of a page. + */ +void +pdf_dev_preserve_color (void) +{ + if (color_stack.current > 0) { + current_stroke = color_stack.stroke[color_stack.current]; + current_fill = color_stack.fill[color_stack.current]; + } +} +#endif + /***************************** COLOR SPACE *****************************/ static int pdf_colorspace_defineresource (const char *ident, diff --git a/Build/source/texk/dvipdfm-x/src/pdfcolor.h b/Build/source/texk/dvipdfm-x/src/pdfcolor.h deleted file mode 100644 index 5c21ad45888..00000000000 --- a/Build/source/texk/dvipdfm-x/src/pdfcolor.h +++ /dev/null @@ -1,112 +0,0 @@ -/* - - This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. - - Copyright (C) 2002-2012 by Jin-Hwan Cho and Shunsaku Hirata, - the dvipdfmx project team. - - Copyright (C) 1998, 1999 by Mark A. Wicks <mwicks@kettering.edu> - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. -*/ - -#ifndef _PDF_COLOR_H_ -#define _PDF_COLOR_H_ - -#include "pdfobj.h" - -#define PDF_COLORSPACE_TYPE_DEVICECMYK -4 -#define PDF_COLORSPACE_TYPE_DEVICERGB -3 -#define PDF_COLORSPACE_TYPE_DEVICEGRAY -1 -#define PDF_COLORSPACE_TYPE_INVALID 0 -#define PDF_COLORSPACE_TYPE_CALGRAY 1 -#define PDF_COLORSPACE_TYPE_CIELAB 2 -#define PDF_COLORSPACE_TYPE_CALRGB 3 -#define PDF_COLORSPACE_TYPE_ICCBASED 4 - -#define PDF_COLORSPACE_TYPE_CMYK PDF_COLORSPACE_TYPE_DEVICECMYK -#define PDF_COLORSPACE_TYPE_RGB PDF_COLORSPACE_TYPE_DEVICERGB -#define PDF_COLORSPACE_TYPE_GRAY PDF_COLORSPACE_TYPE_DEVICEGRAY - - -#define PDF_COLOR_COMPONENT_MAX 4 - -typedef struct -{ - int num_components; - double values[PDF_COLOR_COMPONENT_MAX]; -} pdf_color; - -extern void pdf_color_set_verbose (void); - -extern int pdf_color_type (const pdf_color *color); -extern int pdf_color_rgbcolor (pdf_color *color, - double r, double g, double b); -extern int pdf_color_cmykcolor (pdf_color *color, - double c, double m, double y, double k); -extern int pdf_color_graycolor (pdf_color *color, double g); -#define pdf_color_black(c) pdf_color_graycolor(c, 0.0); -#define pdf_color_white(c) pdf_color_graycolor(c, 1.0); - -extern void pdf_color_copycolor (pdf_color *color1, const pdf_color *color2); -extern void pdf_color_brighten_color (pdf_color *dst, const pdf_color *src, double f); - -extern int pdf_color_compare (const pdf_color *color1, const pdf_color *color2); - -extern int pdf_color_is_white (const pdf_color *color); -extern int pdf_color_is_valid (const pdf_color *color); - -extern int pdf_color_to_string (const pdf_color *color, char *buffer); - -/* Not check size */ -extern pdf_obj *iccp_get_rendering_intent (const void *profile, long proflen); -extern int iccp_check_colorspace (int colortype, - const void *profile, long proflen); - -/* returns colorspace ID */ -extern int iccp_load_profile (const char *ident, - const void *profile, long proflen); - -extern void pdf_init_colors (void); -extern void pdf_close_colors (void); - -extern pdf_obj *pdf_get_colorspace_reference (int cspc_id); -#if 0 -extern int pdf_get_colorspace_num_components (int cspc_id); -extern int pdf_get_colorspace_subtype (int cspc_id); -#endif - -#ifdef XETEX -/* Not working */ -extern int pdf_colorspace_load_ICCBased (const char *ident, - const char *profile_filename); -#endif - -/* Color special - * See remark in spc_color.c. - */ -#ifndef XETEX -extern void pdf_color_set (pdf_color *sc, pdf_color *fc); -#endif -extern void pdf_color_set_default (const pdf_color *color); -extern void pdf_color_push (pdf_color *sc, pdf_color *fc); -extern void pdf_color_pop (void); - -/* Color stack - */ -extern void pdf_color_clear_stack (void); -extern void pdf_color_get_current (pdf_color **sc, pdf_color **fc); - -#endif /* _PDF_COLOR_H_ */ diff --git a/Build/source/texk/dvipdfm-x/src/pdfdev.c b/Build/source/texk/dvipdfm-x/src/pdfdev.c index 9d560bd4c20..3a454d517a4 100644 --- a/Build/source/texk/dvipdfm-x/src/pdfdev.c +++ b/Build/source/texk/dvipdfm-x/src/pdfdev.c @@ -455,6 +455,12 @@ struct dev_font { */ int font_id; int enc_id; +#ifdef XETEX + unsigned short *ft_to_gid; + + /* if >= 0, index of a dev_font that really has the resource and used_chars */ + int real_font_index; +#endif pdf_obj *resource; char *used_chars; @@ -945,6 +951,26 @@ handle_multibyte_string (struct dev_font *font, p = *str_ptr; length = *str_len; +#ifdef XETEX + if (ctype == -1) { /* freetype glyph indexes */ + if (font->ft_to_gid) { + /* convert freetype glyph indexes to physical GID */ + const unsigned char *inbuf = p; + unsigned char *outbuf = sbuf0; + for (i = 0; i < length; i += 2) { + unsigned int gid; + gid = *inbuf++ << 8; + gid += *inbuf++; + gid = font->ft_to_gid[gid]; + *outbuf++ = gid >> 8; + *outbuf++ = gid & 0xff; + } + p = sbuf0; + length = outbuf - sbuf0; + } + } + else +#endif /* _FIXME_ */ if (font->is_unicode) { /* UCS-4 */ if (ctype == 1) { @@ -1069,6 +1095,9 @@ void pdf_dev_pop_coord(void) /* * ctype: +#ifdef XETEX + * -1 input string contains 2-byte Freetype glyph index values +#endif * 0 byte-width of char can be variable and input string * is properly encoded. * n Single character cosumes n bytes in input string. @@ -1463,6 +1492,9 @@ pdf_dev_locate_font (const char *font_name, spt_t ptsize) font->wmode = pdf_get_font_wmode (font->font_id); font->enc_id = pdf_get_font_encoding(font->font_id); +#ifdef XETEX + font->ft_to_gid = pdf_get_font_ft_to_gid(font->font_id); +#endif font->resource = NULL; /* Don't ref obj until font is actually used. */ font->used_chars = NULL; diff --git a/Build/source/texk/dvipdfm-x/src/pdfdev.h b/Build/source/texk/dvipdfm-x/src/pdfdev.h index 705e603e114..6b3d5bb65e8 100644 --- a/Build/source/texk/dvipdfm-x/src/pdfdev.h +++ b/Build/source/texk/dvipdfm-x/src/pdfdev.h @@ -158,7 +158,7 @@ extern int pdf_dev_setfont (const char *font_name, spt_t ptsize); /* The following two routines are NOT WORKING. * Dvipdfmx doesn't manage gstate well.. */ -#if 0 +#ifdef XETEX /* pdf_dev_translate() or pdf_dev_concat() should be used. */ extern void pdf_dev_set_origin (double orig_x, double orig_y); #endif diff --git a/Build/source/texk/dvipdfm-x/src/pdfparse.c b/Build/source/texk/dvipdfm-x/src/pdfparse.c deleted file mode 100644 index c05d37ed454..00000000000 --- a/Build/source/texk/dvipdfm-x/src/pdfparse.c +++ /dev/null @@ -1,1044 +0,0 @@ -/* - - This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. - - Copyright (C) 2002-2012 by Jin-Hwan Cho and Shunsaku Hirata, - the dvipdfmx project team. - - Copyright (C) 1998, 1999 by Mark A. Wicks <mwicks@kettering.edu> - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. -*/ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <ctype.h> -#include <string.h> - -#include "system.h" -#include "mem.h" -#include "error.h" - -#include "numbers.h" - -#include "mfileio.h" - -#include "pdfobj.h" -#include "pdfdoc.h" -#include "pdfdev.h" - -#include "pdfparse.h" - -/* PDF */ -#ifdef is_space -#undef is_space -#endif -#ifdef is_delim -#undef is_delim -#endif - -#define is_space(c) ((c) == ' ' || (c) == '\t' || (c) == '\f' || \ - (c) == '\r' || (c) == '\n' || (c) == '\0') -#define is_delim(c) ((c) == '(' || (c) == '/' || \ - (c) == '<' || (c) == '>' || \ - (c) == '[' || (c) == ']' || \ - (c) == '%') -#define PDF_TOKEN_END(p,e) ((p) >= (e) || is_space(*(p)) || is_delim(*(p))) - -#define istokensep(c) (is_space((c)) || is_delim((c))) - -static struct { - int tainted; -} parser_state = { - 0 -}; - -static int xtoi (char ch); - -static const char *save = NULL; - -void -dump (const char *start, const char *end) -{ - const char *p = start; - -#define DUMP_LIMIT 50 - MESG("\nCurrent input buffer is -->"); - while (p < end && p < start + DUMP_LIMIT) - MESG("%c", *(p++)); - if (p == start+DUMP_LIMIT) - MESG("..."); - MESG("<--\n"); -} - -#define SAVE(s,e) do {\ - save = (s);\ - } while (0) -#define DUMP_RESTORE(s,e) do {\ - dump(save, end);\ - (s) = save;\ - } while (0) - -void -skip_line (const char **start, const char *end) -{ - while (*start < end && **start != '\n' && **start != '\r') - (*start)++; - /* The carriage return (CR; \r; 0x0D) and line feed (LF; \n; 0x0A) - * characters, also called newline characters, are treated as - * end-of-line (EOL) markers. The combination of a carriage return - * followed immediately by a line feed is treated as one EOL marker. - */ - if (*start < end && **start == '\r') - (*start)++; - if (*start < end && **start == '\n') - (*start)++; -} - -void -skip_white (const char **start, const char *end) -{ - /* - * The null (NUL; 0x00) character is a white-space character in PDF spec - * but isspace(0x00) returns FALSE; on the other hand, the vertical tab - * (VT; 0x0B) character is not a white-space character in PDF spec but - * isspace(0x0B) returns TRUE. - */ - while (*start < end && (is_space(**start) || **start == '%')) { - if (**start == '%') - skip_line(start, end); - else - (*start)++; - } -} - - -static char * -parsed_string (const char *start, const char *end) -{ - char *result = NULL; - int len; - - len = end - start; - if (len > 0) { - result = NEW(len + 1, char); - memcpy(result, start, len); - result[len] = '\0'; - } - - return result; -} - -char * -parse_number (const char **start, const char *end) -{ - char *number; - const char *p; - - skip_white(start, end); - p = *start; - if (p < end && (*p == '+' || *p == '-')) - p++; - while (p < end && isdigit(*p)) - p++; - if (p < end && *p == '.') { - p++; - while (p < end && isdigit(*p)) - p++; - } - number = parsed_string(*start, p); - - *start = p; - return number; -} - -char * -parse_unsigned (const char **start, const char *end) -{ - char *number; - const char *p; - - skip_white(start, end); - for (p = *start; p < end; p++) { - if (!isdigit(*p)) - break; - } - number = parsed_string(*start, p); - - *start = p; - return number; -} - -static char * -parse_gen_ident (const char **start, const char *end, const char *valid_chars) -{ - char *ident; - const char *p; - - /* No skip_white(start, end)? */ - for (p = *start; p < end; p++) { - if (!strchr(valid_chars, *p)) - break; - } - ident = parsed_string(*start, p); - - *start = p; - return ident; -} - -char * -parse_ident (const char **start, const char *end) -{ - static const char *valid_chars = - "!\"#$&'*+,-.0123456789:;=?@ABCDEFGHIJKLMNOPQRSTUVWXYZ\\^_`abcdefghijklmnopqrstuvwxyz|~"; - - return parse_gen_ident(start, end, valid_chars); -} - -char * -parse_val_ident (const char **start, const char *end) -{ - static const char *valid_chars = - "!\"#$&'*+,-./0123456789:;?@ABCDEFGHIJKLMNOPQRSTUVWXYZ\\^_`abcdefghijklmnopqrstuvwxyz|~"; - - return parse_gen_ident(start, end, valid_chars); -} - -char * -parse_opt_ident (const char **start, const char *end) -{ - if (*start < end && **start == '@') { - (*start)++; - return parse_ident(start, end); - } - - return NULL; -} - -#define DDIGITS_MAX 10 -pdf_obj * -parse_pdf_number (const char **pp, const char *endptr) -{ - const char *p; - unsigned long ipart = 0, dpart = 0; - int nddigits = 0, sign = 1; - int has_dot = 0; - static double ipot[DDIGITS_MAX+1] = { - 1.0, - 0.1, - 0.01, - 0.001, - 0.0001, - 0.00001, - 0.000001, - 0.0000001, - 0.00000001, - 0.000000001, - 0.0000000001 - }; - - p = *pp; - skip_white(&p, endptr); - if (p >= endptr || - (!isdigit(p[0]) && p[0] != '.' && - p[0] != '+' && p[0] != '-')) { - WARN("Could not find a numeric object."); - return NULL; - } - - if (p[0] == '-') { - if (p + 1 >= endptr) { - WARN("Could not find a numeric object."); - return NULL; - } - sign = -1; - p++; - } else if (p[0] == '+') { - if (p + 1 >= endptr) { - WARN("Could not find a numeric object."); - return NULL; - } - sign = 1; - p++; - } - - while (p < endptr && !istokensep(p[0])) { - if (p[0] == '.') { - if (has_dot) { /* Two dots */ - WARN("Could not find a numeric object."); - return NULL; - } else { - has_dot = 1; - } - } else if (isdigit(p[0])) { - if (has_dot) { - if (nddigits == DDIGITS_MAX && pdf_obj_get_verbose() > 1) { - WARN("Number with more than %d fractional digits.", DDIGITS_MAX); - } else if (nddigits < DDIGITS_MAX) { - dpart = dpart * 10 + p[0] - '0'; - nddigits++; - } /* Ignore decimal digits more than DDIGITS_MAX */ - } else { - ipart = ipart * 10 + p[0] - '0'; - } - } else { - WARN("Could not find a numeric object."); - return NULL; - } - p++; - } - - *pp = p; - return pdf_new_number((double) sign * (((double ) ipart) + dpart * ipot[nddigits])); -} - -/* - * PDF Name: - * - * PDF-1.2+: Two hexadecimal digits preceded by a number sign. - */ -static int -pn_getc (const char **pp, const char *endptr) -{ - int ch = 0; - const char *p; - - p = *pp; - if (p[0] == '#') { - if (p + 2 >= endptr) { - *pp = endptr; - return -1; - } - if (!isxdigit(p[1]) || !isxdigit(p[2])) { - *pp += 3; - return -1; - } - ch = (xtoi(p[1]) << 4); - ch += xtoi(p[2]); - *pp += 3; - } else { - ch = p[0]; - *pp += 1; - } - - return ch; -} - -#ifndef PDF_NAME_LEN_MAX -#define PDF_NAME_LEN_MAX 128 -#endif - -#ifndef PDF_STRING_LEN_MAX -#define PDF_STRING_LEN_MAX 65535 -#endif - -#define STRING_BUFFER_SIZE PDF_STRING_LEN_MAX+1 -static char sbuf[PDF_STRING_LEN_MAX+1]; - - -pdf_obj * -parse_pdf_name (const char **pp, const char *endptr) -{ - char name[PDF_NAME_LEN_MAX+1]; - int ch, len = 0; - - skip_white(pp, endptr); - if (*pp >= endptr || **pp != '/') { - WARN("Could not find a name object."); - return NULL; - } - - (*pp)++; - while (*pp < endptr && !istokensep(**pp)) { - ch = pn_getc(pp, endptr); - if (ch < 0 || ch > 0xff) { - WARN("Invalid char in PDF name object. (ignored)"); - } else if (ch == 0) { - WARN("Null char not allowed in PDF name object. (ignored)"); - } else if (len < STRING_BUFFER_SIZE) { - if (len == PDF_NAME_LEN_MAX) { - WARN("PDF name length too long. (>= %d bytes)", PDF_NAME_LEN_MAX); - } - name[len++] = ch; - } else { - WARN("PDF name length too long. (>= %d bytes, truncated)", - STRING_BUFFER_SIZE); - } - } - if (len < 1) { - WARN("No valid name object found."); - return NULL; - } - name[len] = '\0'; - - return pdf_new_name(name); -} - -pdf_obj * -parse_pdf_boolean (const char **pp, const char *endptr) -{ - skip_white(pp, endptr); - if (*pp + 4 <= endptr && - !strncmp(*pp, "true", 4)) { - if (*pp + 4 == endptr || - istokensep(*(*pp + 4))) { - *pp += 4; - return pdf_new_boolean(1); - } - } else if (*pp + 5 <= endptr && - !strncmp(*pp, "false", 5)) { - if (*pp + 5 == endptr || - istokensep(*(*pp + 5))) { - *pp += 5; - return pdf_new_boolean(0); - } - } - - WARN("Not a boolean object."); - - return NULL; -} - -pdf_obj * -parse_pdf_null (const char **pp, const char *endptr) -{ - skip_white(pp, endptr); - if (*pp + 4 > endptr) { - WARN("Not a null object."); - return NULL; - } else if (*pp + 4 < endptr && - !istokensep(*(*pp+4))) { - WARN("Not a null object."); - return NULL; - } else if (!strncmp(*pp, "null", 4)) { - *pp += 4; - return pdf_new_null(); - } - - WARN("Not a null object."); - - return NULL; -} - -/* - * PDF Literal String - */ -#ifndef isodigit -#define isodigit(c) ((c) >= '0' && (c) <= '7') -#endif -static int -ps_getescc (const char **pp, const char *endptr) -{ - int ch, i; - const char *p; - - p = *pp + 1; /* backslash assumed. */ - switch (p[0]) { - case 'n': ch = '\n'; p++; break; - case 'r': ch = '\r'; p++; break; - case 't': ch = '\t'; p++; break; - case 'b': ch = '\b'; p++; break; - case 'f': ch = '\f'; p++; break; - - /* - * An end-of-line marker preceded by a backslash must be ignored. - */ - case '\n': - ch = -1; - p++; - break; - case '\r': - ch = -1; - p++; - if (p < endptr && p[0] == '\n') - p++; - break; - default: - if (p[0] == '\\' || - p[0] == '(' || p[0] == ')') { - ch = p[0]; - p++; - } else if (isodigit(p[0])) { - ch = 0; - /* Don't forget isodigit() is a macro. */ - for (i = 0; i < 3 && - p < endptr && isodigit(p[0]); i++) { - ch = (ch << 3) + (p[0] - '0'); - p++; - } - ch = (ch & 0xff); /* Ignore overflow. */ - } else { - ch = ((unsigned char) p[0]); /* Ignore only backslash. */ - p++; - } - } - - *pp = p; - return ch; -} - -static pdf_obj * -parse_pdf_literal_string (const char **pp, const char *endptr) -{ - int ch, op_count = 0, len = 0; - const char *p; - - p = *pp; - - skip_white(&p, endptr); - - if (p >= endptr || p[0] != '(') - return NULL; - - p++; - - /* The carriage return (CR, 0x0d) and line feed (LF, 0x0a) characters, - * also called newline characters, are treated as end-of-line (EOL) - * markers. The combination of a carriage return followed immediately - * by a line feed is treated as one EOL marker. - * [PDF Reference, 6th ed., version 1.7, p. 50] */ - - /* If an end-of-line marker appears within a literal string - * without a preceding backslash, the result is equivalent to - * \n (regardless of whether the end-of-line marker was - * a carriage return, a line feed, or both). - * [PDF Reference, 6th ed., version 1.7, p. 55] */ - - while (p < endptr) { - - ch = p[0]; - - if (ch == ')' && op_count < 1) - break; - -#ifndef PDF_PARSE_STRICT - if (parser_state.tainted) { - if (p + 1 < endptr && (ch & 0x80)) { - if (len + 2 >= PDF_STRING_LEN_MAX) { - WARN("PDF string length too long. (limit: %ld)", - PDF_STRING_LEN_MAX); - return NULL; - } - sbuf[len++] = p[0]; - sbuf[len++] = p[1]; - p += 2; - continue; - } - } -#endif /* !PDF_PARSE_STRICT */ - - if (len + 1 >= PDF_STRING_LEN_MAX) { - WARN("PDF string length too long. (limit: %ld)", - PDF_STRING_LEN_MAX); - return NULL; - } - - switch (ch) { - case '\\': - ch = ps_getescc(&p, endptr); - if (ch >= 0) - sbuf[len++] = (ch & 0xff); - break; - case '\r': - p++; - if (p < endptr && p[0] == '\n') - p++; - sbuf[len++] = '\n'; - break; - default: - if (ch == '(') - op_count++; - else if (ch == ')') - op_count--; - sbuf[len++] = ch; - p++; - break; - } - } - - if (op_count > 0 || - p >= endptr || p[0] != ')') { - WARN("Unbalanced parens/truncated PDF literal string."); - return NULL; - } - - *pp = p + 1; - return pdf_new_string(sbuf, len); -} - -/* - * PDF Hex String - */ -static int -xtoi (char ch) -{ - if (ch >= '0' && ch <= '9') - return ch - '0'; - if (ch >= 'A' && ch <= 'F') - return (ch - 'A') + 10; - if (ch >= 'a' && ch <= 'f') - return (ch - 'a') + 10; - - return -1; -} - -static pdf_obj * -parse_pdf_hex_string (const char **pp, const char *endptr) -{ - const char *p; - long len; - - p = *pp; - - skip_white(&p, endptr); - if (p >= endptr || p[0] != '<') - return NULL; - - p++; - - len = 0; - /* - * PDF Reference does not describe how to treat invalid char. - * Zero is appended if final hex digit is missing. - */ - while (p < endptr && p[0] != '>' && len < PDF_STRING_LEN_MAX) { - int ch; - - skip_white(&p, endptr); - if (p >= endptr || p[0] == '>') - break; - - ch = (xtoi(p[0]) << 4); - p++; - - skip_white(&p, endptr); - if (p < endptr && p[0] != '>') { - ch += xtoi(p[0]); - p++; - } - sbuf[len++] = (ch & 0xff); - } - - if (p >= endptr) { - WARN("Premature end of input hex string."); - return NULL; - } else if (p[0] != '>') { - WARN("PDF string length too long. (limit: %ld)", PDF_STRING_LEN_MAX); - return NULL; - } - - *pp = p + 1; - return pdf_new_string(sbuf, len); -} - -pdf_obj * -parse_pdf_string (const char **pp, const char *endptr) -{ - skip_white(pp, endptr); - if (*pp + 2 <= endptr) { - if (**pp == '(') - return parse_pdf_literal_string(pp, endptr); - else if (**pp == '<' && - (*(*pp + 1) == '>' || isxdigit(*(*pp + 1)))) { - return parse_pdf_hex_string(pp, endptr); - } - } - - WARN("Could not find a string object."); - - return NULL; -} - -#ifndef PDF_PARSE_STRICT -pdf_obj * -parse_pdf_tainted_dict (const char **pp, const char *endptr) -{ - pdf_obj *result; - - parser_state.tainted = 1; - result = parse_pdf_dict(pp, endptr, NULL); - parser_state.tainted = 0; - - return result; -} -#else /* PDF_PARSE_STRICT */ -pdf_obj * -parse_pdf_tainted_dict (const char **pp, const char *endptr) -{ - return parse_pdf_dict(pp, endptr, NULL); -} -#endif /* !PDF_PARSE_STRICT */ - -pdf_obj * -parse_pdf_dict (const char **pp, const char *endptr, pdf_file *pf) -{ - pdf_obj *result = NULL; - const char *p; - - p = *pp; - - skip_white(&p, endptr); - - /* At least four letter <<>>. */ - if (p + 4 > endptr || - p[0] != '<' || p[1] != '<') { - return NULL; - } - p += 2; - - result = pdf_new_dict(); - - skip_white(&p, endptr); - while (p < endptr && p[0] != '>') { - pdf_obj *key, *value; - - skip_white(&p, endptr); - key = parse_pdf_name(&p, endptr); - if (!key) { - WARN("Could not find a key in dictionary object."); - pdf_release_obj(result); - return NULL; - } - - skip_white(&p, endptr); - - value = parse_pdf_object(&p, endptr, pf); - if (!value) { - pdf_release_obj(key); - pdf_release_obj(value); - pdf_release_obj(result); - WARN("Could not find a value in dictionary object."); - return NULL; - } - pdf_add_dict(result, key, value); - - skip_white(&p, endptr); - } - - if (p + 2 > endptr || - p[0] != '>' || p[1] != '>') { - WARN("Syntax error: Dictionary object ended prematurely."); - pdf_release_obj(result); - return NULL; - } - - *pp = p + 2; /* skip >> */ - return result; -} - -pdf_obj * -parse_pdf_array (const char **pp, const char *endptr, pdf_file *pf) -{ - pdf_obj *result; - const char *p; - - p = *pp; - - skip_white(&p, endptr); - if (p + 2 > endptr || p[0] != '[') { - WARN("Could not find an array object."); - return NULL; - } - - result = pdf_new_array(); - - p++; - skip_white(&p, endptr); - - while (p < endptr && p[0] != ']') { - pdf_obj *elem; - - elem = parse_pdf_object(&p, endptr, pf); - if (!elem) { - pdf_release_obj(result); - WARN("Could not find a valid object in array object."); - return NULL; - } - pdf_add_array(result, elem); - - skip_white(&p, endptr); - } - - if (p >= endptr || p[0] != ']') { - WARN("Array object ended prematurely."); - pdf_release_obj(result); - return NULL; - } - - *pp = p + 1; /* skip ] */ - return result; -} - -static pdf_obj * -parse_pdf_stream (const char **pp, const char *endptr, pdf_obj *dict, pdf_file *pf) -{ - pdf_obj *result = NULL; - const char *p; - pdf_obj *stream_dict; - long stream_length; - - p = *pp; - skip_white(&p, endptr); - if (p + 6 > endptr || - strncmp(p, "stream", 6)) { - return NULL; - } - p += 6; - - /* The keyword stream that follows the stream dictionary - * should be followed by an end-of-line marker consisting of - * either a carriage return (0x0D;\r) and a line feed (0x0A;\n) - * or just a line feed, and not by a carriage return alone. - * [PDF Reference, 6th ed., version 1.7, pp. 60-61] */ - - /* Notice that TeX translates an end-of-line marker to a single space. */ - if (p < endptr && p[0] == '\n') { - p++; - } else if (p + 1 < endptr && - (p[0] == '\r' && p[1] == '\n')) { - p += 2; - } - - /* Stream length */ - { - pdf_obj *tmp, *tmp2; - - tmp = pdf_lookup_dict(dict, "Length"); - - if (tmp != NULL) { - tmp2 = pdf_deref_obj(tmp); - if (pdf_obj_typeof(tmp2) != PDF_NUMBER) - stream_length = -1; - else { - stream_length = (long) pdf_number_value(tmp2); - } - pdf_release_obj(tmp2); - } - else { - return NULL; - } - } - - - if (stream_length < 0 || - p + stream_length > endptr) - return NULL; - - /* - * If Filter is not applied, set STREAM_COMPRESS flag. - * Should we use filter for ASCIIHexEncode/ASCII85Encode-ed streams? - */ - { - pdf_obj *filters; - - filters = pdf_lookup_dict(dict, "Filter"); - if (!filters && stream_length > 10) { - result = pdf_new_stream(STREAM_COMPRESS); - } else { - result = pdf_new_stream(0); - } - } - - stream_dict = pdf_stream_dict(result); - pdf_merge_dict(stream_dict, dict); - - pdf_add_stream(result, p, stream_length); - p += stream_length; - - /* Check "endsteam" */ - { - /* It is recommended that there be an end-of-line marker - * after the data and before endstream; this marker is not included - * in the stream length. - * [PDF Reference, 6th ed., version 1.7, pp. 61] */ - if (p < endptr && p[0] == '\r') - p++; - if (p < endptr && p[0] == '\n') - p++; - - if (p + 9 > endptr || - memcmp(p, "endstream", 9)) { - pdf_release_obj(result); - return NULL; - } - p += 9; - } - - *pp = p; - return result; -} - -#ifndef PDF_PARSE_STRICT - -/* PLEASE REMOVE THIS */ -#include "specials.h" - -/* This is not PDF indirect reference. */ -static pdf_obj * -parse_pdf_reference (const char **start, const char *end) -{ - pdf_obj *result = NULL; - char *name; - - SAVE(*start, end); - - skip_white(start, end); - name = parse_opt_ident(start, end); - if (name) { - result = spc_lookup_reference(name); - if (!result) { - WARN("Could not find the named reference (@%s).", name); - DUMP_RESTORE(*start, end); - } - RELEASE(name); - } else { - WARN("Could not find a reference name."); - DUMP_RESTORE(*start, end); - result = NULL; - } - - return result; -} -#endif /* !PDF_PARSE_STRICT */ - -static pdf_obj * -try_pdf_reference (const char *start, const char *end, const char **endptr, pdf_file *pf) -{ - unsigned long id = 0; - unsigned short gen = 0; - - ASSERT(pf); - - if (endptr) - *endptr = start; - - skip_white(&start, end); - if (start > end - 5 || !isdigit(*start)) { - return NULL; - } - while (!is_space(*start)) { - if (start >= end || !isdigit(*start)) { - return NULL; - } - id = id * 10 + (*start - '0'); - start++; - } - - skip_white(&start, end); - if (start >= end || !isdigit(*start)) - return NULL; - while (!is_space(*start)) { - if (start >= end || !isdigit(*start)) - return NULL; - gen = gen * 10 + (*start - '0'); - start++; - } - - skip_white(&start, end); - if (start >= end || *start != 'R') - return NULL; - start++; - if (!PDF_TOKEN_END(start, end)) - return NULL; - - if (endptr) - *endptr = start; - - return pdf_new_indirect(pf, id, gen); -} - -pdf_obj * -parse_pdf_object (const char **pp, const char *endptr, pdf_file *pf) -/* If pf is NULL, then indirect references are not allowed */ -{ - pdf_obj *result = NULL; - const char *nextptr; - - skip_white(pp, endptr); - if (*pp >= endptr) { - WARN("Could not find any valid object."); - return NULL; - } - - switch (**pp) { - - case '<': - - if (*(*pp + 1) != '<') { - result = parse_pdf_hex_string(pp, endptr); - } else { - pdf_obj *dict; - - result = parse_pdf_dict(pp, endptr, pf); - skip_white(pp, endptr); - if ( result && - *pp <= endptr - 15 && - !memcmp(*pp, "stream", 6)) { - dict = result; - result = parse_pdf_stream(pp, endptr, dict, pf); - pdf_release_obj(dict); - } - } - - break; - case '(': - result = parse_pdf_string(pp, endptr); - break; - case '[': - result = parse_pdf_array(pp, endptr, pf); - break; - case '/': - result = parse_pdf_name(pp, endptr); - break; - case 'n': - result = parse_pdf_null(pp, endptr); - break; - case 't': case 'f': - result = parse_pdf_boolean(pp, endptr); - break; - case '+': case '-': case '.': - result = parse_pdf_number(pp, endptr); - break; - case '0': case '1': case '2': case '3': case '4': - case '5': case '6': case '7': case '8': case '9': - - /* - * If pf != NULL, then we are parsing a PDF file, - * and indirect references are allowed. - */ - if (pf && (result = try_pdf_reference(*pp, endptr, &nextptr, pf))) { - *pp = nextptr; - } else { - result = parse_pdf_number(pp, endptr); - } - break; - - case '@': - -#ifndef PDF_PARSE_STRICT - result = parse_pdf_reference(pp, endptr); -#endif /* !PDF_PARSE_STRICT */ - break; - - default: - WARN("Unknown PDF object type."); - result = NULL; - } - - return result; -} - diff --git a/Build/source/texk/dvipdfm-x/src/pdfximage.c b/Build/source/texk/dvipdfm-x/src/pdfximage.c index 5dad655a97a..54f59531389 100644 --- a/Build/source/texk/dvipdfm-x/src/pdfximage.c +++ b/Build/source/texk/dvipdfm-x/src/pdfximage.c @@ -82,7 +82,7 @@ struct pdf_ximage_ pdf_obj *resource; pdf_obj *attr_dict; - char tempfile; + char tempfile; }; @@ -210,7 +210,6 @@ pdf_close_images (void) _opts.cmdtmpl = NULL; } - static int source_image_type (FILE *fp) { @@ -912,6 +911,9 @@ ps_include_page (pdf_ximage *ximage) return -1; } pdf_set_ximage_tempfile(ximage, temp); +#if 0 + error = pdf_include_page(ximage, fp, 0, pdfbox_crop); +#endif error = pdf_include_page(ximage, fp, temp); MFCLOSE(fp); diff --git a/Build/source/texk/dvipdfm-x/src/pdfximage.h b/Build/source/texk/dvipdfm-x/src/pdfximage.h deleted file mode 100644 index a919742594d..00000000000 --- a/Build/source/texk/dvipdfm-x/src/pdfximage.h +++ /dev/null @@ -1,94 +0,0 @@ -/* - - This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. - - Copyright (C) 2007-2012 by Jin-Hwan Cho and Shunsaku Hirata, - the dvipdfmx project team. - - Copyright (C) 1998, 1999 by Mark A. Wicks <mwicks@kettering.edu> - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. -*/ - -#ifndef _PDFXIMAGE_H_ -#define _PDFXIMAGE_H_ - -#include "pdfdev.h" - -#define PDF_XOBJECT_TYPE_FORM 0 -#define PDF_XOBJECT_TYPE_IMAGE 1 - -typedef struct { - int flags; - - long width; - long height; - - int bits_per_component; - int num_components; - - long min_dpi; /* NOT USED YET */ - - double xdensity, ydensity; /* scale factor for bp */ -} ximage_info; - -typedef struct { - int flags; - - pdf_rect bbox; - pdf_tmatrix matrix; -} xform_info; - -typedef struct pdf_ximage_ pdf_ximage; - -extern void pdf_ximage_set_verbose (void); - -extern void pdf_init_images (void); -extern void pdf_close_images (void); - -extern char *pdf_ximage_get_resname (int xobj_id); -extern int pdf_ximage_get_subtype (int xobj_id); -extern pdf_obj *pdf_ximage_get_reference (int xobj_id); - - -extern int pdf_ximage_findresource (const char *ident, long page_no, - pdf_obj *dict); -extern int pdf_ximage_defineresource (const char *ident, int subtype, - void *cdata, pdf_obj *resource); - -/* Called by pngimage, jpegimage, epdf, mpost, etc. */ -extern void pdf_ximage_init_image_info (ximage_info *info); -extern void pdf_ximage_init_form_info (xform_info *info); -extern void pdf_ximage_set_image (pdf_ximage *ximage, void *info, pdf_obj *resource); -extern void pdf_ximage_set_form (pdf_ximage *ximage, void *info, pdf_obj *resource); -extern long pdf_ximage_get_page (pdf_ximage *I); - -/* from psimage.h */ -extern void set_distiller_template (char *s); - -extern int -pdf_ximage_scale_image (int id, - pdf_tmatrix *M, /* ret */ - pdf_rect *r, /* ret */ - transform_info *p /* arg */ - ); - -/* from dvipdfmx.c */ -extern void pdf_ximage_disable_ebb (void); - -/* from spc_pdfm.c */ -extern int pdf_ximage_get_subtype (int xobj_id); -extern void pdf_ximage_set_attr (int xobj_id, long width, long height, double xdensity, double ydensity, double llx, double lly, double urx, double ury); -#endif /* _PDFXIMAGE_H_ */ diff --git a/Build/source/texk/dvipdfm-x/src/sfnt.c b/Build/source/texk/dvipdfm-x/src/sfnt.c deleted file mode 100644 index 47627b9f501..00000000000 --- a/Build/source/texk/dvipdfm-x/src/sfnt.c +++ /dev/null @@ -1,529 +0,0 @@ -/* - - This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. - - Copyright (C) 2002-2012 by Jin-Hwan Cho and Shunsaku Hirata, - the dvipdfmx project team. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. -*/ - -/* Based on dvipdfmx-0.13.2c */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <string.h> - -#include "system.h" - -#include "error.h" -#include "mem.h" -#include "mfileio.h" - -#include "sfnt.h" - - -sfnt * -sfnt_open (FILE *fp) -{ - sfnt *sfont; - ULONG type; - - ASSERT(fp); - - rewind(fp); - - sfont = NEW(1, sfnt); - - sfont->stream = fp; - -/* - * type: - * `true' (0x74727565): TrueType (Mac) - * `typ1' (0x74797031) (Mac): PostScript font housed in a sfnt wrapper - * 0x00010000: TrueType (Win)/OpenType - * `OTTO': PostScript CFF font with OpenType wrapper - * `ttcf': TrueType Collection -*/ -#define SFNT_TRUETYPE 0x00010000UL -#define SFNT_OPENTYPE 0x00010000UL -#define SFNT_POSTSCRIPT 0x4f54544fUL -#define SFNT_TTC 0x74746366UL - - type = sfnt_get_ulong(sfont); - - if (type == SFNT_TRUETYPE) { - sfont->type = SFNT_TYPE_TRUETYPE; - } else if (type == SFNT_OPENTYPE) { - sfont->type = SFNT_TYPE_OPENTYPE; - } else if (type == SFNT_POSTSCRIPT) { - sfont->type = SFNT_TYPE_POSTSCRIPT; - } else if (type == SFNT_TTC) { - sfont->type = SFNT_TYPE_TTC; - } - - rewind(sfont->stream); - - sfont->directory = NULL; - sfont->offset = 0UL; - - return sfont; -} - -sfnt * -dfont_open (FILE *fp, int index) -{ - sfnt *sfont; - ULONG rdata_pos, map_pos, tags_pos, types_pos, res_pos, tag; - USHORT tags_num, types_num, i; - - ASSERT(fp); - - rewind(fp); - - sfont = NEW(1, sfnt); - - sfont->stream = fp; - - rdata_pos = sfnt_get_ulong(sfont); - map_pos = sfnt_get_ulong(sfont); - sfnt_seek_set(sfont, map_pos + 0x18); - tags_pos = map_pos + sfnt_get_ushort(sfont); - sfnt_seek_set(sfont, tags_pos); - tags_num = sfnt_get_ushort(sfont); - - for (i = 0; i <= tags_num; i++) { - tag = sfnt_get_ulong(sfont); /* tag name */ - types_num = sfnt_get_ushort(sfont); /* typefaces number */ - types_pos = tags_pos + sfnt_get_ushort(sfont); /* typefaces position */ - if (tag == 0x73666e74UL) /* "sfnt" */ - break; - } - - if (i > tags_num) { - RELEASE(sfont); - return NULL; - } - - sfnt_seek_set(sfont, types_pos); - if (index > types_num) { - ERROR("Invalid index %d for dfont.", index); - } - - for (i = 0; i <= types_num; i++) { - (void) sfnt_get_ushort(sfont); /* resource id */ - (void) sfnt_get_ushort(sfont); /* resource name position from name_list */ - res_pos = sfnt_get_ulong(sfont); /* resource flag (byte) + resource offset */ - sfnt_get_ulong(sfont); /* mbz */ - if (i == index) break; - } - - rewind(sfont->stream); - - sfont->type = SFNT_TYPE_DFONT; - sfont->directory = NULL; - sfont->offset = (res_pos & 0x00ffffffUL) + rdata_pos + 4; - - return sfont; -} - -static void -release_directory (struct sfnt_table_directory *td) -{ - long i; - - if (td) { - if (td->tables) { - for (i = 0; i < td->num_tables; i++) { - if (td->tables[i].data) - RELEASE(td->tables[i].data); - } - RELEASE(td->tables); - } - if (td->flags) - RELEASE(td->flags); - RELEASE(td); - } - - return; -} - -void -sfnt_close (sfnt *sfont) -{ - - if (sfont) { - if (sfont->directory) - release_directory(sfont->directory); - RELEASE(sfont); - } - - return; -} - -int -put_big_endian (void *s, LONG q, int n) -{ - int i; - char *p; - - p = (char *) s; - for (i = n - 1; i >= 0; i--) { - p[i] = (char) (q & 0xff); - q >>= 8; - } - - return n; -} - -/* Convert four-byte number to big endianess - * in a machine independent way. - */ -static void -convert_tag (char *tag, unsigned long u_tag) -{ - int i; - - for (i = 3; i >= 0; i--) { - tag[i] = (char) (u_tag % 256); - u_tag /= 256; - } - - return; -} - -/* - * Computes the max power of 2 <= n - */ -static unsigned -max2floor (unsigned n) -{ - int val = 1; - - while (n > 1) { - n /= 2; - val *= 2; - } - - return val; -} - -/* - * Computes the log2 of the max power of 2 <= n - */ -static unsigned -log2floor (unsigned n) -{ - unsigned val = 0; - - while (n > 1) { - n /= 2; - val++; - } - - return val; -} - -static ULONG -sfnt_calc_checksum(void *data, ULONG length) -{ - ULONG chksum = 0; - BYTE *p, *endptr; - int count = 0; - - p = (BYTE *) data; - endptr = p + length; - while (p < endptr) { - chksum += (p[0] << (8 * ( 3 - count))); - count = ((count + 1) & 3); - p++; - } - - return chksum; -} - -static int -find_table_index (struct sfnt_table_directory *td, const char *tag) -{ - int idx; - - if (!td) - return -1; - - for (idx = 0; idx < td->num_tables; idx++) { - if (!memcmp(td->tables[idx].tag, tag, 4)) - return idx; - } - - return -1; -} - -void -sfnt_set_table (sfnt *sfont, const char *tag, void *data, ULONG length) -{ - struct sfnt_table_directory *td; - int idx; - - ASSERT(sfont); - - td = sfont->directory; - idx = find_table_index(td, tag); - - if (idx < 0) { - idx = td->num_tables; - td->num_tables++; - td->tables = RENEW(td->tables, td->num_tables, struct sfnt_table); - memcpy(td->tables[idx].tag, tag, 4); - } - - td->tables[idx].check_sum = sfnt_calc_checksum(data, length); - td->tables[idx].offset = 0L; - td->tables[idx].length = length; - td->tables[idx].data = data; - - return; -} - -ULONG -sfnt_find_table_len (sfnt *sfont, const char *tag) -{ - ULONG length; - struct sfnt_table_directory *td; - int idx; - - ASSERT(sfont && tag); - - td = sfont->directory; - idx = find_table_index(td, tag); - if (idx < 0) - length = 0; - else { - length = td->tables[idx].length; - } - - return length; -} - -ULONG -sfnt_find_table_pos (sfnt *sfont, const char *tag) -{ - ULONG offset; - struct sfnt_table_directory *td; - int idx; - - ASSERT(sfont && tag); - - td = sfont->directory; - idx = find_table_index(td, tag); - if (idx < 0) - offset = 0; - else { - offset = td->tables[idx].offset; - } - - return offset; -} - -ULONG -sfnt_locate_table (sfnt *sfont, const char *tag) -{ - ULONG offset; - - ASSERT(sfont && tag); - - offset = sfnt_find_table_pos(sfont, tag); - if (offset == 0) - ERROR("sfnt: table not found..."); - - sfnt_seek_set(sfont, offset); - - return offset; -} - -int -sfnt_read_table_directory (sfnt *sfont, ULONG offset) -{ - struct sfnt_table_directory *td; - unsigned long i, u_tag; - - ASSERT(sfont && sfont->stream); - - sfnt_seek_set(sfont, offset); - - if (sfont->directory) - release_directory(sfont->directory); - - sfont->directory = td = NEW (1, struct sfnt_table_directory); - - td->version = sfnt_get_ulong(sfont); - td->num_tables = sfnt_get_ushort(sfont); - td->search_range = sfnt_get_ushort(sfont); - td->entry_selector = sfnt_get_ushort(sfont); - td->range_shift = sfnt_get_ushort(sfont); - - td->flags = NEW(td->num_tables, char); - td->tables = NEW(td->num_tables, struct sfnt_table); - - for (i = 0; i < td->num_tables; i++) { - u_tag = sfnt_get_ulong(sfont); - - convert_tag(td->tables[i].tag, u_tag); - td->tables[i].check_sum = sfnt_get_ulong(sfont); - td->tables[i].offset = sfnt_get_ulong(sfont) + sfont->offset; - td->tables[i].length = sfnt_get_ulong(sfont); - td->tables[i].data = NULL; -//fprintf(stderr, "[%4s:%x]", td->tables[i].tag, td->tables[i].offset); - - td->flags[i] = 0; - } - td->num_kept_tables = 0; - - return 0; -} - -int -sfnt_require_table (sfnt *sfont, const char *tag, int must_exist) -{ - struct sfnt_table_directory *td; - int idx; - - ASSERT(sfont && sfont->directory); - - td = sfont->directory; - idx = find_table_index(td, tag); - if (idx < 0) { - if (must_exist) - return -1; - } else { - td->flags[idx] |= SFNT_TABLE_REQUIRED; - td->num_kept_tables++; - } - - return 0; -} - -#include "pdfobj.h" - -/* - * o All tables begin on four byte boundries, and pad any remaining space - * between tables with zeros - * - * o Entries in the Table Directory must be sorted in ascending order by tag - * - * o The head table contains checksum of the whole font file. - * To compute: first set it to 0, sum the entire font as ULONG, - * then store 0xB1B0AFBA - sum. - */ - -static unsigned char wbuf[1024], padbytes[4] = {0, 0, 0, 0}; - -pdf_obj * -sfnt_create_FontFile_stream (sfnt *sfont) -{ - pdf_obj *stream; - pdf_obj *stream_dict; - struct sfnt_table_directory *td; - long offset, nb_read, length; - int i, sr; - char *p; - - ASSERT(sfont && sfont->directory); - - stream = pdf_new_stream(STREAM_COMPRESS); - - td = sfont->directory; - - /* Header */ - p = (char *) wbuf; - p += sfnt_put_ulong (p, td->version); - p += sfnt_put_ushort(p, td->num_kept_tables); - sr = max2floor(td->num_kept_tables) * 16; - p += sfnt_put_ushort(p, sr); - p += sfnt_put_ushort(p, log2floor(td->num_kept_tables)); - p += sfnt_put_ushort(p, td->num_kept_tables * 16 - sr); - - pdf_add_stream(stream, wbuf, 12); - - /* - * Compute start of actual tables (after headers). - */ - offset = 12 + 16 * td->num_kept_tables; - for (i = 0; i < td->num_tables; i++) { - /* This table must exist in FontFile */ - if (td->flags[i] & SFNT_TABLE_REQUIRED) { - if ((offset % 4) != 0) { - offset += 4 - (offset % 4); - } - - p = (char *) wbuf; - memcpy(p, td->tables[i].tag, 4); - p += 4; - p += sfnt_put_ulong(p, td->tables[i].check_sum); - p += sfnt_put_ulong(p, offset); - p += sfnt_put_ulong(p, td->tables[i].length); - pdf_add_stream(stream, wbuf, 16); - - offset += td->tables[i].length; - } - } - - offset = 12 + 16 * td->num_kept_tables; - for (i = 0; i < td->num_tables; i++) { - if (td->flags[i] & SFNT_TABLE_REQUIRED) { - if ((offset % 4) != 0) { - length = 4 - (offset % 4); - pdf_add_stream(stream, padbytes, length); - offset += length; - } - if (!td->tables[i].data) { - if (!sfont->stream) { - pdf_release_obj(stream); - ERROR("Font file not opened or already closed..."); - return NULL; - } - - length = td->tables[i].length; - sfnt_seek_set(sfont, td->tables[i].offset); - while (length > 0) { - nb_read = sfnt_read(wbuf, MIN(length, 1024), sfont); - if (nb_read < 0) { - pdf_release_obj(stream); - ERROR("Reading file failed..."); - return NULL; - } else if (nb_read > 0) { - pdf_add_stream(stream, wbuf, nb_read); - } - length -= nb_read; - } - } else { - pdf_add_stream(stream, - td->tables[i].data, td->tables[i].length); - RELEASE(td->tables[i].data); - td->tables[i].data = NULL; - } - /* Set offset for next table */ - offset += td->tables[i].length; - } - } - - stream_dict = pdf_stream_dict(stream); - pdf_add_dict(stream_dict, - pdf_new_name("Length1"), - pdf_new_number(offset)); - - return stream; -} diff --git a/Build/source/texk/dvipdfm-x/src/tt_aux.c b/Build/source/texk/dvipdfm-x/src/tt_aux.c deleted file mode 100644 index ccbf4fd2528..00000000000 --- a/Build/source/texk/dvipdfm-x/src/tt_aux.c +++ /dev/null @@ -1,278 +0,0 @@ -/* - - This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. - - Copyright (C) 2002-2012 by Jin-Hwan Cho and Shunsaku Hirata, - the dvipdfmx project team. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. -*/ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include "system.h" -#include "mem.h" -#include "error.h" -#include "numbers.h" - -#include "pdfobj.h" - -#include "sfnt.h" -#include "tt_table.h" -#include "tt_post.h" -#include "tt_aux.h" - -ULONG ttc_read_offset (sfnt *sfont, int ttc_idx) -{ - ULONG offset = 0, num_dirs = 0; - - if (sfont == NULL || -#ifdef XETEX - sfont->ft_face == NULL -#else - sfont->stream == NULL -#endif - ) - ERROR("file not opened"); - - if (sfont->type != SFNT_TYPE_TTC) - ERROR("ttc_read_offset(): invalid font type"); - - sfnt_seek_set (sfont, 4); /* skip version tag */ - - /* version = */ sfnt_get_ulong(sfont); - num_dirs = sfnt_get_ulong(sfont); - if (ttc_idx < 0 || ttc_idx > num_dirs - 1) - ERROR("Invalid TTC index number"); - - sfnt_seek_set (sfont, 12 + ttc_idx * 4); - offset = sfnt_get_ulong (sfont); - - return offset; -} - -/* - Build FontDescriptor (except FontName) from TrueType tables: - - Most information found in FontDescriptor is used only when automatic - font substitution is needed. (in the case of missing/broken font data) - Some PDF viewers may ignore embedded TrueType glyph data. Especially, - any embedded TrueType data for CID-keyed (CIDFontType 2) font is ignored - by PDF viewers that only support PDF versions 1.2 or earlier. - - We use those tables to obtain various values of FontDescriptor. - - head: required - - xMin, xMax, yMin, yMax - FontBBox - unitsPerEm - conversion to PDF unit (points). see PDFUNIT bellow. - The head table must exist in any TrueType font. - - hhea: required - - When the OS/2 table (Windows and OS/2 only) is not available, - Ascender and Descender values can be used to estimate Ascent - and Descent. The hhea table is required for all TrueType fonts. - MaxWidth can be obtained from this table. - - OS/2: required for Windows and OS/2 TrueType, and OpenType - - fsType - liscensing information - sCapHeight - CapHeight (version 2 only) - - The sCapHeight is only available in newer TrueType fonts which has - version 2 OS/2 table and generally not available. Instead, we can - use height of uppercase letter `H'. But we don't use it, we simply - use Ascent value. - - sTypoAscender, sTypoDescender - Ascent and Descent - usWeightClass - roughly estimate StemV. - - Estimation is based on the following expression: - - stemv = (os2->usWeightClass/65)*(os2->usWeightClass/65)+50 - - . I've found this expression in some Adobe document (lost). We use - this expression also, otherwise, we must analyze glyph data. - - xAvgCharWidth - AvgWidth (optional) - sFamilyClass - Flags - sFamilyClass and panose - Panose in Style dictionary (optional) - - post: required - - italicAngle - ItalicAngle - -*/ - - -#ifndef PDFUNIT -#define PDFUNIT(v) (ROUND((1000.0*(v))/(head->unitsPerEm),1)) -#endif - -/* Flags: should not come here */ -#define FIXEDWIDTH (1 << 0) /* Fixed-width font */ -#define SERIF (1 << 1) /* Serif font */ -#define SYMBOLIC (1 << 2) /* Symbolic font */ -#define SCRIPT (1 << 3) /* Script font */ -#define STANDARD (1 << 5) /* Uses the Adobe Standard Character Set */ -#define ITALIC (1 << 6) /* Italic */ -#define ALLCAP (1 << 16) /* All-cap font */ -#define SMALLCAP (1 << 17) /* Small-cap font */ -#define FORCEBOLD (1 << 18) /* Force bold at small text sizes */ -pdf_obj *tt_get_fontdesc (sfnt *sfont, int *embed, int stemv, int type, const char* fontname) -{ - pdf_obj *descriptor = NULL; - pdf_obj *bbox = NULL; - int flag = SYMBOLIC; - /* TrueType tables */ - struct tt_head_table *head; - struct tt_os2__table *os2; - struct tt_post_table *post; - - if (!sfont) { - ERROR("font file not opened"); - } - - os2 = tt_read_os2__table(sfont); - head = tt_read_head_table(sfont); - post = tt_read_post_table(sfont); - if (!post) { - RELEASE(os2); - RELEASE(head); - return NULL; - } - - descriptor = pdf_new_dict(); - pdf_add_dict (descriptor, - pdf_new_name ("Type"), - pdf_new_name ("FontDescriptor")); - - if (*embed) { - /* - License: - - "Preview & Print embedding" (0x004) requires the document containing - Preview & Print font to be opened in read-only mode. However, licensing - information are lost when fonts are embedded in PDF document and - the only way to make the PDF document "read-only" is to encrypt it. - But we have no support for encryption yet. We do not embed any fonts - with "Preview & Print embedding" setting. - - 2001/11/22: Changed to allow `Preview & Print' only fonts embedding - */ - if (os2->fsType == 0x0000 || (os2->fsType & 0x0008)) { - /* the least restrictive license granted takes precedence. */ - *embed = 1; - } else if (os2->fsType & 0x0004) { - fprintf(stderr, - "\n** NOTICE: This document contains `Preview & Print' only"); - fprintf(stderr, " licensed font **\n"); - *embed = 1; - } else { - fprintf(stderr, - "\n*** Embedding disabled due to licensing restriction ***\n"); - *embed = 0; - } - } - - pdf_add_dict (descriptor, - pdf_new_name ("Ascent"), - pdf_new_number (PDFUNIT(os2->sTypoAscender))); - pdf_add_dict (descriptor, - pdf_new_name ("Descent"), - pdf_new_number (PDFUNIT(os2->sTypoDescender))); - if (stemv < 0) /* if not given by the option '-v' */ - stemv = (os2->usWeightClass/65.)*(os2->usWeightClass/65.)+50; - pdf_add_dict (descriptor, - pdf_new_name ("StemV"), - pdf_new_number (stemv)); - if (os2->version == 0x0002) { - pdf_add_dict (descriptor, - pdf_new_name("CapHeight"), - pdf_new_number(PDFUNIT(os2->sCapHeight)) - ); - /* optional */ - pdf_add_dict (descriptor, - pdf_new_name("XHeight"), - pdf_new_number(PDFUNIT(os2->sxHeight)) - ); - } else { /* arbitrary */ - pdf_add_dict (descriptor, - pdf_new_name("CapHeight"), - pdf_new_number(PDFUNIT(os2->sTypoAscender)) - ); - } - /* optional */ - if (os2->xAvgCharWidth != 0) { - pdf_add_dict (descriptor, - pdf_new_name ("AvgWidth"), - pdf_new_number (PDFUNIT(os2->xAvgCharWidth))); - } - - /* BoundingBox (array) */ - bbox = pdf_new_array (); - pdf_add_array (bbox, pdf_new_number (PDFUNIT(head->xMin))); - pdf_add_array (bbox, pdf_new_number (PDFUNIT(head->yMin))); - pdf_add_array (bbox, pdf_new_number (PDFUNIT(head->xMax))); - pdf_add_array (bbox, pdf_new_number (PDFUNIT(head->yMax))); - pdf_add_dict (descriptor, pdf_new_name ("FontBBox"), bbox); - - /* post */ - pdf_add_dict (descriptor, - pdf_new_name ("ItalicAngle"), - pdf_new_number(fixed(post->italicAngle))); - - /* Flags */ - if (os2->fsSelection & (1 << 0)) - flag |= ITALIC; - if (os2->fsSelection & (1 << 5)) - flag |= FORCEBOLD; - if (((os2->sFamilyClass >> 8) & 0xff) != 8) - flag |= SERIF; - if (((os2->sFamilyClass >> 8) & 0xff) == 10) - flag |= SCRIPT; - if (post->isFixedPitch) - flag |= FIXEDWIDTH; - - pdf_add_dict (descriptor, - pdf_new_name ("Flags"), - pdf_new_number (flag)); - - /* insert panose if you want */ - if (type == 0) { /* cid-keyed font - add panose */ - pdf_obj *styledict = NULL; - unsigned char panose[12]; - - panose[0] = os2->sFamilyClass >> 8; - panose[1] = os2->sFamilyClass & 0xff; - memcpy(panose+2, os2->panose, 10); - - styledict = pdf_new_dict (); - pdf_add_dict (styledict, pdf_new_name ("Panose"), - pdf_new_string (panose, 12)); - pdf_add_dict (descriptor, pdf_new_name ("Style"), styledict); - } - - RELEASE(head); - if (os2) - RELEASE(os2); - tt_release_post_table(post); - - return descriptor; -} - diff --git a/Build/source/texk/dvipdfm-x/src/tt_aux.h b/Build/source/texk/dvipdfm-x/src/tt_aux.h deleted file mode 100644 index 5f8cc5f03a0..00000000000 --- a/Build/source/texk/dvipdfm-x/src/tt_aux.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - - This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. - - Copyright (C) 2002-2012 by Jin-Hwan Cho and Shunsaku Hirata, - the dvipdfmx project team. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. -*/ - -#ifndef _TT_AUX_H_ -#define _TT_AUX_H_ - -#include "pdfobj.h" -#include "sfnt.h" - -/* TTC (TrueType Collection) */ -extern ULONG ttc_read_offset (sfnt *sfont, int ttc_idx); - -/* FontDescriptor */ -extern pdf_obj *tt_get_fontdesc (sfnt *sfont, int *embed, int stemv, int type, const char* fontname); - -#endif /* _TT_AUX_H_ */ diff --git a/Build/source/texk/dvipdfm-x/src/tt_post.c b/Build/source/texk/dvipdfm-x/src/tt_post.c deleted file mode 100644 index d95bb577f38..00000000000 --- a/Build/source/texk/dvipdfm-x/src/tt_post.c +++ /dev/null @@ -1,275 +0,0 @@ -/* - - This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. - - Copyright (C) 2002-2012 by Jin-Hwan Cho and Shunsaku Hirata, - the dvipdfmx project team. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. -*/ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include "system.h" -#include "error.h" -#include "mem.h" - -#include "dpxfile.h" - -#include "sfnt.h" - -#include "tt_post.h" - -static const char *macglyphorder[258]; - -/* offset from begenning of the post table */ -#define NAME_STR_OFFSET 32 - -static int -read_v2_post_names (struct tt_post_table *post, sfnt *sfont) -{ - USHORT i, idx, *indices, maxidx; - int len; - - post->numberOfGlyphs = sfnt_get_ushort(sfont); - - indices = NEW(post->numberOfGlyphs, USHORT); - maxidx = 257; - for (i = 0; - i < post->numberOfGlyphs; i++) { - idx = sfnt_get_ushort(sfont); - if (idx >= 258) { - if (idx > maxidx) - maxidx = idx; - if (idx > 32767) { - /* Although this is strictly speaking out of spec, it seems to work - and there are real-life fonts that use it. - We show a warning only once, instead of thousands of times */ - static char warning_issued = 0; - if (!warning_issued) { - WARN("TrueType post table name index %u > 32767", idx); - warning_issued = 1; - } - /* In a real-life large font, (x)dvipdfmx crashes if we use - nonvanishing idx in the case of idx > 32767. - If we set idx = 0, (x)dvipdfmx works fine for the font and - created pdf seems fine. The post table may not be important - in such a case */ - idx = 0; - } - } - indices[i] = idx; - } - - post->count = maxidx - 257; - if (post->count < 1) { - post->names = NULL; - } else { - post->names = NEW(post->count, char *); - for (i = 0; i < post->count; i++) { /* read Pascal strings */ - len = sfnt_get_byte(sfont); - if (len > 0) { - post->names[i] = NEW(len + 1, char); - sfnt_read(post->names[i], len, sfont); - post->names[i][len] = 0; - } else { - post->names[i] = NULL; - } - } - } - - post->glyphNamePtr = NEW(post->numberOfGlyphs, const char *); - for (i = 0; i < post->numberOfGlyphs; i++) { - idx = indices[i]; - if (idx < 258) { - post->glyphNamePtr[i] = macglyphorder[idx]; - } else if (idx - 258 < post->count) { - post->glyphNamePtr[i] = post->names[idx - 258]; - } else { - WARN("Invalid glyph name index number: %u (>= %u)", - idx, post->count + 258); - RELEASE(indices); - return -1; - } - } - RELEASE(indices); - - return 0; -} - -struct tt_post_table * -tt_read_post_table (sfnt *sfont) -{ - struct tt_post_table *post; - - /* offset = */ sfnt_locate_table(sfont, "post"); - - post = NEW(1, struct tt_post_table); - - post->Version = sfnt_get_ulong(sfont); /* Fixed */ - post->italicAngle = sfnt_get_ulong(sfont); /* Fixed */ - post->underlinePosition = sfnt_get_short(sfont); /* FWord */ - post->underlineThickness = sfnt_get_short(sfont); /* FWord */ - post->isFixedPitch = sfnt_get_ulong(sfont); - post->minMemType42 = sfnt_get_ulong(sfont); - post->maxMemType42 = sfnt_get_ulong(sfont); - post->minMemType1 = sfnt_get_ulong(sfont); - post->maxMemType1 = sfnt_get_ulong(sfont); - - post->numberOfGlyphs = 0; - post->glyphNamePtr = NULL; - post->count = 0; - post->names = NULL; - - if (post->Version == 0x00010000UL) { - post->numberOfGlyphs = 258; /* wrong */ - post->glyphNamePtr = macglyphorder; - post->count = 0; - post->names = NULL; - } else if (post->Version == 0x00025000UL) { - WARN("TrueType 'post' version 2.5 found (deprecated)"); - post->numberOfGlyphs = 0; /* wrong */ - post->glyphNamePtr = NULL; - post->count = 0; - post->names = NULL; - } else if (post->Version == 0x00020000UL) { - if (read_v2_post_names(post, sfont) < 0) { - WARN("Invalid TrueType 'post' table..."); - tt_release_post_table(post); - post = NULL; - } - } else if (post->Version == 0x00030000UL) { - post->numberOfGlyphs = 0; /* wrong */ - post->glyphNamePtr = NULL; - post->count = 0; - post->names = NULL; - } else { - WARN("Unknown 'post' version: %08X", post->Version); - tt_release_post_table(post); - post = NULL; - } - - return post; -} - -USHORT -tt_lookup_post_table (struct tt_post_table *post, const char *glyphname) -{ - USHORT gid; - - ASSERT(post && glyphname); - - for (gid = 0; gid < post->count; gid++) { - if (post->glyphNamePtr[gid] && - !strcmp(glyphname, post->glyphNamePtr[gid])) { - return gid; - } - } - - return 0; -} - -void -tt_release_post_table (struct tt_post_table *post) -{ - USHORT i; - - ASSERT(post); - - if (post->glyphNamePtr && post->Version != 0x00010000UL) - RELEASE((void *)post->glyphNamePtr); - if (post->names) { - for (i = 0; i < post->count; i++) { - if (post->names[i]) - RELEASE(post->names[i]); - } - RELEASE(post->names); - } - post->count = 0; - post->glyphNamePtr = NULL; - post->names = NULL; - - RELEASE(post); - - return; -} - -/* Macintosh glyph order - from apple's TTRefMan */ -static const char * -macglyphorder[258] = { - /* 0x0000 */ - ".notdef", ".null", "nonmarkingreturn", "space", "exclam", "quotedbl", - "numbersign", "dollar", "percent", "ampersand", "quotesingle", - "parenleft", "parenright", "asterisk", "plus", "comma", - /* 0x0010 */ - "hyphen", "period", "slash", "zero", "one", "two", "three", "four", - "five", "six", "seven", "eight", "nine", "colon", "semicolon", "less", - /* 0x0020 */ - "equal", "greater", "question", "at", "A", "B", "C", "D", - "E", "F", "G", "H", "I", "J", "K", "L", - /* 0x0030 */ - "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", - "Y", "Z", "bracketleft", "backslash", - /* 0x0040 */ - "bracketright", "asciicircum", "underscore", "grave", - "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", - /* 0x0050 */ - "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", - "y", "z", "braceleft", "bar", - /* 0x0060 */ - "braceright", "asciitilde", "Adieresis", "Aring", "Ccedilla", - "Eacute", "Ntilde", "Odieresis", "Udieresis", "aacute", "agrave", - "acircumflex", "adieresis", "atilde", "aring", "ccedilla", - /* 0x0070 */ - "eacute", "egrave", "ecircumflex", "edieresis", "iacute", "igrave", - "icircumflex", "idieresis", "ntilde", "oacute", "ograve", "ocircumflex", - "odieresis", "otilde", "uacute", "ugrave", - /* 0x0080 */ - "ucircumflex", "udieresis", "dagger", "degree", "cent", "sterling", - "section", "bullet", "paragraph", "germandbls", "registered", - "copyright", "trademark", "acute", "dieresis", "notequal", - /* 0x0090 */ - "AE", "Oslash", "infinity", "plusminus", "lessequal", "greaterequal", - "yen", "mu", "partialdiff", "summation", "product", "pi", "integral", - "ordfeminine", "ordmasculine", "Omega", - /* 0x00a0 */ - "ae", "oslash", "questiondown", "exclamdown", "logicalnot", "radical", - "florin", "approxequal", "Delta", "guillemotleft", "guillemotright", - "ellipsis", "nonbreakingspace", "Agrave", "Atilde", "Otilde", - /* 0x00b0 */ - "OE", "oe", "endash", "emdash", "quotedblleft", "quotedblright", - "quoteleft", "quoteright", "divide", "lozenge", "ydieresis", - "Ydieresis", "fraction", "currency", "guilsinglleft", "guilsinglright", - /* 0x00c0 */ - "fi", "fl", "daggerdbl", "periodcentered", "quotesinglbase", - "quotedblbase", "perthousand", "Acircumflex", "Ecircumflex", "Aacute", - "Edieresis", "Egrave", "Iacute", "Icircumflex", "Idieresis", "Igrave", - /* 0x00d0 */ - "Oacute", "Ocircumflex", "apple", "Ograve", "Uacute", "Ucircumflex", - "Ugrave", "dotlessi", "circumflex", "tilde", "macron", "breve", - "dotaccent", "ring", "cedilla", "hungarumlaut", - /* 0x00e0 */ - "ogonek", "caron", "Lslash", "lslash", "Scaron", "scaron", "Zcaron", - "zcaron", "brokenbar", "Eth", "eth", "Yacute", "yacute", "Thorn", - "thorn", "minus", - /* 0x00f0 */ - "multiply", "onesuperior", "twosuperior", "threesuperior", "onehalf", - "onequarter", "threequarters", "franc", "Gbreve", "gbreve", "Idotaccent", - "Scedilla", "scedilla", "Cacute", "cacute", "Ccaron", - /* 0x0100 */ - "ccaron", "dcroat" -}; diff --git a/Build/source/texk/dvipdfm-x/src/tt_table.c b/Build/source/texk/dvipdfm-x/src/tt_table.c deleted file mode 100644 index 3f8d0157103..00000000000 --- a/Build/source/texk/dvipdfm-x/src/tt_table.c +++ /dev/null @@ -1,507 +0,0 @@ -/* - - This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. - - Copyright (C) 2002-2012 by Jin-Hwan Cho and Shunsaku Hirata, - the dvipdfmx project team. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. -*/ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <stdio.h> - -#include "system.h" -#include "error.h" -#include "mem.h" -#include "mfileio.h" - -#include "sfnt.h" -#include "tt_table.h" - -/* - tables contains information refered by other tables - maxp->numGlyphs, etc --> loca, etc - hhea->numOfLongHorMetrics --> hmtx - head->indexToLocFormat --> loca - head->glyphDataFormat --> glyf -*/ - -char *tt_pack_head_table (struct tt_head_table *table) -{ - int i; - char *p, *data; - - if (table == NULL) - ERROR("passed NULL pointer\n"); - - p = data = NEW(TT_HEAD_TABLE_SIZE, char); - p += sfnt_put_ulong(p, table->version); - p += sfnt_put_ulong(p, table->fontRevision); - p += sfnt_put_ulong(p, table->checkSumAdjustment); - p += sfnt_put_ulong(p, table->magicNumber); - p += sfnt_put_ushort(p, table->flags); - p += sfnt_put_ushort(p, table->unitsPerEm); - for (i=0; i<8; i++) { - *(p++) = (table->created)[i]; - } - for (i=0; i<8; i++) { - *(p++) = (table->modified)[i]; - } - p += sfnt_put_short(p, table->xMin); - p += sfnt_put_short(p, table->yMin); - p += sfnt_put_short(p, table->xMax); - p += sfnt_put_short(p, table->yMax); - p += sfnt_put_ushort(p, table->macStyle); - p += sfnt_put_ushort(p, table->lowestRecPPEM); - p += sfnt_put_short(p, table->fontDirectionHint); - p += sfnt_put_short(p, table->indexToLocFormat); - p += sfnt_put_short(p, table->glyphDataFormat); - - return data; -} - -struct tt_head_table *tt_read_head_table (sfnt *sfont) -{ - int i; - struct tt_head_table *table = NEW(1, struct tt_head_table); - - sfnt_locate_table(sfont, "head"); - - table->version = sfnt_get_ulong(sfont); - table->fontRevision = sfnt_get_ulong(sfont); - table->checkSumAdjustment = sfnt_get_ulong(sfont); - table->magicNumber = sfnt_get_ulong(sfont); - table->flags = sfnt_get_ushort(sfont); - table->unitsPerEm = sfnt_get_ushort(sfont); - for (i=0; i<8; i++) { - (table->created)[i] = sfnt_get_byte (sfont); - } - for (i=0; i<8; i++) { - (table->modified)[i] = sfnt_get_byte (sfont); - } - table->xMin = sfnt_get_short(sfont); - table->yMin = sfnt_get_short(sfont); - table->xMax = sfnt_get_short(sfont); - table->yMax = sfnt_get_short(sfont); - table->macStyle = sfnt_get_short(sfont); - table->lowestRecPPEM = sfnt_get_short(sfont); - table->fontDirectionHint = sfnt_get_short(sfont); - table->indexToLocFormat = sfnt_get_short(sfont); - table->glyphDataFormat = sfnt_get_short(sfont); - - return table; -} - -char *tt_pack_maxp_table (struct tt_maxp_table *table) -{ - char *p, *data; - - p = data = NEW(TT_MAXP_TABLE_SIZE, char); - p += sfnt_put_ulong(p, table->version); - p += sfnt_put_ushort(p, table->numGlyphs); - p += sfnt_put_ushort(p, table->maxPoints); - p += sfnt_put_ushort(p, table->maxContours); - p += sfnt_put_ushort(p, table->maxComponentPoints); - p += sfnt_put_ushort(p, table->maxComponentContours); - p += sfnt_put_ushort(p, table->maxZones); - p += sfnt_put_ushort(p, table->maxTwilightPoints); - p += sfnt_put_ushort(p, table->maxStorage); - p += sfnt_put_ushort(p, table->maxFunctionDefs); - p += sfnt_put_ushort(p, table->maxInstructionDefs); - p += sfnt_put_ushort(p, table->maxStackElements); - p += sfnt_put_ushort(p, table->maxSizeOfInstructions); - p += sfnt_put_ushort(p, table->maxComponentElements); - p += sfnt_put_ushort(p, table->maxComponentDepth); - - return data; -} - -struct tt_maxp_table *tt_read_maxp_table (sfnt *sfont) -{ - struct tt_maxp_table *table = NEW(1, struct tt_maxp_table); - - sfnt_locate_table(sfont, "maxp"); - - table->version = sfnt_get_ulong(sfont); - table->numGlyphs = sfnt_get_ushort(sfont); - table->maxPoints = sfnt_get_ushort(sfont); - table->maxContours = sfnt_get_ushort(sfont); - table->maxComponentPoints = sfnt_get_ushort(sfont); - table->maxComponentContours = sfnt_get_ushort(sfont); - table->maxZones = sfnt_get_ushort(sfont); - table->maxTwilightPoints = sfnt_get_ushort(sfont); - table->maxStorage = sfnt_get_ushort(sfont); - table->maxFunctionDefs = sfnt_get_ushort(sfont); - table->maxInstructionDefs = sfnt_get_ushort(sfont); - table->maxStackElements = sfnt_get_ushort(sfont); - table->maxSizeOfInstructions = sfnt_get_ushort(sfont); - table->maxComponentElements = sfnt_get_ushort(sfont); - table->maxComponentDepth = sfnt_get_ushort(sfont); - - return table; -} - -char *tt_pack_hhea_table (struct tt_hhea_table *table) -{ - int i; - char *p, *data; - - p = data = NEW(TT_HHEA_TABLE_SIZE, char); - p += sfnt_put_ulong(p, table->version); - p += sfnt_put_short(p, table->ascent); - p += sfnt_put_short(p, table->descent); - p += sfnt_put_short(p, table->lineGap); - p += sfnt_put_ushort(p, table->advanceWidthMax); - p += sfnt_put_short(p, table->minLeftSideBearing); - p += sfnt_put_short(p, table->minRightSideBearing); - p += sfnt_put_short(p, table->xMaxExtent); - p += sfnt_put_short(p, table->caretSlopeRise); - p += sfnt_put_short(p, table->caretSlopeRun); - p += sfnt_put_short(p, table->caretOffset); - for (i = 0; i < 4; i++) { - p += sfnt_put_short(p, table->reserved[i]); - } - p += sfnt_put_short(p, table->metricDataFormat); - p += sfnt_put_ushort(p, table->numOfLongHorMetrics); - - return data; -} - -struct tt_hhea_table * -tt_read_hhea_table (sfnt *sfont) -{ - int i; - ULONG len; - struct tt_hhea_table *table = NEW(1, struct tt_hhea_table); - - sfnt_locate_table(sfont, "hhea"); - - table->version = sfnt_get_ulong(sfont); - table->ascent = sfnt_get_short (sfont); - table->descent = sfnt_get_short(sfont); - table->lineGap = sfnt_get_short(sfont); - table->advanceWidthMax = sfnt_get_ushort(sfont); - table->minLeftSideBearing = sfnt_get_short(sfont); - table->minRightSideBearing = sfnt_get_short(sfont); - table->xMaxExtent = sfnt_get_short(sfont); - table->caretSlopeRise = sfnt_get_short(sfont); - table->caretSlopeRun = sfnt_get_short(sfont); - table->caretOffset = sfnt_get_short(sfont); - for(i = 0; i < 4; i++) { - table->reserved[i] = sfnt_get_short(sfont); - } - table->metricDataFormat = sfnt_get_short(sfont); - if (table->metricDataFormat != 0) - ERROR("unknown metricDataFormat"); - table->numOfLongHorMetrics = sfnt_get_ushort(sfont); - - len = sfnt_find_table_len(sfont, "hmtx"); - table->numOfExSideBearings = (USHORT)((len - table->numOfLongHorMetrics * 4) / 2); - - return table; -} - -/* vhea */ -#if 0 -char * -tt_pack_vhea_table (struct tt_vhea_table *table) -{ - int i; - char *p, *data; - - p = data = NEW(TT_VHEA_TABLE_SIZE, char); - p += sfnt_put_ulong(p, table->version); - p += sfnt_put_short(p, table->vertTypoAscender); - p += sfnt_put_short(p, table->vertTypoDescender); - p += sfnt_put_short(p, table->vertTypoLineGap); - p += sfnt_put_short(p, table->advanceHeightMax); /* ushort ? */ - p += sfnt_put_short(p, table->minTopSideBearing); - p += sfnt_put_short(p, table->minBottomSideBearing); - p += sfnt_put_short(p, table->yMaxExtent); - p += sfnt_put_short(p, table->caretSlopeRise); - p += sfnt_put_short(p, table->caretSlopeRun); - p += sfnt_put_short(p, table->caretOffset); - for(i = 0; i < 4; i++) { - p += sfnt_put_short(p, table->reserved[i]); - } - p += sfnt_put_short(p, table->metricDataFormat); - p += sfnt_put_ushort(p, table->numOfLongVerMetrics); - - return data; -} -#endif - -struct tt_vhea_table *tt_read_vhea_table (sfnt *sfont) -{ - int i; - ULONG len; - struct tt_vhea_table *table = NEW(1, struct tt_vhea_table); - - sfnt_locate_table(sfont, "vhea"); - - table->version = sfnt_get_ulong(sfont); - table->vertTypoAscender = sfnt_get_short (sfont); - table->vertTypoDescender = sfnt_get_short(sfont); - table->vertTypoLineGap = sfnt_get_short(sfont); - table->advanceHeightMax = sfnt_get_short(sfont); /* ushort ? */ - table->minTopSideBearing = sfnt_get_short(sfont); - table->minBottomSideBearing = sfnt_get_short(sfont); - table->yMaxExtent = sfnt_get_short(sfont); - table->caretSlopeRise = sfnt_get_short(sfont); - table->caretSlopeRun = sfnt_get_short(sfont); - table->caretOffset = sfnt_get_short(sfont); - for(i = 0; i < 4; i++) { - (table->reserved)[i] = sfnt_get_short(sfont); - } - table->metricDataFormat = sfnt_get_short(sfont); - table->numOfLongVerMetrics = sfnt_get_ushort(sfont); - - len = sfnt_find_table_len(sfont, "vmtx"); - table->numOfExSideBearings = (USHORT)((len - table->numOfLongVerMetrics * 4) / 2); - - return table; -} - - -struct tt_VORG_table * -tt_read_VORG_table (sfnt *sfont) -{ - struct tt_VORG_table *vorg; - ULONG offset; - USHORT i; - - offset = sfnt_find_table_pos(sfont, "VORG"); - - if (offset > 0) { - vorg = NEW(1, struct tt_VORG_table); - - sfnt_locate_table(sfont, "VORG"); - if (sfnt_get_ushort(sfont) != 1 || - sfnt_get_ushort(sfont) != 0) - ERROR("Unsupported VORG version."); - - vorg->defaultVertOriginY = sfnt_get_short(sfont); - vorg->numVertOriginYMetrics = sfnt_get_ushort(sfont); - vorg->vertOriginYMetrics = NEW(vorg->numVertOriginYMetrics, - struct tt_vertOriginYMetrics); - /* - * The vertOriginYMetrics array must be sorted in increasing - * glyphIndex order. - */ - for (i = 0; - i < vorg->numVertOriginYMetrics; i++) { - vorg->vertOriginYMetrics[i].glyphIndex = sfnt_get_ushort(sfont); - vorg->vertOriginYMetrics[i].vertOriginY = sfnt_get_short(sfont); - } - } else { - vorg = NULL; - } - - return vorg; -} - -/* - * hmtx and vmtx - * - * Reading/writing hmtx and vmtx depend on other tables, maxp and hhea/vhea. - */ - -struct tt_longMetrics * -tt_read_longMetrics (sfnt *sfont, USHORT numGlyphs, USHORT numLongMetrics, USHORT numExSideBearings) -{ - struct tt_longMetrics *m; - USHORT gid, last_adv = 0; - SHORT last_esb = 0; - - m = NEW(numGlyphs, struct tt_longMetrics); - for (gid = 0; gid < numGlyphs; gid++) { - if (gid < numLongMetrics) - last_adv = sfnt_get_ushort(sfont); - if (gid < numLongMetrics + numExSideBearings) - last_esb = sfnt_get_short(sfont); - m[gid].advance = last_adv; - m[gid].sideBearing = last_esb; - } - - return m; -} - -/* OS/2 table */ -/* this table may not exist */ -struct tt_os2__table * -tt_read_os2__table (sfnt *sfont) -{ - struct tt_os2__table *table = NULL; - int i; - - table = NEW(1, struct tt_os2__table); - - if (sfnt_find_table_pos(sfont, "OS/2") > 0) { - sfnt_locate_table(sfont, "OS/2"); - table->version = sfnt_get_ushort(sfont); - table->xAvgCharWidth = sfnt_get_short(sfont); - table->usWeightClass = sfnt_get_ushort(sfont); - table->usWidthClass = sfnt_get_ushort(sfont); - table->fsType = sfnt_get_short(sfont); - table->ySubscriptXSize = sfnt_get_short(sfont); - table->ySubscriptYSize = sfnt_get_short(sfont); - table->ySubscriptXOffset = sfnt_get_short(sfont); - table->ySubscriptYOffset = sfnt_get_short(sfont); - table->ySuperscriptXSize = sfnt_get_short(sfont); - table->ySuperscriptYSize = sfnt_get_short(sfont); - table->ySuperscriptXOffset = sfnt_get_short(sfont); - table->ySuperscriptYOffset = sfnt_get_short(sfont); - table->yStrikeoutSize = sfnt_get_short(sfont); - table->yStrikeoutPosition = sfnt_get_short(sfont); - table->sFamilyClass = sfnt_get_short(sfont); - for (i = 0; i < 10; i++) { - table->panose[i] = sfnt_get_byte(sfont); - } - table->ulUnicodeRange1 = sfnt_get_ulong(sfont); - table->ulUnicodeRange2 = sfnt_get_ulong(sfont); - table->ulUnicodeRange3 = sfnt_get_ulong(sfont); - table->ulUnicodeRange4 = sfnt_get_ulong(sfont); - for (i = 0; i < 4; i++) { - table->achVendID[i] = sfnt_get_char(sfont); - } - table->fsSelection = sfnt_get_ushort(sfont); - table->usFirstCharIndex = sfnt_get_ushort(sfont); - table->usLastCharIndex = sfnt_get_ushort(sfont); - table->sTypoAscender = sfnt_get_short(sfont); - table->sTypoDescender = sfnt_get_short(sfont); - table->sTypoLineGap = sfnt_get_short(sfont); - table->usWinAscent = sfnt_get_ushort(sfont); - table->usWinDescent = sfnt_get_ushort(sfont); - table->ulCodePageRange1 = sfnt_get_ulong(sfont); - table->ulCodePageRange2 = sfnt_get_ulong(sfont); - if (table->version == 0x0002) { - table->sxHeight = sfnt_get_short(sfont); - table->sCapHeight = sfnt_get_short(sfont); - table->usDefaultChar = sfnt_get_ushort(sfont); - table->usBreakChar = sfnt_get_ushort(sfont); - table->usMaxContext = sfnt_get_ushort(sfont); - } - } else { - /* used in add_CIDVMetrics() of cidtype0.c */ - table->sTypoAscender = 880; - table->sTypoDescender = -120; - /* used in tt_get_fontdesc() of tt_aux.c */ - table->usWeightClass = 400U; /* Normal(Regular) */ - table->xAvgCharWidth = 0; /* ignore */ - table->version = 0; /* TrueType rev 1.5 */ - table->fsType = 0; /* Installable Embedding */ - table->fsSelection = 0U; /* All undefined */ - table->sFamilyClass = 0; /* No Classification */ - for (i = 0; i < 10; i++) { - table->panose[i] = 0; /* All Any */ - } - } - - return table; -} - -USHORT -tt_get_name (sfnt *sfont, char *dest, USHORT destlen, - USHORT plat_id, USHORT enco_id, - USHORT lang_id, USHORT name_id) -{ - USHORT length = 0; - USHORT num_names, string_offset; - ULONG name_offset; - int i; - - name_offset = sfnt_locate_table (sfont, "name"); - - if (sfnt_get_ushort(sfont)) - ERROR ("Expecting zero"); - - num_names = sfnt_get_ushort(sfont); - string_offset = sfnt_get_ushort(sfont); - for (i=0;i<num_names;i++) { - USHORT p_id, e_id, n_id, l_id; - USHORT offset; - - p_id = sfnt_get_ushort(sfont); - e_id = sfnt_get_ushort(sfont); - l_id = sfnt_get_ushort(sfont); - n_id = sfnt_get_ushort(sfont); - length = sfnt_get_ushort(sfont); - offset = sfnt_get_ushort(sfont); - /* language ID value 0xffffu for `accept any language ID' */ - if ((p_id == plat_id) && (e_id == enco_id) && - (lang_id == 0xffffu || l_id == lang_id) && (n_id == name_id)) { - if (length > destlen - 1) { - fprintf(stderr, "\n** Notice: Name string too long. Truncating **\n"); - length = destlen - 1; - } - sfnt_seek_set (sfont, name_offset+string_offset+offset); - sfnt_read((unsigned char*)dest, length, sfont); - dest[length] = '\0'; - break; - } - } - if (i == num_names) { - length = 0; - } - - return length; -} - -USHORT -tt_get_ps_fontname (sfnt *sfont, char *dest, USHORT destlen) -{ - USHORT namelen = 0; - -#ifdef XETEX - - const char* name = FT_Get_Postscript_Name(sfont->ft_face); - namelen = strlen(name); - if (namelen > destlen - 1) { - strncpy(dest, name, destlen - 1); - dest[destlen] = 0; - } - else - strcpy(dest, name); - -#else - - /* First try Mac-Roman PS name and then Win-Unicode PS name */ - if ((namelen = tt_get_name(sfont, dest, destlen, 1, 0, 0, 6)) != 0 || - (namelen = tt_get_name(sfont, dest, destlen, 3, 1, 0x409u, 6)) != 0 || - (namelen = tt_get_name(sfont, dest, destlen, 3, 5, 0x412u, 6)) != 0) - return namelen; - - fprintf(stderr, "\n** Warning: No valid PostScript name available **\n"); - /* - Wrokaround for some bad TTfonts: - Language ID value 0xffffu for `accept any language ID' - */ - if ((namelen = tt_get_name(sfont, dest, destlen, 1, 0, 0xffffu, 6)) == 0) { - /* - Finally falling back to Mac Roman name field. - Warning: Some bad Japanese TTfonts using SJIS encoded string in the - Mac Roman name field. - */ - namelen = tt_get_name(sfont, dest, destlen, 1, 0, 0, 1); - } - -#endif - - return namelen; -} |