summaryrefslogtreecommitdiff
path: root/Build/source/texk/dvipdfm-x/xsrc
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/texk/dvipdfm-x/xsrc')
-rw-r--r--Build/source/texk/dvipdfm-x/xsrc/cff_dict.c724
-rw-r--r--Build/source/texk/dvipdfm-x/xsrc/dvipdfmx.c3
-rw-r--r--Build/source/texk/dvipdfm-x/xsrc/jpegimage.c16
-rw-r--r--Build/source/texk/dvipdfm-x/xsrc/pdfdev.c6
-rw-r--r--Build/source/texk/dvipdfm-x/xsrc/pdfdoc.c183
-rw-r--r--Build/source/texk/dvipdfm-x/xsrc/pdfdraw.c114
-rw-r--r--Build/source/texk/dvipdfm-x/xsrc/pdfencrypt.c539
-rw-r--r--Build/source/texk/dvipdfm-x/xsrc/pdfnames.c45
-rw-r--r--Build/source/texk/dvipdfm-x/xsrc/pdfnames.h52
-rw-r--r--Build/source/texk/dvipdfm-x/xsrc/pdfobj.c96
-rw-r--r--Build/source/texk/dvipdfm-x/xsrc/pdfximage.c37
-rw-r--r--Build/source/texk/dvipdfm-x/xsrc/spc_dvips.c1075
-rw-r--r--Build/source/texk/dvipdfm-x/xsrc/spc_pdfm.c116
-rw-r--r--Build/source/texk/dvipdfm-x/xsrc/spc_tpic.c153
-rw-r--r--Build/source/texk/dvipdfm-x/xsrc/specials.c619
-rw-r--r--Build/source/texk/dvipdfm-x/xsrc/tfm.c1209
-rw-r--r--Build/source/texk/dvipdfm-x/xsrc/truetype.c1008
-rw-r--r--Build/source/texk/dvipdfm-x/xsrc/tt_cmap.c6
-rw-r--r--Build/source/texk/dvipdfm-x/xsrc/type1.c805
-rw-r--r--Build/source/texk/dvipdfm-x/xsrc/xbb.c46
20 files changed, 564 insertions, 6288 deletions
diff --git a/Build/source/texk/dvipdfm-x/xsrc/cff_dict.c b/Build/source/texk/dvipdfm-x/xsrc/cff_dict.c
deleted file mode 100644
index 94e88a68ea6..00000000000
--- a/Build/source/texk/dvipdfm-x/xsrc/cff_dict.c
+++ /dev/null
@@ -1,724 +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.
-*/
-
-/*
- * CFF Font Dictionary
- *
- * Adobe Technical Note #5176 "The Compact Font Format Specification"
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <math.h>
-#include <stdlib.h>
-#include <errno.h>
-
-#include "error.h"
-#include "mem.h"
-
-#ifndef CFF_DEBUG_STR
-#define CFF_DEBUG_STR "CFF"
-#define CFF_DEBUG 5
-#endif
-
-/* work_buffer for get_real() */
-#include "mfileio.h"
-
-#include "cff_types.h"
-#include "cff_limits.h"
-
-/* #include "cff_string.h" */
-#include "cff_dict.h"
-/* cff_update_dict requires this. */
-#include "cff.h"
-
-#define CFF_PARSE_OK 0
-#define CFF_ERROR_PARSE_ERROR -1
-#define CFF_ERROR_STACK_OVERFLOW -2
-#define CFF_ERROR_STACK_UNDERFLOW -3
-#define CFF_ERROR_STACK_RANGECHECK -4
-
-#define DICT_ENTRY_MAX 16
-cff_dict *cff_new_dict (void)
-{
- cff_dict *dict;
-
- dict = NEW(1, cff_dict);
- dict->max = DICT_ENTRY_MAX;
- dict->count = 0;
- dict->entries = NEW(dict->max, cff_dict_entry);
-
- return dict;
-}
-
-void cff_release_dict (cff_dict *dict)
-{
- if (dict) {
- if (dict->entries) {
- int i;
- for (i=0;i<dict->count;i++) {
- if ((dict->entries)[i].values)
- RELEASE((dict->entries)[i].values);
- }
- RELEASE(dict->entries);
- }
- RELEASE(dict);
- }
-}
-
-/*
- * Operand stack:
- * only numbers are stored (as double)
- *
- * Operand types:
- *
- * number : double (integer or real)
- * boolean: stored as a number
- * SID : stored as a number
- * array : array of numbers
- * delta : array of numbers
- */
-
-#define CFF_DICT_STACK_LIMIT 64
-static int stack_top = 0;
-static double arg_stack[CFF_DICT_STACK_LIMIT];
-
-/*
- * CFF DICT encoding:
- * TODO: default values
- */
-
-#define CFF_LAST_DICT_OP1 22
-#define CFF_LAST_DICT_OP2 39
-#define CFF_LAST_DICT_OP (CFF_LAST_DICT_OP1 + CFF_LAST_DICT_OP2)
-
-static struct {
- const char *opname;
- int argtype;
-} dict_operator[CFF_LAST_DICT_OP] = {
- {"version", CFF_TYPE_SID},
- {"Notice", CFF_TYPE_SID},
- {"FullName", CFF_TYPE_SID},
- {"FamilyName", CFF_TYPE_SID},
- {"Weight", CFF_TYPE_SID},
- {"FontBBox", CFF_TYPE_ARRAY},
- {"BlueValues", CFF_TYPE_DELTA},
- {"OtherBlues", CFF_TYPE_DELTA},
- {"FamilyBlues", CFF_TYPE_DELTA},
- {"FamilyOtherBlues", CFF_TYPE_DELTA},
- {"StdHW", CFF_TYPE_NUMBER},
- {"StdVW", CFF_TYPE_NUMBER},
- {NULL, -1}, /* first byte of two-byte operator */
- /* Top */
- {"UniqueID", CFF_TYPE_NUMBER},
- {"XUID", CFF_TYPE_ARRAY},
- {"charset", CFF_TYPE_OFFSET},
- {"Encoding", CFF_TYPE_OFFSET},
- {"CharStrings", CFF_TYPE_OFFSET},
- {"Private", CFF_TYPE_SZOFF}, /* two numbers (size and offset) */
- /* Private */
- {"Subrs", CFF_TYPE_OFFSET},
- {"defaultWidthX", CFF_TYPE_NUMBER},
- {"nominalWidthX", CFF_TYPE_NUMBER},
- /* Operator 2 */
- {"Copyright", CFF_TYPE_SID},
- {"IsFixedPitch", CFF_TYPE_BOOLEAN},
- {"ItalicAngle", CFF_TYPE_NUMBER},
- {"UnderlinePosition", CFF_TYPE_NUMBER},
- {"UnderlineThickness", CFF_TYPE_NUMBER},
- {"PaintType", CFF_TYPE_NUMBER},
- {"CharstringType", CFF_TYPE_NUMBER},
- {"FontMatrix", CFF_TYPE_ARRAY},
- {"StrokeWidth", CFF_TYPE_NUMBER},
- {"BlueScale", CFF_TYPE_NUMBER},
- {"BlueShift", CFF_TYPE_NUMBER},
- {"BlueFuzz", CFF_TYPE_NUMBER},
- {"StemSnapH", CFF_TYPE_DELTA},
- {"StemSnapV", CFF_TYPE_DELTA},
- {"ForceBold", CFF_TYPE_BOOLEAN},
- {NULL, -1},
- {NULL, -1},
- {"LanguageGroup", CFF_TYPE_NUMBER},
- {"ExpansionFactor", CFF_TYPE_NUMBER},
- {"InitialRandomSeed", CFF_TYPE_NUMBER},
- {"SyntheticBase", CFF_TYPE_NUMBER},
- {"PostScript", CFF_TYPE_SID},
- {"BaseFontName", CFF_TYPE_SID},
- {"BaseFontBlend", CFF_TYPE_DELTA}, /* MMaster ? */
- {NULL, -1},
- {NULL, -1},
- {NULL, -1},
- {NULL, -1},
- {NULL, -1},
- {NULL, -1},
- /* CID-Keyed font */
- {"ROS", CFF_TYPE_ROS}, /* SID SID number */
- {"CIDFontVersion", CFF_TYPE_NUMBER},
- {"CIDFontRevision", CFF_TYPE_NUMBER},
- {"CIDFontType", CFF_TYPE_NUMBER},
- {"CIDCount", CFF_TYPE_NUMBER},
- {"UIDBase", CFF_TYPE_NUMBER},
- {"FDArray", CFF_TYPE_OFFSET},
- {"FDSelect", CFF_TYPE_OFFSET},
- {"FontName", CFF_TYPE_SID},
-};
-
-/* Parse DICT data */
-static double get_integer (card8 **data, card8 *endptr, int *status)
-{
- long result = 0;
- card8 b0, b1, b2;
-
- b0 = *(*data)++;
- if (b0 == 28 && *data < endptr - 2) { /* shortint */
- b1 = *(*data)++;
- b2 = *(*data)++;
- result = b1*256+b2;
- if (result > 0x7fffL)
- result -= 0x10000L;
- } else if (b0 == 29 && *data < endptr - 4) { /* longint */
- int i;
- result = *(*data)++;
- if (result > 0x7f)
- result -= 0x100;
- for (i=0;i<3;i++) {
- result = result*256+(**data);
- *data += 1;
- }
- } else if (b0 >= 32 && b0 <= 246) { /* int (1) */
- result = b0 - 139;
- } else if (b0 >= 247 && b0 <= 250) { /* int (2) */
- b1 = *(*data)++;
- result = (b0-247)*256+b1+108;
- } else if (b0 >= 251 && b0 <= 254) {
- b1 = *(*data)++;
- result = -(b0-251)*256-b1-108;
- } else {
- *status = CFF_ERROR_PARSE_ERROR;
- }
-
- return (double) result;
-}
-
-/* Simply uses strtod */
-static double get_real(card8 **data, card8 *endptr, int *status)
-{
- double result = 0.0;
- int nibble = 0, pos = 0;
- int len = 0, fail = 0;
-
- if (**data != 30 || *data >= endptr -1) {
- *status = CFF_ERROR_PARSE_ERROR;
- return 0.0;
- }
-
- *data += 1; /* skip first byte (30) */
-
- pos = 0;
- while ((! fail) && len < WORK_BUFFER_SIZE - 2 && *data < endptr) {
- /* get nibble */
- if (pos % 2) {
- nibble = **data & 0x0f;
- *data += 1;
- } else {
- nibble = (**data >> 4) & 0x0f;
- }
- if (nibble >= 0x00 && nibble <= 0x09) {
- work_buffer[len++] = nibble + '0';
- } else if (nibble == 0x0a) { /* . */
- work_buffer[len++] = '.';
- } else if (nibble == 0x0b || nibble == 0x0c) { /* E, E- */
- work_buffer[len++] = 'e';
- if (nibble == 0x0c)
- work_buffer[len++] = '-';
- } else if (nibble == 0x0e) { /* `-' */
- work_buffer[len++] = '-';
- } else if (nibble == 0x0d) { /* skip */
- /* do nothing */
- } else if (nibble == 0x0f) { /* end */
- work_buffer[len++] = '\0';
- if (((pos % 2) == 0) && (**data != 0xff)) {
- fail = 1;
- }
- break;
- } else { /* invalid */
- fail = 1;
- }
- pos++;
- }
-
- /* returned values */
- if (fail || nibble != 0x0f) {
- *status = CFF_ERROR_PARSE_ERROR;
- } else {
- char *s;
- result = strtod(work_buffer, &s);
- if (*s != 0 || errno == ERANGE) {
- *status = CFF_ERROR_PARSE_ERROR;
- }
- }
-
- return result;
-}
-
-/* operators */
-static void add_dict (cff_dict *dict,
- card8 **data, card8 *endptr, int *status)
-{
- int id, argtype;
-
- id = **data;
- if (id == 0x0c) {
- *data += 1;
- if (*data >= endptr ||
- (id = **data + CFF_LAST_DICT_OP1) >= CFF_LAST_DICT_OP) {
- *status = CFF_ERROR_PARSE_ERROR;
- return;
- }
- } else if (id >= CFF_LAST_DICT_OP1) {
- *status = CFF_ERROR_PARSE_ERROR;
- return;
- }
-
- argtype = dict_operator[id].argtype;
- if (dict_operator[id].opname == NULL || argtype < 0) {
- *status = CFF_ERROR_PARSE_ERROR;
- return;
- }
-
- if (dict->count >= dict->max) {
- dict->max += DICT_ENTRY_MAX;
- dict->entries = RENEW(dict->entries, dict->max, cff_dict_entry);
- }
-
- (dict->entries)[dict->count].id = id;
- (dict->entries)[dict->count].key = dict_operator[id].opname;
- if (argtype == CFF_TYPE_NUMBER ||
- argtype == CFF_TYPE_BOOLEAN ||
- argtype == CFF_TYPE_SID ||
- argtype == CFF_TYPE_OFFSET) {
- /* check for underflow here, as exactly one operand is expected */
- if (stack_top < 1) {
- *status = CFF_ERROR_STACK_UNDERFLOW;
- return;
- }
- stack_top--;
- (dict->entries)[dict->count].count = 1;
- (dict->entries)[dict->count].values = NEW(1, double);
- (dict->entries)[dict->count].values[0] = arg_stack[stack_top];
- dict->count += 1;
- } else {
- /* just ignore operator if there were no operands provided;
- don't treat this as underflow (e.g. StemSnapV in TemporaLGCUni-Italic.otf) */
- if (stack_top > 0) {
- (dict->entries)[dict->count].count = stack_top;
- (dict->entries)[dict->count].values = NEW(stack_top, double);
- while (stack_top > 0) {
- stack_top--;
- (dict->entries)[dict->count].values[stack_top] = arg_stack[stack_top];
- }
- dict->count += 1;
- }
- }
-
- *data += 1;
-
- return;
-}
-
-/*
- * All operands are treated as number or array of numbers.
- * Private: two numbers, size and offset
- * ROS : three numbers, SID, SID, and a number
- */
-cff_dict *cff_dict_unpack (card8 *data, card8 *endptr)
-{
- cff_dict *dict;
- int status = CFF_PARSE_OK;
-
- stack_top = 0;
-
- dict = cff_new_dict();
- while (data < endptr && status == CFF_PARSE_OK) {
- if (*data < 22) { /* operator */
- add_dict(dict, &data, endptr, &status);
- } else if (*data == 30) { /* real - First byte of a sequence (variable) */
- if (stack_top < CFF_DICT_STACK_LIMIT) {
- arg_stack[stack_top] = get_real(&data, endptr, &status);
- stack_top++;
- } else {
- status = CFF_ERROR_STACK_OVERFLOW;
- }
- } else if (*data == 255 || (*data >= 22 && *data <= 27)) { /* reserved */
- data++;
- } else { /* everything else are integer */
- if (stack_top < CFF_DICT_STACK_LIMIT) {
- arg_stack[stack_top] = get_integer(&data, endptr, &status);
- stack_top++;
- } else {
- status = CFF_ERROR_STACK_OVERFLOW;
- }
- }
- }
-
- if (status != CFF_PARSE_OK) {
- ERROR("%s: Parsing CFF DICT failed. (error=%d)", CFF_DEBUG_STR, status);
- } else if (stack_top != 0) {
- WARN("%s: Garbage in CFF DICT data.", CFF_DEBUG_STR);
- stack_top = 0;
- }
-
- return dict;
-}
-
-/* Pack DICT data */
-static long pack_integer (card8 *dest, long destlen, long value)
-{
- long len = 0;
-
- if (value >= -107 && value <= 107) {
- if (destlen < 1)
- ERROR("%s: Buffer overflow.", CFF_DEBUG_STR);
- dest[0] = (value + 139) & 0xff;
- len = 1;
- } else if (value >= 108 && value <= 1131) {
- if (destlen < 2)
- ERROR("%s: Buffer overflow.", CFF_DEBUG_STR);
- value = 0xf700u + value - 108;
- dest[0] = (value >> 8) & 0xff;
- dest[1] = value & 0xff;
- len = 2;
- } else if (value >= -1131 && value <= -108) {
- if (destlen < 2)
- ERROR("%s: Buffer overflow.", CFF_DEBUG_STR);
- value = 0xfb00u - value - 108;
- dest[0] = (value >> 8) & 0xff;
- dest[1] = value & 0xff;
- len = 2;
- } else if (value >= -32768 && value <= 32767) { /* shortint */
- if (destlen < 3)
- ERROR("%s: Buffer overflow.", CFF_DEBUG_STR);
- dest[0] = 28;
- dest[1] = (value >> 8) & 0xff;
- dest[2] = value & 0xff;
- len = 3;
- } else { /* longint */
- if (destlen < 5)
- ERROR("%s: Buffer overflow.", CFF_DEBUG_STR);
- dest[0] = 29;
- dest[1] = (value >> 24) & 0xff;
- dest[2] = (value >> 16) & 0xff;
- dest[3] = (value >> 8) & 0xff;
- dest[4] = value & 0xff;
- len = 5;
- }
-
- return len;
-}
-
-static long pack_real (card8 *dest, long destlen, double value)
-{
- int i = 0, pos = 2;
- char buffer[32];
-
- if (destlen < 2)
- ERROR("%s: Buffer overflow.", CFF_DEBUG_STR);
-
- dest[0] = 30;
-
- if (value == 0.0) {
- dest[1] = 0x0f;
- return 2;
- }
-
- if (value < 0.0) {
- dest[1] = 0xe0;
- value *= -1.0;
- pos++;
- }
-
- /* To avoid the problem with Mac OS X 10.4 Quartz,
- * change the presion of the real numbers
- * on June 27, 2007 for musix20.pfb */
- sprintf(buffer, "%.13g", value);
-
- for (i = 0; buffer[i] != '\0'; i++) {
- unsigned char ch = 0;
- if (buffer[i] == '.') {
- ch = 0x0a;
- } else if (buffer[i] >= '0' && buffer[i] <= '9') {
- ch = buffer[i] - '0';
- } else if (buffer[i] == 'e') {
- ch = (buffer[++i] == '-' ? 0x0c : 0x0b);
- } else {
- ERROR("%s: Invalid character.", CFF_DEBUG_STR);
- }
-
- if (destlen < pos/2 + 1)
- ERROR("%s: Buffer overflow.", CFF_DEBUG_STR);
-
- if (pos % 2) {
- dest[pos/2] += ch;
- } else {
- dest[pos/2] = (ch << 4);
- }
- pos++;
- }
-
- if (pos % 2) {
- dest[pos/2] += 0x0f;
- pos++;
- } else {
- if (destlen < pos/2 + 1)
- ERROR("%s: Buffer overflow.", CFF_DEBUG_STR);
- dest[pos/2] = 0xff;
- pos += 2;
- }
-
- return pos/2;
-}
-
-static long cff_dict_put_number (double value,
- card8 *dest, long destlen,
- int type)
-{
- long len = 0;
- double nearint;
-
- nearint = floor(value+0.5);
- /* set offset to longint */
- if (type == CFF_TYPE_OFFSET) {
- long lvalue;
-
- lvalue = (long) value;
- if (destlen < 5)
- ERROR("%s: Buffer overflow.", CFF_DEBUG_STR);
- dest[0] = 29;
- dest[1] = (lvalue >> 24) & 0xff;
- dest[2] = (lvalue >> 16) & 0xff;
- dest[3] = (lvalue >> 8) & 0xff;
- dest[4] = lvalue & 0xff;
- len = 5;
- } else if (value > CFF_INT_MAX || value < CFF_INT_MIN ||
- (fabs(value - nearint) > 1.0e-5)) { /* real */
- len = pack_real(dest, destlen, value);
- } else { /* integer */
- len = pack_integer(dest, destlen, (long) nearint);
- }
-
- return len;
-}
-
-static long
-put_dict_entry (cff_dict_entry *de,
- card8 *dest, long destlen)
-{
- long len = 0;
- int i, type, id;
-
- if (de->count > 0) {
- id = de->id;
- if (dict_operator[id].argtype == CFF_TYPE_OFFSET ||
- dict_operator[id].argtype == CFF_TYPE_SZOFF) {
- type = CFF_TYPE_OFFSET;
- } else {
- type = CFF_TYPE_NUMBER;
- }
- for (i = 0; i < de->count; i++) {
- len += cff_dict_put_number(de->values[i],
- dest+len,
- destlen-len, type);
- }
- if (id >= 0 && id < CFF_LAST_DICT_OP1) {
- if (len + 1 > destlen)
- ERROR("%s: Buffer overflow.", CFF_DEBUG_STR);
- dest[len++] = id;
- } else if (id >= 0 && id < CFF_LAST_DICT_OP) {
- if (len + 2 > destlen)
- ERROR("in cff_dict_pack(): Buffer overflow");
- dest[len++] = 12;
- dest[len++] = id - CFF_LAST_DICT_OP1;
- } else {
- ERROR("%s: Invalid CFF DICT operator ID.", CFF_DEBUG_STR);
- }
- }
-
- return len;
-}
-
-long cff_dict_pack (cff_dict *dict, card8 *dest, long destlen)
-{
- long len = 0;
- int i;
-
- for (i = 0; i < dict->count; i++) {
- if (!strcmp(dict->entries[i].key, "ROS")) {
- len += put_dict_entry(&dict->entries[i], dest, destlen);
- break;
- }
- }
- for (i = 0; i < dict->count; i++) {
- if (strcmp(dict->entries[i].key, "ROS")) {
- len += put_dict_entry(&dict->entries[i], dest+len, destlen-len);
- }
- }
-
- return len;
-}
-
-void cff_dict_add (cff_dict *dict, const char *key, int count)
-{
- int id, i;
-
- for (id=0;id<CFF_LAST_DICT_OP;id++) {
- if (key && dict_operator[id].opname &&
- strcmp(dict_operator[id].opname, key) == 0)
- break;
- }
-
- if (id == CFF_LAST_DICT_OP)
- ERROR("%s: Unknown CFF DICT operator.", CFF_DEBUG_STR);
-
- for (i=0;i<dict->count;i++) {
- if ((dict->entries)[i].id == id) {
- if ((dict->entries)[i].count != count)
- ERROR("%s: Inconsistent DICT argument number.", CFF_DEBUG_STR);
- return;
- }
- }
-
- if (dict->count + 1 >= dict->max) {
- dict->max += 8;
- dict->entries = RENEW(dict->entries, dict->max, cff_dict_entry);
- }
-
- (dict->entries)[dict->count].id = id;
- (dict->entries)[dict->count].key = dict_operator[id].opname;
- (dict->entries)[dict->count].count = count;
- if (count > 0) {
- (dict->entries)[dict->count].values = NEW(count, double);
- memset((dict->entries)[dict->count].values,
- 0, sizeof(double)*count);
- } else {
- (dict->entries)[dict->count].values = NULL;
- }
- dict->count += 1;
-
- return;
-}
-
-void cff_dict_remove (cff_dict *dict, const char *key)
-{
- int i;
- for (i = 0; i < dict->count; i++) {
- if (key && strcmp(key, (dict->entries)[i].key) == 0) {
- (dict->entries)[i].count = 0;
- if ((dict->entries)[i].values)
- RELEASE((dict->entries)[i].values);
- (dict->entries)[i].values = NULL;
- }
- }
-}
-
-int cff_dict_known (cff_dict *dict, const char *key)
-{
- int i;
-
- for (i = 0; i < dict->count; i++) {
- if (key && strcmp(key, (dict->entries)[i].key) == 0
- && (dict->entries)[i].count > 0)
- return 1;
- }
-
- return 0;
-}
-
-double cff_dict_get (cff_dict *dict, const char *key, int idx)
-{
- double value = 0.0;
- int i;
-
- ASSERT(key && dict);
-
- for (i = 0; i < dict->count; i++) {
- if (strcmp(key, (dict->entries)[i].key) == 0) {
- if ((dict->entries)[i].count > idx)
- value = (dict->entries)[i].values[idx];
- else
- ERROR("%s: Invalid index number.", CFF_DEBUG_STR);
- break;
- }
- }
-
- if (i == dict->count)
- ERROR("%s: DICT entry \"%s\" not found.", CFF_DEBUG_STR, key);
-
- return value;
-}
-
-void cff_dict_set (cff_dict *dict, const char *key, int idx, double value)
-{
- int i;
-
- ASSERT(dict && key);
-
- for (i = 0 ; i < dict->count; i++) {
- if (strcmp(key, (dict->entries)[i].key) == 0) {
- if ((dict->entries)[i].count > idx)
- (dict->entries)[i].values[idx] = value;
- else
- ERROR("%s: Invalid index number.", CFF_DEBUG_STR);
- break;
- }
- }
-
- if (i == dict->count)
- ERROR("%s: DICT entry \"%s\" not found.", CFF_DEBUG_STR, key);
-}
-
-void cff_dict_update (cff_dict *dict, cff_font *cff)
-{
- int i;
-
- for (i = 0;i < dict->count; i++) {
- if ((dict->entries)[i].count > 0) {
- char *str;
- int id;
-
- id = (dict->entries)[i].id;
- if (dict_operator[id].argtype == CFF_TYPE_SID) {
- str = cff_get_string(cff, (dict->entries)[i].values[0]);
- (dict->entries)[i].values[0] = cff_add_string(cff, str, 1);
- RELEASE(str);
- } else if (dict_operator[id].argtype == CFF_TYPE_ROS) {
- str = cff_get_string(cff, (dict->entries)[i].values[0]);
- (dict->entries)[i].values[0] = cff_add_string(cff, str, 1);
- RELEASE(str);
- str = cff_get_string(cff, (dict->entries)[i].values[1]);
- (dict->entries)[i].values[1] = cff_add_string(cff, str, 1);
- RELEASE(str);
- }
- }
- }
-}
diff --git a/Build/source/texk/dvipdfm-x/xsrc/dvipdfmx.c b/Build/source/texk/dvipdfm-x/xsrc/dvipdfmx.c
index 255bfecb79c..65c79e929b2 100644
--- a/Build/source/texk/dvipdfm-x/xsrc/dvipdfmx.c
+++ b/Build/source/texk/dvipdfm-x/xsrc/dvipdfmx.c
@@ -977,7 +977,8 @@ main (int argc, char *argv[])
* bookmark_open: Miximal depth of open bookmarks.
*/
pdf_open_document(pdf_filename, do_encryption,
- paper_width, paper_height, annot_grow, bookmark_open);
+ paper_width, paper_height, annot_grow, bookmark_open,
+ 0);
/* Ignore_colors placed here since
* they are considered as device's capacity.
diff --git a/Build/source/texk/dvipdfm-x/xsrc/jpegimage.c b/Build/source/texk/dvipdfm-x/xsrc/jpegimage.c
index 7fcdad5fa73..d1b31c214d0 100644
--- a/Build/source/texk/dvipdfm-x/xsrc/jpegimage.c
+++ b/Build/source/texk/dvipdfm-x/xsrc/jpegimage.c
@@ -339,15 +339,12 @@ jpeg_include_image (pdf_ximage *ximage, FILE *fp)
info.bits_per_component = j_info.bits_per_component;
info.num_components = j_info.num_components;
-#define IS_Exif(j) ((j).flags & HAVE_APPn_Exif)
-#define IS_JFIF(j) ((j).flags & HAVE_APPn_JFIF)
-
- if (IS_Exif(j_info)) { /* resolution data from EXIF is handled here,
- takes precedence over JFIF */
+ if (j_info.flags & HAVE_APPn_Exif) {
+ /* resolution data from EXIF is handled here, takes precedence over JFIF */
info.xdensity = 72.0 / j_info.xdpi;
info.ydensity = 72.0 / j_info.ydpi;
}
- else if (IS_JFIF(j_info)) {
+ else if (j_info.flags & HAVE_APPn_JFIF) {
int i;
for (i = 0; i < j_info.num_appn; i++) {
if (j_info.appn[i].marker == JM_APP0 && j_info.appn[i].app_sig == JS_APPn_JFIF)
@@ -376,9 +373,6 @@ jpeg_include_image (pdf_ximage *ximage, FILE *fp)
return 0;
}
-#undef IS_JFIF
-#define IS_JFIF(j) ((j)->flags & HAVE_APPn_JFIF)
-
static void
jpeg_get_density (struct JPEG_info *j_info,
double *xdensity, double *ydensity)
@@ -390,7 +384,7 @@ jpeg_get_density (struct JPEG_info *j_info,
*xdensity = *ydensity = 1.0;
- if (IS_JFIF(j_info)) {
+ if (j_info->flags & HAVE_APPn_JFIF) {
struct JPEG_APPn_JFIF *app_data;
int i;
for (i = 0; i < j_info->num_appn; i++) {
@@ -577,6 +571,7 @@ read_APP14_Adobe (struct JPEG_info *j_info, FILE *fp, unsigned short length)
return 7;
}
+#ifdef XETEX
static unsigned long
read_exif_bytes(unsigned char **p, int n, int b)
{
@@ -703,6 +698,7 @@ err:
RELEASE(buffer);
return length;
}
+#endif
static unsigned short
read_APP0_JFIF (struct JPEG_info *j_info, FILE *fp, unsigned short length)
diff --git a/Build/source/texk/dvipdfm-x/xsrc/pdfdev.c b/Build/source/texk/dvipdfm-x/xsrc/pdfdev.c
index e41024b0dbe..c5f857920e2 100644
--- a/Build/source/texk/dvipdfm-x/xsrc/pdfdev.c
+++ b/Build/source/texk/dvipdfm-x/xsrc/pdfdev.c
@@ -167,7 +167,7 @@ p_dtoa (double value, int prec, char *buf)
buf[0] = '0'; buf[1] = '\0'; n = 1;
}
- return n;
+ return n;
}
static int
@@ -1268,6 +1268,7 @@ pdf_dev_reset_fonts (void)
text_state.is_mb = 0;
}
+#ifdef XETEX
void
pdf_dev_reset_color(void)
{
@@ -1409,7 +1410,9 @@ pdf_dev_set_nonstrokingcolor (pdf_color *color)
pdf_doc_add_page_content(format_buffer, len);
return;
}
+#endif
+#if 0
/* Not working */
void
pdf_dev_set_origin (double phys_x, double phys_y)
@@ -1424,6 +1427,7 @@ pdf_dev_set_origin (double phys_x, double phys_y)
pdf_dev_concat(&M1);
}
+#endif
void
pdf_dev_bop (const pdf_tmatrix *M)
diff --git a/Build/source/texk/dvipdfm-x/xsrc/pdfdoc.c b/Build/source/texk/dvipdfm-x/xsrc/pdfdoc.c
index 539ad1ab763..73ee86c8c38 100644
--- a/Build/source/texk/dvipdfm-x/xsrc/pdfdoc.c
+++ b/Build/source/texk/dvipdfm-x/xsrc/pdfdoc.c
@@ -236,6 +236,9 @@ typedef struct pdf_doc
struct name_dict *names;
+ int check_gotos;
+ struct ht_table gotos;
+
struct {
int outline_open_depth;
double annot_grow;
@@ -368,9 +371,11 @@ doc_get_page_entry (pdf_doc *p, unsigned long page_no)
static void pdf_doc_init_page_tree (pdf_doc *p, double media_width, double media_height);
static void pdf_doc_close_page_tree (pdf_doc *p);
-static void pdf_doc_init_names (pdf_doc *p);
+static void pdf_doc_init_names (pdf_doc *p, int check_gotos);
static void pdf_doc_close_names (pdf_doc *p);
+static void pdf_doc_add_goto (pdf_obj *annot_dict);
+
static void pdf_doc_init_docinfo (pdf_doc *p);
static void pdf_doc_close_docinfo (pdf_doc *p);
@@ -1355,6 +1360,8 @@ pdf_doc_bookmarks_add (pdf_obj *dict, int is_open)
p->outlines.current = item;
+ pdf_doc_add_goto(dict);
+
return;
}
@@ -1397,7 +1404,7 @@ static const char *name_dict_categories[] = {
#define NUM_NAME_CATEGORY (sizeof(name_dict_categories)/sizeof(name_dict_categories[0]))
static void
-pdf_doc_init_names (pdf_doc *p)
+pdf_doc_init_names (pdf_doc *p, int check_gotos)
{
int i;
@@ -1411,6 +1418,9 @@ pdf_doc_init_names (pdf_doc *p)
p->names[NUM_NAME_CATEGORY].category = NULL;
p->names[NUM_NAME_CATEGORY].data = NULL;
+ p->check_gotos = check_gotos;
+ ht_init_table(&p->gotos, (void (*) (void *)) pdf_release_obj);
+
return;
}
@@ -1438,6 +1448,136 @@ pdf_doc_add_names (const char *category,
}
static void
+pdf_doc_add_goto (pdf_obj *annot_dict)
+{
+ pdf_obj *subtype = NULL, *A = NULL, *S = NULL, *D = NULL, *D_new, *dict;
+ const char *dest, *key;
+
+ if (!pdoc.check_gotos)
+ return;
+
+ /*
+ * An annotation dictionary coming from an annotation special
+ * must have a "Subtype". An annotation dictionary coming from
+ * an outline special has none.
+ */
+ subtype = pdf_deref_obj(pdf_lookup_dict(annot_dict, "Subtype"));
+ if (subtype) {
+ if (PDF_OBJ_UNDEFINED(subtype))
+ goto undefined;
+ else if (!PDF_OBJ_NAMETYPE(subtype))
+ goto error;
+ else if (strcmp(pdf_name_value(subtype), "Link"))
+ goto cleanup;
+ }
+
+ dict = annot_dict;
+ key = "Dest";
+ D = pdf_deref_obj(pdf_lookup_dict(annot_dict, key));
+ if (PDF_OBJ_UNDEFINED(D))
+ goto undefined;
+
+ A = pdf_deref_obj(pdf_lookup_dict(annot_dict, "A"));
+ if (A) {
+ if (PDF_OBJ_UNDEFINED(A))
+ goto undefined;
+ else if (D || !PDF_OBJ_DICTTYPE(A))
+ goto error;
+ else {
+ S = pdf_deref_obj(pdf_lookup_dict(A, "S"));
+ if (PDF_OBJ_UNDEFINED(S))
+ goto undefined;
+ else if (!PDF_OBJ_NAMETYPE(S))
+ goto error;
+ else if (strcmp(pdf_name_value(S), "GoTo"))
+ goto cleanup;
+
+ dict = A;
+ key = "D";
+ D = pdf_deref_obj(pdf_lookup_dict(A, key));
+ }
+ }
+
+ if (PDF_OBJ_STRINGTYPE(D))
+ dest = (char *) pdf_string_value(D);
+#if 0
+ /* Names as destinations are not supported by dvipdfmx */
+ else if (PDF_OBJ_NAMETYPE(D))
+ dest = pdf_name_value(D);
+#endif
+ else if (PDF_OBJ_ARRAYTYPE(D))
+ goto cleanup;
+ else if (PDF_OBJ_UNDEFINED(D))
+ goto undefined;
+ else
+ goto error;
+
+ D_new = ht_lookup_table(&pdoc.gotos, dest, strlen(dest));
+ if (!D_new) {
+ char buf[10];
+
+ /* We use hexadecimal notation for our numeric destinations.
+ * Other bases (e.g., 10+26 or 10+2*26) would be more efficient.
+ */
+ sprintf(buf, "%lx", ht_table_size(&pdoc.gotos));
+ D_new = pdf_new_string(buf, strlen(buf));
+ ht_append_table(&pdoc.gotos, dest, strlen(dest), D_new);
+ }
+
+ {
+ pdf_obj *key_obj = pdf_new_name(key);
+ if (!pdf_add_dict(dict, key_obj, pdf_link_obj(D_new)))
+ pdf_release_obj(key_obj);
+ }
+
+ cleanup:
+ if (subtype)
+ pdf_release_obj(subtype);
+ if (A)
+ pdf_release_obj(A);
+ if (S)
+ pdf_release_obj(S);
+ if (D)
+ pdf_release_obj(D);
+
+ return;
+
+ error:
+ WARN("Unknown PDF annotation format. Output file may be broken.");
+ goto cleanup;
+
+ undefined:
+ WARN("Cannot optimize PDF annotations. Output file may be broken."
+ " Please restart with option \"-C 0x10\"\n");
+ goto cleanup;
+}
+
+#ifndef XETEX
+static void
+warn_undef_dests (struct ht_table *dests, struct ht_table *gotos)
+{
+ struct ht_iter iter;
+
+ if (ht_set_iter(gotos, &iter) < 0)
+ return;
+
+ do {
+ int keylen;
+ char *key = ht_iter_getkey(&iter, &keylen);
+ if (!ht_lookup_table(dests, key, keylen)) {
+ char *dest = NEW(keylen+1, char);
+ memcpy(dest, key, keylen);
+ dest[keylen] = 0;
+ WARN("PDF destination \"%s\" not defined.", dest);
+ RELEASE(dest);
+ }
+ } while (ht_iter_next(&iter) >= 0);
+
+ ht_clear_iter(&iter);
+}
+#endif
+
+static void
pdf_doc_close_names (pdf_doc *p)
{
pdf_obj *tmp;
@@ -1445,15 +1585,20 @@ pdf_doc_close_names (pdf_doc *p)
for (i = 0; p->names[i].category != NULL; i++) {
if (p->names[i].data) {
+ struct ht_table *data = p->names[i].data;
pdf_obj *name_tree;
+ long count;
+
+ name_tree = pdf_names_create_tree(data, &count, NULL);
- name_tree = pdf_names_create_tree(p->names[i].data);
- if (!p->root.names) {
- p->root.names = pdf_new_dict();
+ if (name_tree) {
+ if (!p->root.names) {
+ p->root.names = pdf_new_dict();
+ }
+ pdf_add_dict(p->root.names,
+ pdf_new_name(p->names[i].category), pdf_ref_obj(name_tree));
+ pdf_release_obj(name_tree);
}
- pdf_add_dict(p->root.names,
- pdf_new_name(p->names[i].category), pdf_ref_obj(name_tree));
- pdf_release_obj(name_tree);
pdf_delete_name_tree(&p->names[i].data);
}
}
@@ -1480,12 +1625,15 @@ pdf_doc_close_names (pdf_doc *p)
RELEASE(p->names);
p->names = NULL;
+ ht_clear_table(&p->gotos);
+
return;
}
void
-pdf_doc_add_annot (unsigned page_no, const pdf_rect *rect, pdf_obj *annot_dict)
+pdf_doc_add_annot (unsigned page_no, const pdf_rect *rect,
+ pdf_obj *annot_dict, int new_annot)
{
pdf_doc *p = &pdoc;
pdf_page *page;
@@ -1496,7 +1644,6 @@ pdf_doc_add_annot (unsigned page_no, const pdf_rect *rect, pdf_obj *annot_dict)
if (!page->annots)
page->annots = pdf_new_array();
-#if 1
{
pdf_rect mediabox;
@@ -1517,7 +1664,6 @@ pdf_doc_add_annot (unsigned page_no, const pdf_rect *rect, pdf_obj *annot_dict)
rect->llx, rect->lly, rect->urx, rect->ury);
}
}
-#endif
rect_array = pdf_new_array();
pdf_add_array(rect_array, pdf_new_number(ROUND(rect->llx - annot_grow, 0.001)));
@@ -1528,6 +1674,9 @@ pdf_doc_add_annot (unsigned page_no, const pdf_rect *rect, pdf_obj *annot_dict)
pdf_add_array(page->annots, pdf_ref_obj(annot_dict));
+ if (new_annot)
+ pdf_doc_add_goto(annot_dict);
+
return;
}
@@ -2211,7 +2360,8 @@ void
pdf_open_document (const char *filename,
int do_encryption,
double media_width, double media_height,
- double annot_grow_amount, int bookmark_open_depth)
+ double annot_grow_amount, int bookmark_open_depth,
+ int check_gotos)
{
pdf_doc *p = &pdoc;
@@ -2238,14 +2388,15 @@ pdf_open_document (const char *filename,
pdf_doc_init_bookmarks(p, bookmark_open_depth);
pdf_doc_init_articles (p);
- pdf_doc_init_names (p);
+ pdf_doc_init_names (p, check_gotos);
pdf_doc_init_page_tree(p, media_width, media_height);
if (do_encryption) {
pdf_obj *encrypt = pdf_encrypt_obj();
- pdf_set_encrypt(encrypt, pdf_enc_id_array());
+ pdf_set_encrypt(encrypt);
pdf_release_obj(encrypt);
}
+ pdf_set_id(pdf_enc_id_array());
/* Create a default name for thumbnail image files */
if (manual_thumb_enabled) {
@@ -2515,8 +2666,8 @@ pdf_doc_break_annot (void)
/* Copy dict */
annot_dict = pdf_new_dict();
pdf_merge_dict(annot_dict, breaking_state.annot_dict);
- pdf_doc_add_annot(pdf_doc_current_page_number(),
- &(breaking_state.rect), annot_dict);
+ pdf_doc_add_annot(pdf_doc_current_page_number(), &(breaking_state.rect),
+ annot_dict, 0);
pdf_release_obj(annot_dict);
}
reset_box();
diff --git a/Build/source/texk/dvipdfm-x/xsrc/pdfdraw.c b/Build/source/texk/dvipdfm-x/xsrc/pdfdraw.c
index 2d1ab02c29c..334649b3bec 100644
--- a/Build/source/texk/dvipdfm-x/xsrc/pdfdraw.c
+++ b/Build/source/texk/dvipdfm-x/xsrc/pdfdraw.c
@@ -156,7 +156,7 @@ pdf_coord__itransform (pdf_coord *p, const pdf_tmatrix *M)
return 0;
}
-#endif /* 0 */
+#endif
static /* __inline__ */ int
pdf_coord__dtransform (pdf_coord *p, const pdf_tmatrix *M)
@@ -802,7 +802,7 @@ pdf_dev__rectshape (pdf_dev *P,
buf[len++] = isclip ? 'n' : 'Q';
}
- pdf_doc_add_page_content(buf, len); len = 0;
+ pdf_doc_add_page_content(buf, len); /* op: q cm n re Q */
return 0;
}
@@ -851,7 +851,8 @@ pdf_dev__flushpath (pdf_dev *P,
b[len++] = ' ';
b[len++] = 'r';
b[len++] = 'e';
- pdf_doc_add_page_content(b, len); len = 0;
+ pdf_doc_add_page_content(b, len); /* op: re */
+ len = 0;
} else {
n_seg = PA_LENGTH(pa);
for (i = 0, len = 0, pe = &pa->path[0];
@@ -865,11 +866,13 @@ pdf_dev__flushpath (pdf_dev *P,
b[len++] = ' ';
b[len++] = PE_OPCHR(pe);
if (len + 128 > b_len) {
- pdf_doc_add_page_content(b, len); len = 0;
+ pdf_doc_add_page_content(b, len); /* op: m l c v y h */
+ len = 0;
}
}
if (len > 0) {
- pdf_doc_add_page_content(b, len); len = 0;
+ pdf_doc_add_page_content(b, len); /* op: m l c v y h */
+ len = 0;
}
}
@@ -881,7 +884,7 @@ pdf_dev__flushpath (pdf_dev *P,
b[len++] = ' '; b[len++] = 'n';
}
- pdf_doc_add_page_content(b, len);
+ pdf_doc_add_page_content(b, len); /* op: f F s S b B W f* F* s* S* b* B* W* */
return 0;
}
@@ -1129,7 +1132,7 @@ pdf_dev_gsave (void)
pdf_color_copycolor(&gs1->fillcolor, fc);
m_stack_push(&gs_stack, gs1);
- pdf_doc_add_page_content(" q", 2);
+ pdf_doc_add_page_content(" q", 2); /* op: q */
return 0;
}
@@ -1148,7 +1151,7 @@ pdf_dev_grestore (void)
clear_a_gstate(gs);
RELEASE(gs);
- pdf_doc_add_page_content(" Q", 2);
+ pdf_doc_add_page_content(" Q", 2); /* op: Q */
pdf_dev_reset_fonts();
@@ -1210,7 +1213,7 @@ pdf_dev_grestore_to (int depth)
}
while (m_stack_depth(gss) > depth + 1) {
- pdf_doc_add_page_content(" Q", 2);
+ pdf_doc_add_page_content(" Q", 2); /* op: Q */
gs = m_stack_pop(gss);
clear_a_gstate(gs);
RELEASE(gs);
@@ -1265,6 +1268,63 @@ pdf_dev_currentcolor (pdf_color *color, int is_fill)
}
#endif /* 0 */
+#ifndef XETEX
+/*
+ * mask == 0 means stroking color, mask == 0x20 nonstroking color
+ *
+ * force == 1 means that operators will be generated even if
+ * the color is the same as the current graphics state color
+ */
+void
+pdf_dev_set_color (const pdf_color *color, char mask, int force)
+{
+ int len;
+
+ pdf_gstate *gs = m_stack_top(&gs_stack);
+ pdf_color *current = mask ? &gs->fillcolor : &gs->strokecolor;
+
+ ASSERT(pdf_color_is_valid(color));
+
+ if (!(pdf_dev_get_param(PDF_DEV_PARAM_COLORMODE) &&
+ (force || pdf_color_compare(color, current))))
+ /* If "color" is already the current color, then do nothing
+ * unless a color operator is forced
+ */
+ return;
+
+ graphics_mode();
+ len = pdf_color_to_string(color, fmt_buf);
+ fmt_buf[len++] = ' ';
+ switch (pdf_color_type(color)) {
+ case PDF_COLORSPACE_TYPE_RGB:
+ fmt_buf[len++] = 'R' | mask;
+ fmt_buf[len++] = 'G' | mask;
+ break;
+ case PDF_COLORSPACE_TYPE_CMYK:
+ fmt_buf[len++] = 'K' | mask;
+ break;
+ case PDF_COLORSPACE_TYPE_GRAY:
+ fmt_buf[len++] = 'G' | mask;
+ break;
+ default: /* already verified the given color */
+ break;
+ }
+ pdf_doc_add_page_content(fmt_buf, len); /* op: RG K G rg k g */
+
+ pdf_color_copycolor(current, color);
+}
+
+void
+pdf_dev_reset_color (int force)
+{
+ pdf_color *sc, *fc;
+
+ pdf_color_get_current(&sc, &fc);
+ pdf_dev_set_color(sc, 0, force);
+ pdf_dev_set_color(fc, 0x20, force);
+}
+#endif
+
int
pdf_dev_concat (const pdf_tmatrix *M)
{
@@ -1297,7 +1357,7 @@ pdf_dev_concat (const pdf_tmatrix *M)
buf[len++] = ' ';
buf[len++] = 'c';
buf[len++] = 'm';
- pdf_doc_add_page_content(buf, len);
+ pdf_doc_add_page_content(buf, len); /* op: cm */
pdf_concatmatrix(CTM, M);
}
@@ -1332,7 +1392,7 @@ pdf_dev_setmiterlimit (double mlimit)
len += pdf_sprint_length(buf + len, mlimit);
buf[len++] = ' ';
buf[len++] = 'M';
- pdf_doc_add_page_content(buf, len);
+ pdf_doc_add_page_content(buf, len); /* op: M */
gs->miterlimit = mlimit;
}
@@ -1349,7 +1409,7 @@ pdf_dev_setlinecap (int capstyle)
if (gs->linecap != capstyle) {
len = sprintf(buf, " %d J", capstyle);
- pdf_doc_add_page_content(buf, len);
+ pdf_doc_add_page_content(buf, len); /* op: J */
gs->linecap = capstyle;
}
@@ -1366,7 +1426,7 @@ pdf_dev_setlinejoin (int joinstyle)
if (gs->linejoin != joinstyle) {
len = sprintf(buf, " %d j", joinstyle);
- pdf_doc_add_page_content(buf, len);
+ pdf_doc_add_page_content(buf, len); /* op: j */
gs->linejoin = joinstyle;
}
@@ -1386,7 +1446,7 @@ pdf_dev_setlinewidth (double width)
len += pdf_sprint_length(buf + len, width);
buf[len++] = ' ';
buf[len++] = 'w';
- pdf_doc_add_page_content(buf, len);
+ pdf_doc_add_page_content(buf, len); /* op: w */
gs->linewidth = width;
}
@@ -1404,17 +1464,17 @@ pdf_dev_setdash (int count, double *pattern, double offset)
gs->linedash.num_dash = count;
gs->linedash.offset = offset;
- pdf_doc_add_page_content(" [", 2);
+ pdf_doc_add_page_content(" [", 2); /* op: */
for (i = 0; i < count; i++) {
buf[0] = ' ';
len = pdf_sprint_length (buf + 1, pattern[i]);
- pdf_doc_add_page_content(buf, len + 1);
+ pdf_doc_add_page_content(buf, len + 1); /* op: */
gs->linedash.pattern[i] = pattern[i];
}
- pdf_doc_add_page_content("] ", 2);
+ pdf_doc_add_page_content("] ", 2); /* op: */
len = pdf_sprint_length (buf, offset);
- pdf_doc_add_page_content(buf, len);
- pdf_doc_add_page_content(" d", 2);
+ pdf_doc_add_page_content(buf, len); /* op: */
+ pdf_doc_add_page_content(" d", 2); /* op: d */
return 0;
}
@@ -1434,13 +1494,13 @@ pdf_dev_setflat (int flatness)
if (gs->flatness != flatness) {
gs->flatness = flatness;
len = sprintf(buf, " %d i", flatness);
- pdf_doc_add_page_content(buf, len);
+ pdf_doc_add_page_content(buf, len); /* op: i */
}
return 0;
}
-#endif /* 0 */
-
+#endif
+
/* ZSYUEDVEDEOF */
int
pdf_dev_clip (void)
@@ -1493,7 +1553,7 @@ pdf_dev_newpath (void)
pdf_path__clearpath (p);
}
/* The following is required for "newpath" operator in mpost.c. */
- pdf_doc_add_page_content(" n", 2);
+ pdf_doc_add_page_content(" n", 2); /* op: n */
return 0;
}
@@ -1571,6 +1631,7 @@ pdf_dev_curveto (double x0, double y0,
return pdf_path__curveto(cpa, cpt, &p0, &p1, &p2);
}
+#ifdef XETEX
int
pdf_dev_vcurveto (double x0, double y0,
double x1, double y1)
@@ -1602,6 +1663,7 @@ pdf_dev_ycurveto (double x0, double y0,
return pdf_path__curveto(cpa, cpt, &p0, &p1, &p1);
}
+#endif
int
pdf_dev_rcurveto (double x0, double y0,
@@ -1690,7 +1752,7 @@ pdf_dev_itransform (pdf_coord *p, const pdf_tmatrix *M)
return;
}
-#endif /* 0 */
+#endif
int
pdf_dev_arc (double c_x , double c_y, double r,
@@ -1778,7 +1840,7 @@ pdf_dev_rectstroke (double x, double y,
return pdf_dev__rectshape(NULL, &r, M, 'S');
}
-#endif /* 0 */
+#endif
int
pdf_dev_rectfill (double x, double y,
@@ -1808,6 +1870,7 @@ pdf_dev_rectclip (double x, double y,
return pdf_dev__rectshape(NULL, &r, NULL, 'W');
}
+#ifdef XETEX
int
pdf_dev_rectadd (double x, double y,
double w, double h)
@@ -1840,3 +1903,4 @@ pdf_dev_get_fixed_point (pdf_coord *p)
p->x = gs->pt_fixee.x;
p->y = gs->pt_fixee.y;
}
+#endif
diff --git a/Build/source/texk/dvipdfm-x/xsrc/pdfencrypt.c b/Build/source/texk/dvipdfm-x/xsrc/pdfencrypt.c
deleted file mode 100644
index 8e3bf625c53..00000000000
--- a/Build/source/texk/dvipdfm-x/xsrc/pdfencrypt.c
+++ /dev/null
@@ -1,539 +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 <stdlib.h>
-#include <string.h>
-#include <time.h>
-
-#ifdef WIN32
-#include <conio.h>
-#define getch _getch
-#else /* !WIN32 */
-#include <unistd.h>
-#endif /* WIN32 */
-
-#include "system.h"
-#include "mem.h"
-#include "error.h"
-#include "pdfobj.h"
-#include "dpxcrypt.h"
-
-#include "pdfencrypt.h"
-
-#define MAX_KEY_LEN 16
-#define MAX_STR_LEN 32
-
-static unsigned char algorithm, revision, key_size;
-static unsigned long permission;
-
-static unsigned char key_data[MAX_KEY_LEN], id_string[MAX_KEY_LEN];
-static unsigned char opwd_string[MAX_STR_LEN], upwd_string[MAX_STR_LEN];
-
-static unsigned long current_label = 0;
-static unsigned current_generation = 0;
-
-static ARC4_KEY key;
-static MD5_CONTEXT md5_ctx;
-
-static unsigned char md5_buf[MAX_KEY_LEN], key_buf[MAX_KEY_LEN];
-static unsigned char in_buf[MAX_STR_LEN], out_buf[MAX_STR_LEN];
-
-static const unsigned char padding_string[MAX_STR_LEN] = {
- 0x28, 0xbf, 0x4e, 0x5e, 0x4e, 0x75, 0x8a, 0x41,
- 0x64, 0x00, 0x4e, 0x56, 0xff, 0xfa, 0x01, 0x08,
- 0x2e, 0x2e, 0x00, 0xb6, 0xd0, 0x68, 0x3e, 0x80,
- 0x2f, 0x0c, 0xa9, 0xfe, 0x64, 0x53, 0x69, 0x7a
-};
-
-static char owner_passwd[MAX_PWD_LEN], user_passwd[MAX_PWD_LEN];
-
-static unsigned char verbose = 0;
-
-void pdf_enc_set_verbose (void)
-{
- if (verbose < 255) verbose++;
-}
-
-#define PRODUCER "%s-%s, Copyright \251 2002-2010 by Jin-Hwan Cho, Matthias Franz, and Shunsaku Hirata"
-void pdf_enc_compute_id_string (char *dviname, char *pdfname)
-{
- char *date_string, *producer;
- time_t current_time;
- struct tm *bd_time;
-
- MD5_init(&md5_ctx);
-
- date_string = NEW (15, char);
- time(&current_time);
- bd_time = localtime(&current_time);
- sprintf (date_string, "%04d%02d%02d%02d%02d%02d",
- bd_time -> tm_year+1900, bd_time -> tm_mon+1, bd_time -> tm_mday,
- bd_time -> tm_hour, bd_time -> tm_min, bd_time -> tm_sec);
- MD5_write(&md5_ctx, (unsigned char *)date_string, strlen(date_string));
- RELEASE (date_string);
-
- producer = NEW (strlen(PRODUCER)+strlen(PACKAGE)+strlen(VERSION), char);
- sprintf(producer, PRODUCER, PACKAGE, VERSION);
- MD5_write(&md5_ctx, (unsigned char *)producer, strlen(producer));
- RELEASE (producer);
-
- if (dviname)
- MD5_write(&md5_ctx, (unsigned char *)dviname, strlen(dviname));
- if (pdfname)
- MD5_write(&md5_ctx, (unsigned char *)pdfname, strlen(pdfname));
- MD5_final(id_string, &md5_ctx);
-}
-
-static void passwd_padding (unsigned char *src, unsigned char *dst)
-{
- register int len = strlen((char *)src);
-
- if (len > MAX_STR_LEN)
- len = MAX_STR_LEN;
-
- memcpy(dst, src, len);
- memcpy(dst+len, padding_string, MAX_STR_LEN-len);
-}
-
-static void compute_owner_password (void)
-{
- register unsigned char i, j;
- /*
- * Algorithm 3.3 Computing the encryption dictionary's O (owner password)
- * value
- *
- * 1. Pad or truncate the owner password string as described in step 1
- * of Algorithm 3.2. If there is no owner password, use the user
- * password instead. (See implementation note 17 in Appendix H.)
- */
- passwd_padding((unsigned char *)(strlen(owner_passwd) > 0 ? owner_passwd : user_passwd), in_buf);
- /*
- * 2. Initialize the MD5 hash function and pass the result of step 1
- * as input to this function.
- */
- MD5_init(&md5_ctx);
- MD5_write(&md5_ctx, in_buf, MAX_STR_LEN);
- MD5_final(md5_buf, &md5_ctx);
- /*
- * 3. (Revision 3 only) Do the following 50 times: Take the output
- * from the previous MD5 hash and pass it as input into a new
- * MD5 hash.
- */
- if (revision == 3)
- for (i = 0; i < 50; i++) {
- /*
- * NOTE: We truncate each MD5 hash as in the following step.
- * Otherwise Adobe Reader won't decrypt the PDF file.
- */
- MD5_init(&md5_ctx);
- MD5_write(&md5_ctx, md5_buf, key_size);
- MD5_final(md5_buf, &md5_ctx);
- }
- /*
- * 4. Create an RC4 encryption key using the first n bytes of the output
- * from the final MD5 hash, where n is always 5 for revision 2 but
- * for revision 3 depends on the value of the encryption dictionary's
- * Length entry.
- */
- ARC4_set_key(&key, key_size, md5_buf);
- /*
- * 5. Pad or truncate the user password string as described in step 1
- * of Algorithm 3.2.
- */
- passwd_padding((unsigned char *)user_passwd, in_buf);
- /*
- * 6. Encrypt the result of step 5, using an RC4 encryption function
- * with the encryption key obtained in step 4.
- */
- ARC4(&key, MAX_STR_LEN, in_buf, out_buf);
- /*
- * 7. (Revision 3 only) Do the following 19 times: Take the output
- * from the previous invocation of the RC4 function and pass it
- * as input to a new invocation of the function; use an encryption
- * key generated by taking each byte of the encryption key obtained
- * in step 4 and performing an XOR (exclusive or) operation between
- * that byte and the single-byte value of the iteration counter
- * (from 1 to 19).
- */
- if (revision == 3)
- for (i = 1; i <= 19; i++) {
- memcpy(in_buf, out_buf, MAX_STR_LEN);
- for (j = 0; j < key_size; j++)
- key_buf[j] = md5_buf[j] ^ i;
- ARC4_set_key(&key, key_size, key_buf);
- ARC4(&key, MAX_STR_LEN, in_buf, out_buf);
- }
- /*
- * 8. Store the output from the final invocation of the RC4 function
- * as the value of the O entry in the encryption dictionary.
- */
- memcpy(opwd_string, out_buf, MAX_STR_LEN);
-}
-
-static void compute_encryption_key (unsigned char *pwd)
-{
- register unsigned char i;
- /*
- * Algorithm 3.2 Computing an encryption key
- *
- * 1. Pad or truncate the password string to exactly 32 bytes. If the
- * password string is more than 32 bytes long, use only its first
- * 32 bytes; if it is less than 32 bytes long, pad it by appending
- * the required number of additional bytes from the beginning of
- * the following padding string:
- *
- * < 28 BF 4E 5E 4E 75 8A 41 64 00 4E 56 FF FA 01 08
- * 2E 2E 00 B6 D0 68 3E 80 2F 0C A9 FE 64 53 69 7A >
- *
- * That is, if the password string is n bytes long, append the
- * first 32 - n bytes of the padding string to the end of the
- * password string. If the password string is empty (zero-length),
- * meaning there is no user password, substitute the entire
- * padding string in its place.
- */
- passwd_padding(pwd, in_buf);
- /*
- * 2. Initialize the MD5 hash function and pass the result of step 1
- * as input to this fuction.
- */
- MD5_init(&md5_ctx);
- MD5_write(&md5_ctx, in_buf, MAX_STR_LEN);
- /*
- * 3. Pass the value of the encryption dictionary's O entry to the
- * MD5 hash function. (Algorithm 3.3 shows how the O value is
- * computed.)
- */
- MD5_write(&md5_ctx, opwd_string, MAX_STR_LEN);
- /*
- * 4. Treat the value of the P entry as an unsigned 4-byte integer
- * and pass these bytes to the MD5 hash function, low-order byte
- * first.
- */
- in_buf[0] = (unsigned char)(permission) & 0xFF;
- in_buf[1] = (unsigned char)(permission >> 8) & 0xFF;
- in_buf[2] = (unsigned char)(permission >> 16) & 0xFF;
- in_buf[3] = (unsigned char)(permission >> 24) & 0xFF;
- MD5_write(&md5_ctx, in_buf, 4);
- /*
- * 5. Pass the first element of the file's file identifier array
- * (the value of the ID entry in the document's trailer dictionary;
- * see Table 3.12 on page 68) to the MD5 hash function and
- * finish the hash.
- */
- MD5_write(&md5_ctx, id_string, MAX_KEY_LEN);
- MD5_final(md5_buf, &md5_ctx);
- /*
- * 6. (Revision 3 only) Do the following 50 times; Take the output from
- * the previous MD5 hash and pass it as input into a new MD5 hash.
- */
- if (revision == 3)
- for (i = 0; i < 50; i++) {
- /*
- * NOTE: We truncate each MD5 hash as in the following step.
- * Otherwise Adobe Reader won't decrypt the PDF file.
- */
- MD5_init(&md5_ctx);
- MD5_write(&md5_ctx, md5_buf, key_size);
- MD5_final(md5_buf, &md5_ctx);
- }
- /*
- * 7. Set the encryption key to the first n bytes of the output from
- * the final MD5 hash, where n is always 5 for revision 2 but for
- * revision 3 depends on the value of the encryption dictionary's
- * Length entry.
- */
- memcpy(key_data, md5_buf, key_size);
-}
-
-static void compute_user_password (void)
-{
- register unsigned char i, j;
- /*
- * Algorithm 3.4 Computing the encryption dictionary's U (user password)
- * value (Revision 2)
- *
- * 1. Create an encryption key based on the user password string, as
- * described in Algorithm 3.2.
- *
- * 2. Encrypt the 32-byte padding string shown in step 1 of Algorithm
- * 3.2, using an RC4 encryption fuction with the encryption key from
- * the preceeding step.
- *
- * 3. Store the result of step 2 as the value of the U entry in the
- * encryption dictionary.
- */
- /*
- * Algorithm 3.5 Computing the encryption dictionary's U (user password)
- * value (Revision 3)
- *
- * 1. Create an encryption key based on the user password string, as
- * described in Algorithm 3.2.
- *
- * 2. Initialize the MD5 hash function and pass the 32-byte padding
- * string shown in step 1 of Algorithm 3.2 as input to this function.
- *
- * 3. Pass the first element of the file's file identifier array (the
- * value of the ID entry in the document's trailer dictionary; see
- * Table 3.12 on page 68) to the hash function and finish the hash.
- *
- * 4. Encrypt the 16-byte result of the hash, using an RC4 encryption
- * function with the encryption key from step 1.
- *
- * 5. Do the following 19 times: Take the output from the previous
- * invocation of the RC4 function and pass it as input to a new
- * invocation of the function; use an encryption key generated by
- * taking each byte of the original encryption key (obtained in
- * step 1) and performing an XOR (exclusive or) operation between
- * that byte and the single-byte value of the iteration counter
- * (from 1 to 19).
- *
- * 6. Append 16 bytes of arbitrary padding to the output from the
- * final invocation of the RC4 function and store the 32-byte
- * result as the value of the U entry in the encryption dictionary.
- */
- compute_encryption_key((unsigned char *)user_passwd);
-
- switch (revision) {
- case 2:
- ARC4_set_key(&key, key_size, key_data);
- ARC4(&key, MAX_STR_LEN, padding_string, out_buf);
- break;
- case 3:
- MD5_init(&md5_ctx);
- MD5_write(&md5_ctx, padding_string, MAX_STR_LEN);
-
- MD5_write(&md5_ctx, id_string, MAX_KEY_LEN);
- MD5_final(md5_buf, &md5_ctx);
-
- ARC4_set_key(&key, key_size, key_data);
- ARC4(&key, MAX_KEY_LEN, md5_buf, out_buf);
-
- for (i = 1; i <= 19; i++) {
- memcpy(in_buf, out_buf, MAX_KEY_LEN);
- for (j = 0; j < key_size; j++)
- key_buf[j] = key_data[j] ^ i;
- ARC4_set_key(&key, key_size, key_buf);
- ARC4(&key, MAX_KEY_LEN, in_buf, out_buf);
- }
- break;
- default:
- ERROR("Invalid revision number.\n");
- }
-
- memcpy(upwd_string, out_buf, MAX_STR_LEN);
-}
-
-#ifdef WIN32
-static char *getpass (const char *prompt)
-{
- static char pwd_buf[128];
- size_t i;
-
- fputs(prompt, stderr);
- fflush(stderr);
- for (i = 0; i < sizeof(pwd_buf)-1; i++) {
- pwd_buf[i] = getch();
- if (pwd_buf[i] == '\r')
- break;
- fputs("*", stderr);
- fflush(stderr);
- }
- pwd_buf[i] = '\0';
- fputs("\n", stderr);
- return pwd_buf;
-}
-#endif
-
-void pdf_enc_set_passwd (unsigned bits, unsigned perm, const char *owner_pw, const char *user_pw)
-{
- char *retry_passwd;
-
- if (owner_pw) {
- strncpy(owner_passwd, owner_pw, MAX_PWD_LEN);
- } else
- while (1) {
- strncpy(owner_passwd, getpass("Owner password: "), MAX_PWD_LEN);
- retry_passwd = getpass("Re-enter owner password: ");
- if (!strncmp(owner_passwd, retry_passwd, MAX_PWD_LEN))
- break;
- fputs("Password is not identical.\nTry again.\n", stderr);
- fflush(stderr);
- }
-
- if (user_pw) {
- strncpy(user_passwd, user_pw, MAX_PWD_LEN);
- } else
- while (1) {
- strncpy(user_passwd, getpass("User password: "), MAX_PWD_LEN);
- retry_passwd = getpass("Re-enter user password: ");
- if (!strncmp(user_passwd, retry_passwd, MAX_PWD_LEN))
- break;
- fputs("Password is not identical.\nTry again.\n", stderr);
- fflush(stderr);
- }
-
- key_size = (unsigned char)(bits / 8);
- algorithm = (key_size == 5 ? 1 : 2);
- permission = (unsigned long)perm | 0x000000C0;
- revision = ((algorithm == 1 && permission < 0x100) ? 2 : 3);
- if (revision == 3)
- permission |= 0xFFFFF000;
-
- compute_owner_password();
- compute_user_password();
-}
-
-void pdf_encrypt_data (unsigned char *data, unsigned long len)
-{
- unsigned char *result;
-
- memcpy(in_buf, key_data, key_size);
- in_buf[key_size] = (unsigned char)(current_label) & 0xFF;
- in_buf[key_size+1] = (unsigned char)(current_label >> 8) & 0xFF;
- in_buf[key_size+2] = (unsigned char)(current_label >> 16) & 0xFF;
- in_buf[key_size+3] = (unsigned char)(current_generation) & 0xFF;
- in_buf[key_size+4] = (unsigned char)(current_generation >> 8) & 0xFF;
-
- MD5_init(&md5_ctx);
- MD5_write(&md5_ctx, in_buf, key_size+5);
- MD5_final(md5_buf, &md5_ctx);
-
- result = NEW (len, unsigned char);
- ARC4_set_key(&key, (key_size > 10 ? MAX_KEY_LEN : key_size+5), md5_buf);
- ARC4(&key, len, data, result);
- memcpy(data, result, len);
- RELEASE (result);
-}
-
-pdf_obj *pdf_encrypt_obj (void)
-{
- pdf_obj *doc_encrypt;
-
-#ifdef DEBUG
- fprintf (stderr, "(pdf_encrypt_obj)");
-#endif
-
- doc_encrypt = pdf_new_dict ();
-
- /* KEY : Filter
- * TYPE : name
- * VALUE: (Required) The name of the security handler for this document;
- * see below. Default value: Standard, for the built-in security
- * handler.
- */
- pdf_add_dict (doc_encrypt,
- pdf_new_name ("Filter"),
- pdf_new_name ("Standard"));
- /* KEY : V
- * TYPE : number
- * VALUE: (Optional but strongly recommended) A code specifying the
- * algorithm to be used in encrypting and decrypting the document:
- * 0 An algorithm that is undocumented and no longer supported,
- * and whose use is strongly discouraged.
- * 1 Algorithm 3.1 on page 73, with an encryption key length
- * of 40 bits; see below.
- * 2 (PDF 1.4) Algorithm 3.1 on page 73, but allowing encryption
- * key lengths greater than 40 bits.
- * 3 (PDF 1.4) An unpublished algorithm allowing encryption key
- * lengths ranging from 40 to 128 bits. (This algorithm is
- * unpublished as an export requirement of the U.S. Department
- * of Commerce.)
- * The default value if this entry is omitted is 0, but a value
- * of 1 or greater is strongly recommended.
- */
- pdf_add_dict (doc_encrypt,
- pdf_new_name ("V"),
- pdf_new_number (algorithm));
- /* KEY : Length
- * TYPE : integer
- * VALUE: (Optional; PDF 1.4; only if V is 2 or 3) The length of the
- * encryption key, in bits. The value must be a multiple of 8,
- * in the range 40 to 128. Default value: 40.
- */
- if (algorithm > 1)
- pdf_add_dict (doc_encrypt,
- pdf_new_name ("Length"),
- pdf_new_number (key_size * 8));
- /* KEY : R
- * TYPE : number
- * VALUE: (Required) A number specifying which revision of the standard
- * security handler should be used to interpret this dictionary.
- * The revison number should be 2 if the document is encrypted
- * with a V value less than 2; otherwise this value should be 3.
- */
- pdf_add_dict (doc_encrypt,
- pdf_new_name ("R"),
- pdf_new_number (revision));
- /* KEY : O
- * TYPE : string
- * VALUE: (Required) A 32-byte string, based on both the owner and
- * user passwords, that is used in computing the encryption
- * key and in determining whether a valid owner password was
- * entered.
- */
- pdf_add_dict (doc_encrypt,
- pdf_new_name ("O"),
- pdf_new_string (opwd_string, 32));
- /* KEY : U
- * TYPE : string
- * VALUE: (Required) A 32-byte string, based on the user password,
- * that is used in determining whether to prompt the user
- * for a password and, if so, whether a valid user or owner
- * password was entered.
- */
- pdf_add_dict (doc_encrypt,
- pdf_new_name ("U"),
- pdf_new_string (upwd_string, 32));
- /* KEY : P
- * TYPE : integer
- * VALUE: (Required) A set of flags specifying which operations are
- * permitted when the document is opened with user access.
- */
- pdf_add_dict (doc_encrypt,
- pdf_new_name ("P"),
- pdf_new_number (permission));
-
- return doc_encrypt;
-}
-
-pdf_obj *pdf_enc_id_array (void)
-{
- pdf_obj *id = pdf_new_array();
- pdf_add_array(id, pdf_new_string(id_string, MAX_KEY_LEN));
- pdf_add_array(id, pdf_new_string(id_string, MAX_KEY_LEN));
- return id;
-}
-
-void pdf_enc_set_label (unsigned long label)
-{
- current_label = label;
-}
-
-void pdf_enc_set_generation (unsigned generation)
-{
- current_generation = generation;
-}
diff --git a/Build/source/texk/dvipdfm-x/xsrc/pdfnames.c b/Build/source/texk/dvipdfm-x/xsrc/pdfnames.c
index 1aa9d1096dd..c898dedfb31 100644
--- a/Build/source/texk/dvipdfm-x/xsrc/pdfnames.c
+++ b/Build/source/texk/dvipdfm-x/xsrc/pdfnames.c
@@ -74,6 +74,7 @@ printable_key (const char *key, int keylen)
return (char *) pkey;
}
+#ifdef XETEX
static void
flush_objects (struct ht_table *ht_tab)
{
@@ -104,6 +105,7 @@ flush_objects (struct ht_table *ht_tab)
ht_clear_iter(&iter);
}
}
+#endif
static void CDECL
hval_free (void *hval)
@@ -136,6 +138,32 @@ pdf_new_name_tree (void)
return names;
}
+#ifndef XETEX
+static void
+check_objects_defined (struct ht_table *ht_tab)
+{
+ struct ht_iter iter;
+
+ if (ht_set_iter(ht_tab, &iter) >= 0) {
+ do {
+ char *key;
+ int keylen;
+ struct obj_data *value;
+
+ key = ht_iter_getkey(&iter, &keylen);
+ value = ht_iter_getval(&iter);
+ ASSERT(value->object);
+ if (PDF_OBJ_UNDEFINED(value->object)) {
+ pdf_names_add_object(ht_tab, key, keylen, pdf_new_null());
+ WARN("Object @%s used, but not defined. Replaced by null.",
+ printable_key(key, keylen));
+ }
+ } while (ht_iter_next(&iter) >= 0);
+ ht_clear_iter(&iter);
+ }
+}
+#endif
+
void
pdf_delete_name_tree (struct ht_table **names)
{
@@ -189,6 +217,7 @@ pdf_names_add_object (struct ht_table *names,
return 0;
}
+#ifdef XETEX
int
pdf_names_add_reference (struct ht_table *names,
const void *key, int keylen, pdf_obj *object_ref)
@@ -225,6 +254,7 @@ pdf_names_add_reference (struct ht_table *names,
return 0;
}
+#endif
/*
* The following routine returns copies, not the original object.
@@ -415,7 +445,8 @@ build_name_tree (struct named_object *first, long num_leaves, int is_root)
}
static struct named_object *
-flat_table (struct ht_table *ht_tab, long *num_entries)
+flat_table (struct ht_table *ht_tab, long *num_entries,
+ struct ht_table *filter)
{
struct named_object *objects;
struct ht_iter iter;
@@ -465,21 +496,21 @@ flat_table (struct ht_table *ht_tab, long *num_entries)
}
pdf_obj *
-pdf_names_create_tree (struct ht_table *names)
+pdf_names_create_tree (struct ht_table *names, long *count,
+ struct ht_table *filter)
{
pdf_obj *name_tree;
struct named_object *flat;
- long count;
- flat = flat_table(names, &count);
+ flat = flat_table(names, count, filter);
if (!flat)
name_tree = NULL;
else {
- if (count < 1)
+ if (*count < 1)
name_tree = NULL;
else {
- qsort(flat, count, sizeof(struct named_object), cmp_key);
- name_tree = build_name_tree(flat, count, 1);
+ qsort(flat, *count, sizeof(struct named_object), cmp_key);
+ name_tree = build_name_tree(flat, *count, 1);
}
RELEASE(flat);
}
diff --git a/Build/source/texk/dvipdfm-x/xsrc/pdfnames.h b/Build/source/texk/dvipdfm-x/xsrc/pdfnames.h
deleted file mode 100644
index ca4a7dbc0bf..00000000000
--- a/Build/source/texk/dvipdfm-x/xsrc/pdfnames.h
+++ /dev/null
@@ -1,52 +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_NAMES_H_
-#define _PDF_NAMES_H_
-
-/* Hash */
-#include "dpxutil.h"
-#include "pdfobj.h"
-
-/* Not actually tree... */
-extern struct ht_table *pdf_new_name_tree (void);
-extern void pdf_delete_name_tree (struct ht_table **names);
-
-extern int pdf_names_add_object (struct ht_table *names,
- const void *key, int keylen, pdf_obj *object);
-extern int pdf_names_add_reference (struct ht_table *names,
- const void *key, int keylen, pdf_obj *object_ref);
-extern pdf_obj *pdf_names_lookup_reference (struct ht_table *names,
- const void *key, int keylen);
-extern pdf_obj *pdf_names_lookup_object (struct ht_table *names,
- const void *key, int keylen);
-extern int pdf_names_close_object (struct ht_table *names,
- const void *key, int keylen);
-
-/* Really create name tree... */
-extern pdf_obj *pdf_names_create_tree (struct ht_table *names);
-
-extern char *printable_key (const char *key, int keylen);
-
-#endif /* _PDF_NAMES_H_ */
diff --git a/Build/source/texk/dvipdfm-x/xsrc/pdfobj.c b/Build/source/texk/dvipdfm-x/xsrc/pdfobj.c
index 0861c46278a..3f97ee28928 100644
--- a/Build/source/texk/dvipdfm-x/xsrc/pdfobj.c
+++ b/Build/source/texk/dvipdfm-x/xsrc/pdfobj.c
@@ -180,6 +180,8 @@ static pdf_obj *xref_stream;
/* Internal static routines */
+static int check_for_pdf_version (FILE *file);
+
static void pdf_flush_obj (pdf_obj *object, FILE *file);
static void pdf_label_obj (pdf_obj *object);
static void pdf_write_obj (pdf_obj *object, FILE *file);
@@ -511,14 +513,20 @@ pdf_set_info (pdf_obj *object)
}
void
-pdf_set_encrypt (pdf_obj *encrypt, pdf_obj *id)
+pdf_set_id (pdf_obj *id)
+{
+ if (pdf_add_dict(trailer_dict, pdf_new_name("ID"), id)) {
+ ERROR ("ID already set!");
+ }
+}
+
+void
+pdf_set_encrypt (pdf_obj *encrypt)
{
if (pdf_add_dict(trailer_dict, pdf_new_name("Encrypt"), pdf_ref_obj(encrypt))) {
ERROR("Encrypt object already set!");
}
encrypt->flags |= OBJ_NO_ENCRYPT;
-
- pdf_add_dict(trailer_dict, pdf_new_name("ID"), id);
}
static
@@ -634,8 +642,25 @@ pdf_label_obj (pdf_obj *object)
}
}
+#ifndef XETEX
/*
- * This doesn't really copy the object, but allows it to be used without
+ * Transfer the label assigned to the object src to the object dst.
+ * The object dst must not yet have been labeled.
+ */
+void
+pdf_transfer_label (pdf_obj *dst, pdf_obj *src)
+{
+ ASSERT(dst && !dst->label && src);
+
+ dst->label = src->label;
+ dst->generation = src->generation;
+ src->label = 0;
+ src->generation = 0;
+}
+#endif
+
+/*
+ * This doesn't really copy the object, but allows it to be used without
* fear that somebody else will free it.
*/
pdf_obj *
@@ -689,6 +714,22 @@ write_indirect (pdf_indirect *indirect, FILE *file)
pdf_out(file, format_buffer, length);
}
+#ifndef XETEX
+/* The undefined object is used as a placeholder in pdfnames.c
+ * for objects which are referenced before they are defined.
+ */
+pdf_obj *
+pdf_new_undefined (void)
+{
+ pdf_obj *result;
+
+ result = pdf_new_obj(PDF_UNDEFINED);
+ result->data = NULL;
+
+ return result;
+}
+#endif
+
pdf_obj *
pdf_new_null (void)
{
@@ -2113,6 +2154,7 @@ pdf_release_obj (pdf_obj *object)
}
}
+#ifdef XETEX
/* Copy object data without changing object label. */
void
pdf_copy_object (pdf_obj *dst, pdf_obj *src)
@@ -2208,6 +2250,7 @@ pdf_copy_object (pdf_obj *dst, pdf_obj *src)
return;
}
+#endif
static int
backup_line (FILE *pdf_input_file)
@@ -2941,8 +2984,11 @@ pdf_file_free (pdf_file *pf)
pdf_release_obj(pf->xref_table[i].indirect);
}
- RELEASE(pf->xref_table);
- pdf_release_obj(pf->trailer);
+ RELEASE(pf->xref_table);
+ if (pf->trailer) {
+ pdf_release_obj(pf->trailer);
+ pf->trailer = NULL;
+ }
RELEASE(pf);
}
@@ -2990,8 +3036,9 @@ pdf_open (const char *ident, FILE *file)
if (pf) {
pf->file = file;
} else {
- int version = check_for_pdf(file);
- if (!version) {
+ int version = check_for_pdf_version(file);
+
+ if (version < 0 || version > 5) {
WARN("pdf_open: Not a PDF 1.[1-5] file.");
return NULL;
}
@@ -3026,24 +3073,31 @@ pdf_files_close (void)
RELEASE(pdf_files);
}
+static int
+check_for_pdf_version (FILE *file)
+{
+ unsigned int minor;
+
+ rewind(file);
+
+ return (ungetc(fgetc(file), file) == '%' &&
+ fscanf(file, "%%PDF-1.%u", &minor) == 1) ? minor : -1;
+}
+
int
check_for_pdf (FILE *file)
{
- int result = 0;
+ int version = check_for_pdf_version(file);
- rewind(file);
- if (fread(work_buffer, sizeof(char), strlen("%PDF-1.x"), file) ==
- strlen("%PDF-1.x") &&
- !strncmp(work_buffer, "%PDF-1.", strlen("%PDF-1."))) {
- if (work_buffer[7] >= '0' && work_buffer[7] <= '0' + pdf_version)
- result = 1;
- else {
- WARN("Version of PDF file (1.%c) is newer than version limit specification.",
- work_buffer[7]);
- }
- }
+ if (version < 0) /* not a PDF file */
+ return 0;
- return result;
+ if (version <= pdf_version)
+ return 1;
+
+ WARN("Version of PDF file (1.%c) is newer than version limit specification.",
+ pdf_version);
+ return 0;
}
static int CDECL
diff --git a/Build/source/texk/dvipdfm-x/xsrc/pdfximage.c b/Build/source/texk/dvipdfm-x/xsrc/pdfximage.c
index 3774fa14fac..13efb1136a8 100644
--- a/Build/source/texk/dvipdfm-x/xsrc/pdfximage.c
+++ b/Build/source/texk/dvipdfm-x/xsrc/pdfximage.c
@@ -474,11 +474,13 @@ pdf_ximage_init_image_info (ximage_info *info)
info->xdensity = info->ydensity = 1.0;
}
+#ifdef XETEX
char *
pdf_ximage_get_ident (pdf_ximage *I)
{
return I->ident;
}
+#endif
void
pdf_ximage_set_image (pdf_ximage *I, void *image_info, pdf_obj *resource)
@@ -608,6 +610,39 @@ pdf_ximage_get_resname (int id)
return I->res_name;
}
+#ifndef XETEX
+int
+pdf_ximage_get_subtype (int id)
+{
+ struct ic_ *ic = &_ic;
+ pdf_ximage *I;
+
+ CHECK_ID(ic, id);
+
+ I = GET_IMAGE(ic, id);
+
+ return I->subtype;
+}
+
+void
+pdf_ximage_set_attr (int id, long width, long height, double xdensity, double ydensity, double llx, double lly, double urx, double ury)
+{
+ struct ic_ *ic = &_ic;
+ pdf_ximage *I;
+
+ CHECK_ID(ic, id);
+
+ I = GET_IMAGE(ic, id);
+ I->attr.width = width;
+ I->attr.height = height;
+ I->attr.xdensity = xdensity;
+ I->attr.ydensity = ydensity;
+ I->attr.bbox.llx = llx;
+ I->attr.bbox.lly = lly;
+ I->attr.bbox.urx = urx;
+ I->attr.bbox.ury = ury;
+}
+#endif
/* depth...
* Dvipdfm treat "depth" as "yoffset" for pdf:image and pdf:uxobj
@@ -823,10 +858,12 @@ void set_distiller_template (char *s)
return;
}
+#ifdef XETEX
char *get_distiller_template (void)
{
return _opts.cmdtmpl;
}
+#endif
static int
ps_include_page (pdf_ximage *ximage, const char *filename)
diff --git a/Build/source/texk/dvipdfm-x/xsrc/spc_dvips.c b/Build/source/texk/dvipdfm-x/xsrc/spc_dvips.c
deleted file mode 100644
index 0b30570a27c..00000000000
--- a/Build/source/texk/dvipdfm-x/xsrc/spc_dvips.c
+++ /dev/null
@@ -1,1075 +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 <string.h>
-
-#include "system.h"
-#include "mem.h"
-#include "error.h"
-
-#include "dpxfile.h"
-
-#include "dvi.h"
-#include "dvicodes.h"
-
-#include "pdfparse.h"
-
-#include "pdfdoc.h"
-
-#include "mpost.h"
-
-#include "pdfximage.h"
-#include "pdfdraw.h"
-#include "pdfcolor.h"
-#include "pdfdev.h"
-
-#include "specials.h"
-#include "spc_util.h"
-#include "mfileio.h"
-
-#include "spc_dvips.h"
-#include "spc_xtx.h"
-
-#include "epdf.h"
-
-static int block_pending = 0;
-static double pending_x = 0.0;
-static double pending_y = 0.0;
-static int position_set = 0;
-
-static char** ps_headers = 0;
-static int num_ps_headers = 0;
-
-static int
-spc_handler_ps_header (struct spc_env *spe, struct spc_arg *args)
-{
- char *ps_header, *pro;
-
- skip_white(&args->curptr, args->endptr);
- if (args->curptr + 1 >= args->endptr ||
- args->curptr[0] != '=') {
- spc_warn(spe, "No filename specified for PSfile special.");
- return -1;
- }
- args->curptr++;
-
- pro = malloc(args->endptr - args->curptr + 1);
- strncpy(pro, args->curptr, args->endptr - args->curptr);
- pro[args->endptr - args->curptr] = 0;
- ps_header = kpse_find_file(pro, kpse_tex_ps_header_format, 0);
- if (!ps_header) {
- spc_warn(spe, "PS header %s not found.", pro);
- return -1;
- }
- free(pro);
-
- if (!(num_ps_headers & 0x0f))
- ps_headers = realloc(ps_headers, sizeof(char*) * (num_ps_headers + 16));
- ps_headers[num_ps_headers++] = ps_header;
- args->curptr = args->endptr;
- return 0;
-}
-
-static char *
-parse_filename (const char **pp, const char *endptr)
-{
- char *r;
- const char *q = NULL, *p = *pp;
- char qchar;
- int n;
-
- if (!p || p >= endptr)
- return NULL;
- else if (*p == '\"' || *p == '\'')
- qchar = *p++;
- else {
- qchar = ' ';
- }
- for (n = 0, q = p; p < endptr && *p != qchar; n++, p++);
- if (qchar != ' ') {
- if (*p != qchar)
- return NULL;
- p++;
- }
- if (!q || n == 0)
- return NULL;
-
-#if 0
- {
- int i;
- for (i = 0; i < n && isprint(q[i]); i++);
- if (i != n) {
- WARN("Non printable char in filename string...");
- }
- }
-#endif
-
- r = NEW(n + 1, char);
- memcpy(r, q, n); r[n] = '\0';
-
- *pp = p;
- return r;
-}
-
-/* =filename ... */
-static int
-spc_handler_ps_file (struct spc_env *spe, struct spc_arg *args)
-{
- int form_id;
- char *filename;
- transform_info ti;
-
- ASSERT(spe && args);
-
- skip_white(&args->curptr, args->endptr);
- if (args->curptr + 1 >= args->endptr ||
- args->curptr[0] != '=') {
- spc_warn(spe, "No filename specified for PSfile special.");
- return -1;
- }
- args->curptr++;
-
- filename = parse_filename(&args->curptr, args->endptr);
- if (!filename) {
- spc_warn(spe, "No filename specified for PSfile special.");
- return -1;
- }
-
- transform_info_clear(&ti);
- if (spc_util_read_dimtrns(spe, &ti, args, NULL, 1) < 0) {
- RELEASE(filename);
- return -1;
- }
-
- form_id = pdf_ximage_findresource(filename, 1, NULL);
- if (form_id < 0) {
- spc_warn(spe, "Failed to read image file: %s", filename);
- RELEASE(filename);
- return -1;
- }
- RELEASE(filename);
-
- pdf_dev_put_image(form_id, &ti, spe->x_user, spe->y_user);
-
- return 0;
-}
-
-/* This isn't correct implementation but dvipdfm supports... */
-static int
-spc_handler_ps_plotfile (struct spc_env *spe, struct spc_arg *args)
-{
- int error = 0;
- int form_id;
- char *filename;
- transform_info p;
-
- ASSERT(spe && args);
-
- spc_warn(spe, "\"ps: plotfile\" found (not properly implemented)");
-
- skip_white(&args->curptr, args->endptr);
- filename = parse_filename(&args->curptr, args->endptr);
- if (!filename) {
- spc_warn(spe, "Expecting filename but not found...");
- return -1;
- }
-
- form_id = pdf_ximage_findresource(filename, 1, NULL);
- if (form_id < 0) {
- spc_warn(spe, "Could not open PS file: %s", filename);
- error = -1;
- } else {
- transform_info_clear(&p);
- p.matrix.d = -1.0; /* xscale = 1.0, yscale = -1.0 */
-#if 0
- /* I don't know how to treat this... */
- pdf_dev_put_image(form_id, &p,
- block_pending ? pending_x : spe->x_user,
- block_pending ? pending_y : spe->y_user);
-#endif
- pdf_dev_put_image(form_id, &p, 0, 0);
- }
- RELEASE(filename);
-
- return error;
-}
-
-static int
-spc_handler_ps_literal (struct spc_env *spe, struct spc_arg *args)
-{
- int error = 0;
- int st_depth, gs_depth;
- double x_user, y_user;
-
- ASSERT(spe && args && args->curptr <= args->endptr);
-
- if (args->curptr + strlen(":[begin]") <= args->endptr &&
- !strncmp(args->curptr, ":[begin]", strlen(":[begin]"))) {
- block_pending++;
- position_set = 1;
-
- x_user = pending_x = spe->x_user;
- y_user = pending_y = spe->y_user;
- args->curptr += strlen(":[begin]");
- } else if (args->curptr + strlen(":[end]") <= args->endptr &&
- !strncmp(args->curptr, ":[end]", strlen(":[end]"))) {
- if (block_pending <= 0) {
- spc_warn(spe, "No corresponding ::[begin] found.");
- return -1;
- }
- block_pending--;
-
- position_set = 0;
-
- x_user = pending_x;
- y_user = pending_y;
- args->curptr += strlen(":[end]");
- } else if (args->curptr < args->endptr &&
- args->curptr[0] == ':') {
- x_user = position_set ? pending_x : spe->x_user;
- y_user = position_set ? pending_y : spe->y_user;
- args->curptr++;
- } else {
- position_set = 1;
- x_user = pending_x = spe->x_user;
- y_user = pending_y = spe->y_user;
- }
-
- skip_white(&args->curptr, args->endptr);
- if (args->curptr < args->endptr) {
-
- st_depth = mps_stack_depth();
- gs_depth = pdf_dev_current_depth();
-
- error = mps_exec_inline(&args->curptr,
- args->endptr,
- x_user, y_user);
- if (error) {
- spc_warn(spe, "Interpreting PS code failed!!! Output might be broken!!!");
- pdf_dev_grestore_to(gs_depth);
- } else if (st_depth != mps_stack_depth()) {
- spc_warn(spe, "Stack not empty after execution of inline PostScript code.");
- spc_warn(spe, ">> Your macro package makes some assumption on internal behaviour of DVI drivers.");
- spc_warn(spe, ">> It may not compatible with dvipdfmx.");
- }
- }
-
- return error;
-}
-
-static char *global_defs = 0;
-static char *page_defs = 0;
-static char *temporary_defs = 0;
-static char *distiller_template = 0;
-static pdf_coord *put_stack;
-static int put_stack_depth = -1;
-static char *gs_in = 0;
-
-#if 0
-/* Not used */
-static int
-spc_handler_ps_tricks_gdef (struct spc_env *spe, struct spc_arg *args)
-{
- FILE* fp;
-
- fp = fopen(global_defs, "ab");
- fwrite(args->curptr, 1, args->endptr - args->curptr, fp);
- fprintf(fp, "\n");
- fclose(fp);
-
- return 0;
-}
-#endif
-
-static int
-spc_handler_ps_tricks_pdef (struct spc_env *spe, struct spc_arg *args)
-{
- FILE* fp;
- pdf_tmatrix M, T = { 1, 0, 0, 1, 0, 0 };
- pdf_coord pt;
-
- pdf_dev_currentmatrix(&M);
- pdf_dev_get_fixed_point(&pt);
- T.e = pt.x;
- T.f = pt.y;
- pdf_concatmatrix(&M, &T);
-
- if (!page_defs)
- page_defs = dpx_create_temp_file();
- if (!page_defs) {
- WARN("Failed to create temporary input file for PSTricks image conversion.");
- return -1;
- }
-
- fp = fopen(page_defs, "ab");
- fprintf(fp, "gsave initmatrix [%f %f %f %f %f %f] concat %f %f moveto\n", M.a, M.b, M.c, M.d, M.e, M.f, spe->x_user - pt.x, spe->y_user - pt.y);
- fwrite(args->curptr, 1, args->endptr - args->curptr, fp);
- fprintf(fp, "\ngrestore\n");
- fclose(fp);
-
- return 0;
-}
-
-static int
-spc_handler_ps_tricks_tdef (struct spc_env *spe, struct spc_arg *args)
-{
- FILE* fp;
- if (!temporary_defs)
- temporary_defs = dpx_create_temp_file();
- if (!temporary_defs) {
- WARN("Failed to create temporary input file for PSTricks image conversion.");
- return -1;
- }
-
- fp = fopen(temporary_defs, "wb");
- fwrite(args->curptr, 1, args->endptr - args->curptr, fp);
- fprintf(fp, "\n");
- fclose(fp);
-
- return 0;
-}
-
-static int calculate_PS (char *string, int length, double *res1, double *res2, double *res3, double *res4, double *res5, double *res6);
-
-static int
-spc_handler_ps_tricks_bput (struct spc_env *spe, struct spc_arg *args, int must_def, int pre_def)
-{
- char *PutBegin, *formula, *ncLabel;
- int label = 0;
- pdf_coord tr;
- pdf_tmatrix M, T = { 1, 0, 0, 1, 0, 0 };
-
- if (must_def != 0) {
- ncLabel = strstr(args->curptr, "LPut");
- if (ncLabel != 0 && ncLabel < args->endptr - 3)
- label = 1;
- ncLabel = strstr(args->curptr, "HPutPos");
- if (ncLabel != 0 && ncLabel < args->endptr - 6)
- label = 1;
- }
-
- if (pre_def == 0) {
- dpx_delete_temp_file(temporary_defs, true);
- temporary_defs = 0;
- }
-
- pdf_dev_currentmatrix(&M);
- formula = malloc(args->endptr - args->curptr + 120);
- if (label != 0) {
- sprintf(formula, "[%f %f %f %f %f %f] concat %f %f moveto\n", M.a, M.b, M.c, M.d, M.e, M.f, spe->x_user + get_origin(1), spe->y_user + get_origin(0));
- } else
- sprintf(formula, "[%f %f %f %f %f %f] concat %f %f moveto\n", M.a, M.b, M.c, M.d, M.e, M.f, spe->x_user, spe->y_user);
- strncat(formula, args->curptr, args->endptr - args->curptr);
- PutBegin = strstr(formula, "PutBegin");
- strcpy(PutBegin, "exch = =");
- *(PutBegin + 8) = 0;
- if (calculate_PS(formula, strlen(formula), &tr.x, &tr.y, 0, 0, 0, 0) == 0) {
- if (!(++put_stack_depth & 0x0f))
- put_stack = realloc(put_stack, (put_stack_depth + 16) * sizeof(pdf_coord));
- put_stack[put_stack_depth] = tr;
- }
- T.e = tr.x; T.f = tr.y;
-
- pdf_dev_concat(&T);
-
- if (must_def != 0) {
- FILE* fp;
- if (!temporary_defs)
- temporary_defs = dpx_create_temp_file();
- if (!temporary_defs) {
- WARN("Failed to create temporary input file for PSTricks image conversion.");
- return -1;
- }
-
- fp = fopen(temporary_defs, "ab");
- fprintf(fp, "gsave\n");
- if (label == 0)
- fprintf(fp, "[%f %f %f %f %f %f] concat %f %f moveto\n", M.a, M.b, M.c, M.d, M.e, M.f, spe->x_user, spe->y_user);
- fwrite(args->curptr, 1, args->endptr - args->curptr, fp);
- fprintf(fp, "\ngrestore\n");
- fclose(fp);
- }
-
- free(formula);
- return 0;
-}
-
-static int
-spc_handler_ps_tricks_eput (struct spc_env *spe, struct spc_arg *args)
-{
- pdf_coord tr = put_stack[put_stack_depth--];
- pdf_tmatrix M = { 1, 0, 0, 1, -tr.x, -tr.y };
-
- pdf_dev_concat(&M);
-
- return 0;
-}
-
-/* Rotation without gsave/grestore. */
-static double* RAngles = 0;
-static int RAngleCount = -1;
-
-static int
-spc_handler_ps_tricks_brotate (struct spc_env *spe, struct spc_arg *args)
-{
- double value, RAngle = 0;
- char *cmd, *RotBegin;
- int i, l = args->endptr - args->curptr;
-
- static const char *pre = "tx@Dict begin /RAngle { %f } def\n";
- static const char *post = "= end";
-
- if (!(++RAngleCount & 0x0f))
- RAngles = realloc(RAngles, (RAngleCount + 16) * sizeof(double));
- for (i = 0; i < RAngleCount; i++)
- RAngle += RAngles[i];
- cmd = calloc(l + strlen(pre) + strlen(post) + 12, 1);
- sprintf(cmd, pre, RAngle);
- strncat(cmd, args->curptr, l);
- RotBegin = strstr(cmd, "RotBegin");
- strcpy(RotBegin, post);
- if (calculate_PS(cmd, strlen(cmd), &value, 0, 0, 0, 0, 0) != 0)
- return -1;
- RAngles[RAngleCount] = value;
-
- return spc_handler_xtx_do_transform (spe->x_user, spe->y_user,
- cos(value * M_PI / 180), sin(value * M_PI / 180),
- -sin(value * M_PI / 180), cos(value * M_PI / 180),
- 0, 0);
-}
-
-static int
-spc_handler_ps_tricks_erotate (struct spc_env *spe, struct spc_arg *args)
-{
- double value = RAngles[RAngleCount--];
-
- return spc_handler_xtx_do_transform (spe->x_user, spe->y_user,
- cos(value * M_PI / 180), -sin(value * M_PI / 180),
- sin(value * M_PI / 180), cos(value * M_PI / 180),
- 0, 0);
-}
-
-static int
-spc_handler_ps_tricks_transform (struct spc_env *spe, struct spc_arg *args)
-{
- double d1, d2, d3, d4, d5, d6;
- char *cmd, *concat;
- int l = args->endptr - args->curptr;
-
- static const char *post = "concat matrix currentmatrix ==";
-
- cmd = calloc(l + 41, 1);
- strncpy(cmd, "matrix setmatrix ", 17);
- strncpy(cmd + 17, args->curptr, l);
- concat = strstr(cmd, "concat");
- if (concat != 0) {
- strcpy(concat, post);
- concat[strlen(post)] = 0;
- concat = strstr(cmd, "{");
- *concat = ' ';
- if (calculate_PS(cmd, strlen(cmd), &d1, &d2, &d3, &d4, &d5, &d6) != 0)
- return -1;
- if (spc_handler_xtx_gsave (0, 0) != 0)
- return -1;
- return spc_handler_xtx_do_transform (spe->x_user, spe->y_user, d1, d2, d3, d4, d5, d6);
- }
- return spc_handler_xtx_grestore (0, 0);
-}
-
-static int
-check_next_obj(const unsigned char * buffer)
-{
- switch (buffer[0]) {
- case XXX1:
- if (buffer[1] < 5)
- return 0;
- buffer += 2;
- break;
- case XXX2:
- buffer += 3;
- break;
- case XXX3:
- buffer += 4;
- break;
- case XXX4:
- buffer += 5;
- break;
- default:
- return 0;
- }
-
- if (strncmp((const char*)buffer, "pst:", 4))
- return 0;
- return 1;
-}
-
-static int
-spc_handler_ps_tricks_parse_path (struct spc_env *spe, struct spc_arg *args,
- int flag)
-{
- FILE* fp;
- int k;
- pdf_tmatrix M;
- char *distiller_template = get_distiller_template();
- char *gs_out;
- const char *clip;
- int error;
-
- if (!distiller_template)
- distiller_template = get_distiller_template();
-
- pdf_dev_currentmatrix(&M);
- if (!gs_in) {
- gs_in = dpx_create_temp_file();
- if (!gs_in) {
- WARN("Failed to create temporary input file for PSTricks image conversion.");
- return -1;
- }
- fp = fopen(gs_in, "wb");
- for (k = 0; k < num_ps_headers; k++)
- fprintf(fp, "(%s) run\n", ps_headers[k]);
- fprintf(fp, "[%f %f %f %f %f %f] concat %f %f translate 0 0 moveto\n", M.a, M.b, M.c, M.d, M.e, M.f, spe->x_user, spe->y_user);
- fprintf(fp, "(%s) run\n", global_defs);
- if (page_defs != 0)
- fprintf(fp, "(%s) run\n", page_defs);
-
-#if 0
- fprintf(fp, "/clip {stroke} def\n");
- fwrite(args->curptr, 1, args->endptr - args->curptr, fp);
-#else
- clip = strstr(args->curptr, " clip");
- if (clip == 0 || clip > args->endptr - 5) {
- fprintf(fp, "tx@TextPathDict begin /stroke {} def\n");
- fwrite(args->curptr, 1, args->endptr - args->curptr, fp);
- fprintf(fp, "\nend\n");
- fclose(fp);
- return 0;
- } else {
- fwrite(args->curptr, 1, clip - args->curptr, fp);
- fprintf(fp, " stroke ");
- skip_white(&clip, args->endptr);
- parse_ident(&clip, args->endptr);
- fwrite(clip, 1, args->endptr - clip, fp);
- }
-#endif
- } else {
- fp = fopen(gs_in, "ab");
- fprintf(fp, "flattenpath stroke\n");
- }
- fclose(fp);
-
- gs_out = dpx_create_temp_file();
- if (!gs_out) {
- WARN("Failed to create temporary output file for PSTricks image conversion.");
- RELEASE(gs_in);
- gs_in = 0;
- return -1;
- }
-#ifdef MIKTEX
- {
- char *p;
- for (p = (char *)gs_in; *p; p++) {
- if (*p == '\\') *p = '/';
- }
- for (p = (char *)gs_out; *p; p++) {
- if (*p == '\\') *p = '/';
- }
- }
-#endif
- error = dpx_file_apply_filter(distiller_template, gs_in, gs_out,
- (unsigned char) pdf_get_version());
- if (error) {
- WARN("Image format conversion for PSTricks failed.");
- RELEASE(gs_in);
- gs_in = 0;
- return error;
- }
-
- fp = fopen(gs_out, "rb");
- if (pdf_copy_clip(fp, 1, 0, 0) != 0) {
- spc_warn(spe, "Failed to parse the clipping path.");
- RELEASE(gs_in);
- gs_in = 0;
- RELEASE(gs_out);
- return -1;
- }
- fclose(fp);
-
- dpx_delete_temp_file(gs_out, true);
- dpx_delete_temp_file(gs_in, true);
- gs_in = 0;
-
- return 0;
-}
-
-static int
-spc_handler_ps_tricks_render (struct spc_env *spe, struct spc_arg *args)
-{
- FILE* fp;
- int k;
- pdf_tmatrix M;
-
- if (!distiller_template)
- distiller_template = get_distiller_template();
-
- pdf_dev_currentmatrix(&M);
- if (!gs_in) {
- gs_in = dpx_create_temp_file();
- if (!gs_in) {
- WARN("Failed to create temporary input file for PSTricks image conversion.");
- return -1;
- }
- fp = fopen(gs_in, "wb");
- for (k = 0; k < num_ps_headers; k++)
- fprintf(fp, "(%s) run\n", ps_headers[k]);
- fprintf(fp, "[%f %f %f %f %f %f] concat %f %f translate 0 0 moveto\n", M.a, M.b, M.c, M.d, M.e, M.f, spe->x_user, spe->y_user);
- fprintf(fp, "(%s) run\n", global_defs);
- if (page_defs != 0)
- fprintf(fp, "(%s) run\n", page_defs);
- } else
- fp = fopen(gs_in, "ab");
-
- fprintf(fp, "\nsave\n");
- fwrite(args->curptr, 1, args->endptr - args->curptr, fp);
- fprintf(fp, "\ncount 1 sub {pop} repeat restore\n");
-
- if (check_next_obj((const unsigned char*)args->endptr)) {
- fclose(fp);
- } else {
- char *distiller_template = get_distiller_template();
- char *gs_out;
- int error, form_id;
- transform_info p;
- transform_info_clear(&p);
- pdf_invertmatrix(&M);
- p.matrix = M;
-
- fclose(fp);
-
- gs_out = dpx_create_temp_file();
- if (!gs_out) {
- WARN("Failed to create temporary output file for PSTricks image conversion.");
- RELEASE(gs_in);
- gs_in = 0;
- return -1;
- }
-#ifdef MIKTEX
- {
- char *p;
- for (p = (char *)gs_in; *p; p++) {
- if (*p == '\\') *p = '/';
- }
- for (p = (char *)gs_out; *p; p++) {
- if (*p == '\\') *p = '/';
- }
- }
-#endif
- error = dpx_file_apply_filter(distiller_template, gs_in, gs_out,
- (unsigned char) pdf_get_version());
- if (error) {
- WARN("Image format conversion for PSTricks failed.");
- RELEASE(gs_in);
- gs_in = 0;
- return error;
- }
-
- form_id = pdf_ximage_findresource(gs_out, 1, NULL);
- if (form_id < 0) {
- spc_warn(spe, "Failed to read converted PSTricks image file.");
- RELEASE(gs_in);
- gs_in = 0;
- RELEASE(gs_out);
- return -1;
- }
- pdf_dev_put_image(form_id, &p, 0, 0);
-
- dpx_delete_temp_file(gs_out, true);
- dpx_delete_temp_file(gs_in, true);
- gs_in = 0;
- }
-
- return 0;
-}
-
-typedef enum {
- render = 1 << 0,
- global_def = 1 << 1,
- page_def = 1 << 2,
- new_temp = 1 << 3,
- add_temp = 1 << 4,
- begin_put = 1 << 5,
- end_put = 1 << 6,
- begin_rotate = 1 << 7,
- end_rotate = 1 << 8,
- parse = 1 << 9,
- req_ref = 1 << 10,
- transform = 1 << 11
-} Operation;
-
-/* ToDo: all the substring search must be centralized so that *
- * keys can be read from external configuration. */
-struct pstricks_key_ {
- const char * key;
- Operation exec;
-} pstricks_key[] = {
- /* The first 5 are hard-coded here. */
- {"LPut", add_temp | req_ref},
- {"HPutPos", add_temp | req_ref},
- {"PutBegin", begin_put},
- {"RotBegin", begin_rotate},
- {"clip", parse},
- /* The rest can be read from an external source. */
- {"NewNode", page_def | req_ref},
- {"InitNC", render | new_temp},
- {"/Glbx", add_temp},
- {"NewtonSolving", add_temp},
- {"tx@LightThreeDDict", page_def},
- {"PutEnd", end_put},
- {"RotEnd", end_rotate},
- {"mtrxc", parse},
- {"stroke", render},
- {"fill", render},
- {"Fill", render},
- {" Glbx", req_ref},
- {"TextPathShow", parse},
- {"/rotAngle", page_def},
- {"NAngle", req_ref},
- {"TMatrix", transform}
-};
-
-static int
-spc_handler_ps_trickscmd (struct spc_env *spe, struct spc_arg *args)
-{
- char *test_string;
- int k, error = 0, f_exec = 0;
-
- /* Hack time! */
- /* The problem is that while any macros in pstricks.tex
- * can be overridden by the codes in pstricks.con, you cannot
- * modify the pst@Verb specials generated by other PSTricks
- * packages. So pstricks generate specials won't signal what
- * to expect for you.
- */
- test_string = malloc(args->endptr - args->curptr + 1);
- strncpy(test_string, args->curptr, args->endptr - args->curptr);
- test_string[args->endptr - args->curptr] = 0;
- for (k = 0; k < sizeof(pstricks_key) / sizeof(pstricks_key[0]); k++) {
- if (strstr(test_string, pstricks_key[k].key) != 0)
- f_exec |= pstricks_key[k].exec;
- }
- free(test_string);
-
- if (f_exec & new_temp)
- error |= spc_handler_ps_tricks_tdef(spe, args);
- if (f_exec & render)
- error |= spc_handler_ps_tricks_render(spe, args);
- if (f_exec & parse)
- error |= spc_handler_ps_tricks_parse_path(spe, args, f_exec);
- if (f_exec & begin_put)
- error |= spc_handler_ps_tricks_bput(spe, args, (f_exec & add_temp), (f_exec & req_ref));
- if (f_exec & end_put)
- error |= spc_handler_ps_tricks_eput(spe, args);
- if (f_exec & begin_rotate)
- error |= spc_handler_ps_tricks_brotate(spe, args);
- if (f_exec & end_rotate)
- error |= spc_handler_ps_tricks_erotate(spe, args);
- if (f_exec & transform)
- error |= spc_handler_ps_tricks_transform(spe, args);
- if (f_exec & page_def)
- error |= spc_handler_ps_tricks_pdef (spe, args);
- if (f_exec == 0)
- error |= spc_handler_ps_tricks_pdef (spe, args);
-
- args->curptr = args->endptr;
- return error;
-}
-
-static int
-spc_handler_ps_tricksobj (struct spc_env *spe, struct spc_arg *args)
-{
- int error = spc_handler_ps_tricks_render(spe, args);
- args->curptr = args->endptr;
- return error;
-}
-
-static int
-spc_handler_ps_default (struct spc_env *spe, struct spc_arg *args)
-{
- int error;
- int st_depth, gs_depth;
-
- ASSERT(spe && args);
-
- pdf_dev_gsave();
-
- st_depth = mps_stack_depth();
- gs_depth = pdf_dev_current_depth();
-
- {
- pdf_tmatrix M;
- M.a = M.d = 1.0; M.b = M.c = 0.0; M.e = spe->x_user; M.f = spe->y_user;
- pdf_dev_concat(&M);
- error = mps_exec_inline(&args->curptr,
- args->endptr,
- spe->x_user, spe->y_user);
- M.e = -spe->x_user; M.f = -spe->y_user;
- pdf_dev_concat(&M);
- }
- if (error)
- spc_warn(spe, "Interpreting PS code failed!!! Output might be broken!!!");
- else {
- if (st_depth != mps_stack_depth()) {
- spc_warn(spe, "Stack not empty after execution of inline PostScript code.");
- spc_warn(spe, ">> Your macro package makes some assumption on internal behaviour of DVI drivers.");
- spc_warn(spe, ">> It may not compatible with dvipdfmx.");
- }
- }
-
- pdf_dev_grestore_to(gs_depth);
- pdf_dev_grestore();
-
- return error;
-}
-
-static struct spc_handler dvips_handlers[] = {
- {"header", spc_handler_ps_header},
- {"PSfile", spc_handler_ps_file},
- {"psfile", spc_handler_ps_file},
- {"ps: plotfile ", spc_handler_ps_plotfile},
- {"PS: plotfile ", spc_handler_ps_plotfile},
- {"PS:", spc_handler_ps_literal},
- {"ps:", spc_handler_ps_literal},
- {"PST:", spc_handler_ps_trickscmd},
- {"pst:", spc_handler_ps_tricksobj},
- {"\" ", spc_handler_ps_default}
-};
-
-#ifdef XETEX
-int
-spc_dvips_at_begin_document (void)
-{
- FILE* fp;
-
- /* This, together with \pscharpath support code, must be moved to xtex.pro header. */
- global_defs = dpx_create_temp_file();
- if (!global_defs) {
- WARN("Failed to create temporary input file for PSTricks image conversion.");
- return -1;
- }
-
- fp = fopen(global_defs, "wb");
- fprintf(fp, "tx@Dict begin /STV {} def end\n");
- fclose(fp);
- return 0;
-}
-
-int
-spc_dvips_at_end_document (void)
-{
- if (ps_headers) {
- while (num_ps_headers > 0)
- RELEASE(ps_headers[--num_ps_headers]);
- free(ps_headers);
- ps_headers = NULL;
- }
- dpx_delete_temp_file(global_defs, true);
- dpx_delete_temp_file(page_defs, true);
- return 0;
-}
-
-int
-spc_dvips_at_begin_page (void)
-{
- if (page_defs) {
- dpx_delete_temp_file(page_defs, true);
- page_defs = 0;
- }
-
- put_stack_depth = -1;
-
- return 0;
-}
-#endif
-
-int
-spc_dvips_at_end_page (void)
-{
- mps_eop_cleanup();
-#ifdef XETEX
- if (!temporary_defs) {
- dpx_delete_temp_file(temporary_defs, true);
- temporary_defs = 0;
- }
-#endif
- return 0;
-}
-
-int
-spc_dvips_check_special (const char *buf, long len)
-{
- const char *p, *endptr;
- int i;
-
- p = buf;
- endptr = p + len;
-
- skip_white(&p, endptr);
- if (p >= endptr)
- return 0;
-
- len = (long) (endptr - p);
- for (i = 0;
- i < sizeof(dvips_handlers)/sizeof(struct spc_handler); i++) {
- if (len >= strlen(dvips_handlers[i].key) &&
- !memcmp(p, dvips_handlers[i].key,
- strlen(dvips_handlers[i].key))) {
- return 1;
- }
- }
-
- return 0;
-}
-
-int
-spc_dvips_setup_handler (struct spc_handler *handle,
- struct spc_env *spe, struct spc_arg *args)
-{
- const char *key;
- int i, keylen;
-
- ASSERT(handle && spe && args);
-
- skip_white(&args->curptr, args->endptr);
-
- key = args->curptr;
- while (args->curptr < args->endptr &&
- isalpha(args->curptr[0])) {
- args->curptr++;
- }
- /* Test for "ps:". The "ps::" special is subsumed under this case. */
- if (args->curptr < args->endptr &&
- args->curptr[0] == ':') {
- args->curptr++;
- if (args->curptr+strlen(" plotfile ") <= args->endptr &&
- !strncmp(args->curptr, " plotfile ", strlen(" plotfile "))) {
- args->curptr += strlen(" plotfile ");
- }
- } else if (args->curptr+1 < args->endptr &&
- args->curptr[0] == '"' && args->curptr[1] == ' ') {
- args->curptr += 2;
- }
-
- keylen = (int) (args->curptr - key);
- if (keylen < 1) {
- spc_warn(spe, "Not ps: special???");
- return -1;
- }
-
- for (i = 0;
- i < sizeof(dvips_handlers) / sizeof(struct spc_handler); i++) {
- if (keylen <= strlen(dvips_handlers[i].key) &&
- !strncmp(key, dvips_handlers[i].key, strlen(dvips_handlers[i].key))) {
-
- skip_white(&args->curptr, args->endptr);
-
- args->command = dvips_handlers[i].key;
-
- handle->key = "ps:";
- handle->exec = dvips_handlers[i].exec;
-
- return 0;
- }
- }
-
- return -1;
-}
-
-#ifdef __EMX__
-#define GS_CALCULATOR "gsos2 -q -dNOPAUSE -dBATCH -sDEVICE=nullpage -f "
-#elif defined(WIN32)
-#define GS_CALCULATOR "gswin32c -q -dNOPAUSE -dBATCH -sDEVICE=nullpage -f "
-#else
-#define GS_CALCULATOR "gs -q -dNOPAUSE -dBATCH -sDEVICE=nullpage -f "
-#endif
-
-static
-int calculate_PS (char *string, int length, double *res1, double *res2, double *res3, double *res4, double *res5, double *res6) {
- char *formula, *cmd;
- FILE *fp, *coord;
- int k;
-
- if (res1 == 0 && res2 == 0)
- return -1;
- formula = dpx_create_temp_file();
- if (!formula) {
- WARN("Failed to create temporary input file for PSTricks image conversion.");
- return -1;
- }
-
- fp = fopen(formula, "wb");
- for (k = 0; k < num_ps_headers; k++)
- fprintf(fp, "(%s) run\n", ps_headers[k]);
- fprintf(fp, "0 0 moveto\n");
- fprintf(fp, "(%s) run\n", global_defs);
- if (page_defs != 0)
- fprintf(fp, "(%s) run\n", page_defs);
- if (temporary_defs)
- fprintf(fp, "(%s) run\n", temporary_defs);
- fwrite(string, 1, length, fp);
- fclose(fp);
-#ifdef MIKTEX
- {
- char *p;
- for (p = formula; *p; p++)
- if (*p == '\\')
- *p = '/';
- }
-#endif
- k = strlen(GS_CALCULATOR) + strlen(formula) + 1;
- cmd = NEW(k, char);
- strcpy(cmd, GS_CALCULATOR);
- strcat(cmd, formula);
-
- coord = popen(cmd, "r");
- if (coord) {
- if (res1 == 0)
- fscanf(coord, " %lf ", res2);
- else if (res2 == 0)
- fscanf(coord, " %lf ", res1);
- else if (res3 == 0)
- fscanf(coord, " %lf %lf ", res1, res2);
- else
- fscanf(coord, " [%lf %lf %lf %lf %lf %lf] ", res1, res2, res3, res4, res5, res6);
- } else
- return -1;
-
- pclose(coord);
- RELEASE(cmd);
- dpx_delete_temp_file(formula, true);
- return 0;
-}
diff --git a/Build/source/texk/dvipdfm-x/xsrc/spc_pdfm.c b/Build/source/texk/dvipdfm-x/xsrc/spc_pdfm.c
index fb307523dcf..f522fbeb7eb 100644
--- a/Build/source/texk/dvipdfm-x/xsrc/spc_pdfm.c
+++ b/Build/source/texk/dvipdfm-x/xsrc/spc_pdfm.c
@@ -54,6 +54,7 @@
#include "spc_util.h"
#include "spc_pdfm.h"
+#include "dvipdfmx.h"
#define ENABLE_TOUNICODE 1
@@ -116,7 +117,7 @@ addresource (struct spc_pdf_ *sd, const char *ident, int res_id)
ht_append_table(sd->resourcemap, ident, strlen(ident), r);
spc_push_object(ident, pdf_ximage_get_reference(res_id));
- return 0;
+ return 0;
}
static int
@@ -159,7 +160,7 @@ spc_handler_pdfm__init (struct spc_env *spe, struct spc_arg *ap, void *dp)
}
#endif /* ENABLE_TOUNICODE */
- return 0;
+ return 0;
}
static int
@@ -185,7 +186,7 @@ spc_handler_pdfm__clean (struct spc_env *spe, struct spc_arg *ap, void *dp)
sd->cd.taintkeys = NULL;
#endif /* ENABLE_TOUNICODE */
- return 0;
+ return 0;
}
@@ -215,7 +216,7 @@ spc_handler_pdfm_bop (struct spc_env *spe, struct spc_arg *args)
args->curptr = args->endptr;
- return 0;
+ return 0;
}
static int
@@ -228,7 +229,7 @@ spc_handler_pdfm_eop (struct spc_env *spe, struct spc_arg *args)
args->curptr = args->endptr;
- return 0;
+ return 0;
}
#define streamfiltered(o) \
@@ -249,7 +250,7 @@ safeputresdent (pdf_obj *kp, pdf_obj *vp, void *dp)
pdf_add_dict(dp,
pdf_link_obj(kp), pdf_link_obj(vp));
}
- return 0;
+ return 0;
}
#ifndef pdf_obj_isaref
@@ -280,7 +281,7 @@ safeputresdict (pdf_obj *kp, pdf_obj *vp, void *dp)
return -1;
}
- return 0;
+ return 0;
}
@@ -415,9 +416,10 @@ reencodestring (CMap *cmap, pdf_obj *instring)
pdf_set_string(instring, wbuf, WBUF_SIZE - obufleft);
- return 0;
+ return 0;
}
+#ifdef XETEX
/* tables/values used in UTF-8 interpretation -
code is based on ConvertUTF.[ch] sample code
published by the Unicode consortium */
@@ -508,6 +510,7 @@ maybe_reencode_utf8(pdf_obj *instring)
return 0;
}
+#endif
static int
needreencode (pdf_obj *kp, pdf_obj *vp, struct tounicode *cd)
@@ -543,6 +546,7 @@ static int
modstrings (pdf_obj *kp, pdf_obj *vp, void *dp)
{
int r = 0; /* continue */
+ struct tounicode *cd = dp;
ASSERT( pdf_obj_typeof(kp) == PDF_NAME );
@@ -550,7 +554,7 @@ modstrings (pdf_obj *kp, pdf_obj *vp, void *dp)
case PDF_STRING:
{
CMap *cmap;
- struct tounicode *cd = dp;
+
if (cd && cd->cmap_id >= 0 && cd->taintkeys) {
cmap = CMap_cache_get(cd->cmap_id);
if (needreencode(kp, vp, cd)) {
@@ -580,8 +584,9 @@ my_parse_pdf_dict (const char **pp, const char *endptr, struct tounicode *cd)
{
pdf_obj *dict;
-#if 0
+#ifdef XETEX
/* disable this test, as we do utf8 reencoding with no cmap */
+#else
if (cd->cmap_id < 0)
return parse_pdf_dict(pp, endptr, NULL);
#endif
@@ -670,7 +675,7 @@ spc_handler_pdfm_annot (struct spc_env *spe, struct spc_arg *args)
if (ident)
spc_push_object(ident, pdf_link_obj(annot_dict));
/* This add reference. */
- pdf_doc_add_annot(pdf_doc_current_page_number(), &rect, annot_dict);
+ pdf_doc_add_annot(pdf_doc_current_page_number(), &rect, annot_dict, 0);
if (ident) {
spc_flush_object(ident);
@@ -678,7 +683,7 @@ spc_handler_pdfm_annot (struct spc_env *spe, struct spc_arg *args)
}
pdf_release_obj(annot_dict);
- return 0;
+ return 0;
}
/* NOTE: This can't have ident. See "Dvipdfm User's Manual". */
@@ -762,7 +767,10 @@ spc_handler_pdfm_bcolor (struct spc_env *spe, struct spc_arg *ap)
return error;
}
-/* Different than "color rgb 1 0 0" ? */
+/*
+ * This special changes the current color without clearing the color stack.
+ * It therefore differs from "color rgb 1 0 0".
+ */
static int
spc_handler_pdfm_scolor (struct spc_env *spe, struct spc_arg *ap)
{
@@ -793,7 +801,7 @@ static int
spc_handler_pdfm_ecolor (struct spc_env *spe, struct spc_arg *args)
{
pdf_color_pop();
- return 0;
+ return 0;
}
@@ -816,7 +824,7 @@ spc_handler_pdfm_btrans (struct spc_env *spe, struct spc_arg *args)
pdf_dev_gsave();
pdf_dev_concat(&M);
- return 0;
+ return 0;
}
static int
@@ -834,7 +842,7 @@ spc_handler_pdfm_etrans (struct spc_env *spe, struct spc_arg *args)
pdf_dev_reset_fonts();
pdf_dev_reset_color();
- return 0;
+ return 0;
}
static int
@@ -912,7 +920,7 @@ spc_handler_pdfm_outline (struct spc_env *spe, struct spc_arg *args)
pdf_doc_bookmarks_add(item_dict, is_open);
- return 0;
+ return 0;
}
static int
@@ -947,7 +955,7 @@ spc_handler_pdfm_article (struct spc_env *spe, struct spc_arg *args)
spc_push_object(ident, info_dict);
RELEASE(ident);
- return 0;
+ return 0;
}
static int
@@ -1034,7 +1042,7 @@ spc_handler_pdfm_bead (struct spc_env *spe, struct spc_arg *args)
pdf_doc_add_bead(article_name, NULL, page_no, &rect);
RELEASE(article_name);
- return 0;
+ return 0;
}
static int
@@ -1109,7 +1117,7 @@ spc_handler_pdfm_image (struct spc_env *spe, struct spc_arg *args)
pdf_release_obj(fspec);
- return 0;
+ return 0;
}
/* Use do_names instead. */
@@ -1117,7 +1125,6 @@ static int
spc_handler_pdfm_dest (struct spc_env *spe, struct spc_arg *args)
{
pdf_obj *name, *array;
- int error = 0;
skip_white(&args->curptr, args->endptr);
@@ -1130,14 +1137,17 @@ spc_handler_pdfm_dest (struct spc_env *spe, struct spc_arg *args)
pdf_release_obj(name);
return -1;
}
+
+#ifdef XETEX
#ifdef ENABLE_TOUNICODE
- error = maybe_reencode_utf8(name);
- if (error < 0)
+ if (maybe_reencode_utf8(name) < 0)
WARN("Failed to convert input string to UTF16...");
#endif
+#endif
+
array = parse_pdf_object(&args->curptr, args->endptr, NULL);
if (!array) {
- spc_warn(spe, "Destination not specified for pdf:dest.");
+ spc_warn(spe, "No destination specified for pdf:dest.");
pdf_release_obj(name);
return -1;
} else if (!PDF_OBJ_ARRAYTYPE(array)) {
@@ -1147,13 +1157,13 @@ spc_handler_pdfm_dest (struct spc_env *spe, struct spc_arg *args)
return -1;
}
- error = pdf_doc_add_names("Dests",
- pdf_string_value (name),
- pdf_string_length(name),
- array);
+ pdf_doc_add_names("Dests",
+ pdf_string_value (name),
+ pdf_string_length(name),
+ array);
pdf_release_obj(name);
- return 0;
+ return 0;
}
static int
@@ -1232,7 +1242,7 @@ spc_handler_pdfm_names (struct spc_env *spe, struct spc_arg *args)
}
pdf_release_obj(category);
- return 0;
+ return 0;
}
static int
@@ -1257,7 +1267,7 @@ spc_handler_pdfm_docinfo (struct spc_env *spe, struct spc_arg *args)
pdf_merge_dict(docinfo, dict);
pdf_release_obj(dict);
- return 0;
+ return 0;
}
static int
@@ -1290,7 +1300,7 @@ spc_handler_pdfm_docview (struct spc_env *spe, struct spc_arg *args)
pdf_merge_dict (catalog, dict);
pdf_release_obj(dict);
- return 0;
+ return 0;
}
static int
@@ -1307,7 +1317,7 @@ spc_handler_pdfm_close (struct spc_env *spe, struct spc_arg *args)
spc_clear_objects();
}
- return 0;
+ return 0;
}
static int
@@ -1333,7 +1343,7 @@ spc_handler_pdfm_object (struct spc_env *spe, struct spc_arg *args)
}
RELEASE(ident);
- return 0;
+ return 0;
}
static int
@@ -1355,14 +1365,14 @@ spc_handler_pdfm_content (struct spc_env *spe, struct spc_arg *args)
work_buffer[len++] = 'm';
work_buffer[len++] = ' ';
- pdf_doc_add_page_content(work_buffer, len);
+ pdf_doc_add_page_content(work_buffer, len); /* op: q cm */
len = (long) (args->endptr - args->curptr);
- pdf_doc_add_page_content(args->curptr, len);
- pdf_doc_add_page_content(" Q", 2);
+ pdf_doc_add_page_content(args->curptr, len); /* op: ANY */
+ pdf_doc_add_page_content(" Q", 2); /* op: Q */
}
args->curptr = args->endptr;
- return 0;
+ return 0;
}
static int
@@ -1393,8 +1403,8 @@ spc_handler_pdfm_literal (struct spc_env *spe, struct spc_arg *args)
M.e = spe->x_user; M.f = spe->y_user;
pdf_dev_concat(&M);
}
- pdf_doc_add_page_content(" ", 1);
- pdf_doc_add_page_content(args->curptr, (long) (args->endptr - args->curptr));
+ pdf_doc_add_page_content(" ", 1); /* op: */
+ pdf_doc_add_page_content(args->curptr, (long) (args->endptr - args->curptr)); /* op: ANY */
if (!direct) {
M.e = -spe->x_user; M.f = -spe->y_user;
pdf_dev_concat(&M);
@@ -1403,7 +1413,7 @@ spc_handler_pdfm_literal (struct spc_env *spe, struct spc_arg *args)
args->curptr = args->endptr;
- return 0;
+ return 0;
}
static int
@@ -1417,7 +1427,7 @@ spc_handler_pdfm_bcontent (struct spc_env *spe, struct spc_arg *args)
pdf_setmatrix(&M, 1.0, 0.0, 0.0, 1.0, spe->x_user - xpos, spe->y_user - ypos);
pdf_dev_concat(&M);
pdf_dev_push_coord(spe->x_user, spe->y_user);
- return 0;
+ return 0;
}
static int
@@ -1425,7 +1435,7 @@ spc_handler_pdfm_econtent (struct spc_env *spe, struct spc_arg *args)
{
pdf_dev_pop_coord();
pdf_dev_grestore();
- return 0;
+ return 0;
}
static int
@@ -1434,19 +1444,19 @@ spc_handler_pdfm_code (struct spc_env *spe, struct spc_arg *args)
skip_white(&args->curptr, args->endptr);
if (args->curptr < args->endptr) {
- pdf_doc_add_page_content(" ", 1);
- pdf_doc_add_page_content(args->curptr, (long) (args->endptr - args->curptr));
+ pdf_doc_add_page_content(" ", 1); /* op: */
+ pdf_doc_add_page_content(args->curptr, (long) (args->endptr - args->curptr)); /* op: ANY */
args->curptr = args->endptr;
}
- return 0;
+ return 0;
}
static int
spc_handler_pdfm_do_nothing (struct spc_env *spe, struct spc_arg *args)
{
args->curptr = args->endptr;
- return 0;
+ return 0;
}
#define STRING_STREAM 0
@@ -1559,7 +1569,7 @@ spc_handler_pdfm_stream_with_type (struct spc_env *spe, struct spc_arg *args, in
spc_push_object(ident, fstream);
RELEASE(ident);
- return 0;
+ return 0;
}
/*
@@ -1662,7 +1672,7 @@ spc_handler_pdfm_bform (struct spc_env *spe, struct spc_arg *args)
spc_push_object(ident, pdf_ximage_get_reference(xobj_id));
RELEASE(ident);
- return 0;
+ return 0;
}
/* An extra dictionary after exobj must be merged to the form dictionary,
@@ -1685,7 +1695,7 @@ spc_handler_pdfm_eform (struct spc_env *spe, struct spc_arg *args)
}
pdf_doc_end_grabbing(attrib);
- return 0;
+ return 0;
}
/* Saved XObjects can be used as follows:
@@ -1751,7 +1761,7 @@ spc_handler_pdfm_uxobj (struct spc_env *spe, struct spc_arg *args)
pdf_dev_put_image(xobj_id, &ti, spe->x_user, spe->y_user);
RELEASE(ident);
- return 0;
+ return 0;
}
static int
@@ -1774,7 +1784,7 @@ spc_handler_pdfm_pagesize (struct spc_env *spe, struct spc_arg *args)
{
args->curptr = args->endptr;
- return 0;
+ return 0;
}
/* Please remove this.
@@ -1854,7 +1864,7 @@ spc_handler_pdfm_mapline (struct spc_env *spe, struct spc_arg *ap)
if (!error)
ap->curptr = ap->endptr;
- return 0;
+ return 0;
}
static int
diff --git a/Build/source/texk/dvipdfm-x/xsrc/spc_tpic.c b/Build/source/texk/dvipdfm-x/xsrc/spc_tpic.c
index a63e61554f1..1e5f196e737 100644
--- a/Build/source/texk/dvipdfm-x/xsrc/spc_tpic.c
+++ b/Build/source/texk/dvipdfm-x/xsrc/spc_tpic.c
@@ -201,6 +201,60 @@ set_fillstyle (double g, double a, int f_ais)
return 0;
}
+static void
+set_styles (struct spc_tpic_ *tp,
+ const pdf_coord *c,
+ int f_fs,
+ int f_vp,
+ double pn,
+ double da) {
+ pdf_tmatrix M;
+
+ pdf_setmatrix (&M, 1.0, 0.0, 0.0, -1.0, c->x, c->y);
+ pdf_dev_concat(&M);
+
+ if (f_vp)
+ set_linestyle(pn, da);
+
+ if (f_fs) {
+ double g, a;
+ int f_ais;
+
+#ifdef XETEX
+ switch (tp->mode.fill) {
+ case TPIC_MODE__FILL_SOLID:
+ g = 1.0 - tp->fill_color;
+ a = 0.0;
+ break;
+ case TPIC_MODE__FILL_SHAPE:
+ case TPIC_MODE__FILL_OPACITY:
+ if (tp->fill_color > 0.0) {
+ a = tp->fill_color;
+ g = 0.0;
+ } else {
+ a = 0.0;
+ g = 1.0;
+ }
+ break;
+ default:
+ g = 0.5;
+ a = 0.0;
+ }
+#else
+ if (tp->mode.fill == TPIC_MODE__FILL_SOLID || !tp->fill_color) {
+ g = 1.0 - tp->fill_color;
+ a = 0.0;
+ } else {
+ g = 0.0;
+ a = tp->fill_color;
+ }
+#endif
+
+ f_ais = (tp->mode.fill == TPIC_MODE__FILL_SHAPE) ? 1 : 0;
+
+ set_fillstyle(g, a, f_ais);
+ }
+}
static void
showpath (int f_vp, int f_fs) /* visible_path, fill_shape */
@@ -235,45 +289,18 @@ tpic__polyline (struct spc_tpic_ *tp,
int f_vp,
double da)
{
- pdf_tmatrix M;
double pn = tp->pen_size;
int f_fs = tp->fill_shape;
- int f_ais = 0;
- double g = 0.5;
- double a = 0.0;
int i, error = 0;
/* Shading is applied only to closed path. */
f_fs = CLOSED_PATH(tp) ? f_fs : 0;
f_vp = (pn > 0.0) ? f_vp : 0;
- f_ais = (tp->mode.fill == TPIC_MODE__FILL_SHAPE) ? 1 : 0;
- switch (tp->mode.fill) {
- case TPIC_MODE__FILL_SOLID:
- g = 1.0 - tp->fill_color;
- a = 0.0;
- break;
- case TPIC_MODE__FILL_SHAPE:
- case TPIC_MODE__FILL_OPACITY:
- if (tp->fill_color > 0.0) {
- a = tp->fill_color;
- g = 0.0;
- } else {
- a = 0.0;
- g = 1.0;
- }
- break;
- }
if (f_vp || f_fs) {
pdf_dev_gsave();
- pdf_setmatrix (&M, 1.0, 0.0, 0.0, -1.0, c->x, c->y);
- pdf_dev_concat(&M);
-
- if (f_vp)
- set_linestyle(pn, da);
- if (f_fs)
- set_fillstyle(g, a, f_ais);
+ set_styles(tp, c, f_fs, f_vp, pn, da);
pdf_dev_moveto(tp->points[0].x, tp->points[0].y);
for (i = 0; i < tp->num_points; i++)
@@ -316,44 +343,17 @@ tpic__spline (struct spc_tpic_ *tp,
double da)
{
double v[6];
- pdf_tmatrix M;
double pn = tp->pen_size;
int f_fs = tp->fill_shape;
- int f_ais = 0;
- double g = 0.5;
- double a = 0.0;
int i, error = 0;
f_fs = CLOSED_PATH(tp) ? f_fs : 0;
f_vp = (pn > 0.0) ? f_vp : 0;
- f_ais = (tp->mode.fill == TPIC_MODE__FILL_SHAPE) ? 1 : 0;
- switch (tp->mode.fill) {
- case TPIC_MODE__FILL_SOLID:
- g = 1.0 - tp->fill_color;
- a = 0.0;
- break;
- case TPIC_MODE__FILL_SHAPE:
- case TPIC_MODE__FILL_OPACITY:
- if (tp->fill_color > 0.0) {
- a = tp->fill_color;
- g = 0.0;
- } else {
- a = 0.0;
- g = 1.0;
- }
- break;
- }
- if ( f_vp || f_fs ) {
+ if (f_vp || f_fs) {
pdf_dev_gsave();
- pdf_setmatrix (&M, 1.0, 0.0, 0.0, -1.0, c->x, c->y);
- pdf_dev_concat(&M);
-
- if (f_vp)
- set_linestyle(pn, da);
- if (f_fs)
- set_fillstyle(g, a, f_ais);
+ set_styles(tp, c, f_fs, f_vp, pn, da);
pdf_dev_moveto(tp->points[0].x, tp->points[0].y);
@@ -388,43 +388,16 @@ tpic__arc (struct spc_tpic_ *tp,
double da,
double *v /* 6 numbers */ )
{
- pdf_tmatrix M;
double pn = tp->pen_size;
int f_fs = tp->fill_shape;
- int f_ais = 0;
- double g = 0.5;
- double a = 0.0;
f_fs = (round(fabs(v[4] - v[5]) + 0.5) >= 360) ? f_fs : 0;
f_vp = (pn > 0.0) ? f_vp : 0;
- f_ais = (tp->mode.fill == TPIC_MODE__FILL_SHAPE) ? 1 : 0;
- switch (tp->mode.fill) {
- case TPIC_MODE__FILL_SOLID:
- g = 1.0 - tp->fill_color;
- a = 0.0;
- break;
- case TPIC_MODE__FILL_SHAPE:
- case TPIC_MODE__FILL_OPACITY:
- if (tp->fill_color > 0.0) {
- a = tp->fill_color;
- g = 0.0;
- } else {
- a = 0.0;
- g = 1.0;
- }
- break;
- }
- if ( f_vp || f_fs ) {
+ if (f_vp || f_fs) {
pdf_dev_gsave();
- pdf_setmatrix (&M, 1.0, 0.0, 0.0, -1.0, c->x, c->y);
- pdf_dev_concat(&M);
-
- if (f_vp)
- set_linestyle(pn, da);
- if (f_fs)
- set_fillstyle(g, a, f_ais);
+ set_styles(tp, c, f_fs, f_vp, pn, da);
pdf_dev_arcx(v[0], v[1], v[2], v[3], v[4], v[5], +1, 0.0);
@@ -727,8 +700,14 @@ spc_handler_tpic_sh (struct spc_env *spe,
skip_blank(&ap->curptr, ap->endptr);
q = parse_float_decimal(&ap->curptr, ap->endptr);
if (q) {
- tp->fill_color = atof(q);
+ double g = atof(q);
RELEASE(q);
+ if (g >= 0.0 && g <= 1.0)
+ tp->fill_color = g;
+ else {
+ WARN("Invalid fill color specified: %g\n", g);
+ return -1;
+ }
}
return 0;
diff --git a/Build/source/texk/dvipdfm-x/xsrc/specials.c b/Build/source/texk/dvipdfm-x/xsrc/specials.c
deleted file mode 100644
index 5142e0082ab..00000000000
--- a/Build/source/texk/dvipdfm-x/xsrc/specials.c
+++ /dev/null
@@ -1,619 +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 <stdarg.h>
-
-#include "system.h"
-#include "mem.h"
-#include "error.h"
-#include "numbers.h"
-
-#include "dvi.h"
-
-#include "pdfobj.h"
-#include "pdfparse.h"
-#include "pdfdoc.h"
-#include "pdfnames.h"
-
-#include "pdfdraw.h"
-#include "pdfdev.h"
-
-#include "spc_pdfm.h"
-#include "spc_tpic.h"
-#include "spc_html.h"
-#include "spc_misc.h"
-#include "spc_color.h"
-#include "spc_dvips.h"
-#ifdef XETEX
-#include "spc_xtx.h"
-#endif
-
-#include "specials.h"
-
-static int verbose = 0;
-void
-spc_set_verbose (void)
-{
- verbose++;
-}
-
-
-void
-spc_warn (struct spc_env *spe, const char *fmt, ...)
-{
- va_list ap;
- static char buf[1024];
-
- va_start(ap, fmt);
-
- vsprintf(buf, fmt, ap);
- WARN(buf);
-
- va_end(ap);
-
- return;
-}
-
-
-/* This is currently just to make other spc_xxx to not directly
- * call dvi_xxx.
- */
-int
-spc_begin_annot (struct spc_env *spe, pdf_obj *dict)
-{
- pdf_doc_begin_annot(dict);
- dvi_tag_depth(); /* Tell dvi interpreter to handle line-break. */
- return 0;
-}
-
-int
-spc_end_annot (struct spc_env *spe)
-{
- dvi_untag_depth();
- pdf_doc_end_annot();
- return 0;
-}
-
-int
-spc_resume_annot (struct spc_env *spe)
-{
- dvi_link_annot(1);
- return 0;
-}
-
-int
-spc_suspend_annot (struct spc_env *spe)
-{
- dvi_link_annot(0);
- return 0;
-}
-
-
-
-static struct ht_table *named_objects = NULL;
-
-/* reserved keys */
-static const char *_rkeys[] = {
-#define K_OBJ__XPOS 0
-#define K_OBJ__YPOS 1
- "xpos", "ypos",
-#define K_OBJ__THISPAGE 2
-#define K_OBJ__PREVPAGE 3
-#define K_OBJ__NEXTPAGE 4
- "thispage", "prevpage", "nextpage",
-#define K_OBJ__RESOURCES 5
- "resources",
-#define K_OBJ__PAGES 6
-#define K_OBJ__NAMES 7
- "pages", "names",
-#define K_OBJ__CATALOG 8
-#define K_OBJ__DOCINFO 9
- "catalog", "docinfo",
-#if 0
-#define K_OBJ__TRAILER 10
- "trailer",
-#endif /* NYI */
- NULL
-};
-
-/* pageN where N is a positive integer.
- * Note that page need not exist at this time.
- */
-static int
-ispageref (const char *key)
-{
- const char *p;
- if (strlen(key) <= strlen("page") ||
- memcmp(key, "page", strlen("page")))
- return 0;
- else {
- for (p = key + 4; *p && *p >= '0' && *p <= '9'; p++);
- if (*p != '\0')
- return 0;
- }
- return 1;
-}
-
-/*
- * The following routine returns copies, not the original object.
- */
-pdf_obj *
-spc_lookup_reference (const char *key)
-{
- pdf_obj *value = NULL;
- pdf_coord cp;
- int k;
-
- ASSERT(named_objects);
-
- if (!key)
- return NULL;
-
- for (k = 0; _rkeys[k] && strcmp(key, _rkeys[k]); k++);
- switch (k) {
- /* xpos and ypos must be position in device space here. */
- case K_OBJ__XPOS:
- cp.x = dvi_dev_xpos(); cp.y = 0.0;
- pdf_dev_transform(&cp, NULL);
- value = pdf_new_number(ROUND(cp.x, .01));
- break;
- case K_OBJ__YPOS:
- cp.x = 0.0; cp.y = dvi_dev_ypos();
- pdf_dev_transform(&cp, NULL);
- value = pdf_new_number(ROUND(cp.y, .01));
- break;
- case K_OBJ__THISPAGE:
- value = pdf_doc_this_page_ref();
- break;
- case K_OBJ__PREVPAGE:
- value = pdf_doc_prev_page_ref();
- break;
- case K_OBJ__NEXTPAGE:
- value = pdf_doc_next_page_ref();
- break;
- case K_OBJ__PAGES:
- value = pdf_ref_obj(pdf_doc_page_tree());
- break;
- case K_OBJ__NAMES:
- value = pdf_ref_obj(pdf_doc_names());
- break;
- case K_OBJ__RESOURCES:
- value = pdf_ref_obj(pdf_doc_current_page_resources());
- break;
- case K_OBJ__CATALOG:
- value = pdf_ref_obj(pdf_doc_catalog());
- break;
- case K_OBJ__DOCINFO:
- value = pdf_ref_obj(pdf_doc_docinfo());
- break;
- default:
- if (ispageref(key))
- value = pdf_doc_ref_page(atoi(key + 4));
- else {
- value = pdf_names_lookup_reference(named_objects, key, strlen(key));
- }
- break;
- }
-
- if (!value) {
- ERROR("Object reference %s not exist.", key);
- }
-
- return value;
-}
-
-pdf_obj *
-spc_lookup_object (const char *key)
-{
- pdf_obj *value = NULL;
- pdf_coord cp;
- int k;
-
- ASSERT(named_objects);
-
- if (!key)
- return NULL;
-
- for (k = 0; _rkeys[k] && strcmp(key, _rkeys[k]); k++);
- switch (k) {
- case K_OBJ__XPOS:
- cp.x = dvi_dev_xpos(); cp.y = 0.0;
- pdf_dev_transform(&cp, NULL);
- value = pdf_new_number(ROUND(cp.x, .01));
- break;
- case K_OBJ__YPOS:
- cp.x = 0.0; cp.y = dvi_dev_ypos();
- pdf_dev_transform(&cp, NULL);
- value = pdf_new_number(ROUND(cp.y, .01));
- break;
- case K_OBJ__THISPAGE:
- value = pdf_doc_this_page();
- break;
- case K_OBJ__PAGES:
- value = pdf_doc_page_tree();
- break;
- case K_OBJ__NAMES:
- value = pdf_doc_names();
- break;
- case K_OBJ__RESOURCES:
- value = pdf_doc_current_page_resources();
- break;
- case K_OBJ__CATALOG:
- value = pdf_doc_catalog();
- break;
- case K_OBJ__DOCINFO:
- value = pdf_doc_docinfo();
- break;
- default:
- value = pdf_names_lookup_object(named_objects, key, strlen(key));
- break;
- }
-
-/* spc_handler_pdfm_bead() in spc_pdfm.c controls NULL too.
- if (!value) {
- ERROR("Object reference %s not exist.", key);
- }
-*/
-
- return value;
-}
-
-void
-spc_push_object (const char *key, pdf_obj *value)
-{
- int error = 0;
-
- if (!key || !value)
- return;
-
- if (PDF_OBJ_INDIRECTTYPE(value)) {
- pdf_names_add_reference(named_objects,
- key, strlen(key), value);
- } else {
- error = pdf_names_add_object(named_objects,
- key, strlen(key), value);
- if (!error) {
- /* _FIXME_:
- * Objects created by pdf:obj must always
- * be written to output regardless of if
- * they are actually used in document.
- */
- pdf_obj *obj_ref = pdf_names_lookup_reference(named_objects,
- key, strlen(key));
- if (obj_ref)
- pdf_release_obj(obj_ref);
- }
- }
-
- return;
-}
-
-void
-spc_flush_object (const char *key)
-{
- pdf_names_close_object(named_objects, key, strlen(key));
-}
-
-void
-spc_clear_objects (void)
-{
- pdf_delete_name_tree(&named_objects);
- named_objects = pdf_new_name_tree();
-}
-
-
-static int
-spc_handler_unknown (struct spc_env *spe,
- struct spc_arg *args)
-{
- ASSERT(spe && args);
-
- args->curptr = args->endptr;
-
- return -1;
-}
-
-static void
-init_special (struct spc_handler *special,
- struct spc_env *spe,
- struct spc_arg *args,
- const char *p, long size,
- double x_user, double y_user, double mag)
-{
-
- special->key = NULL;
- special->exec = (spc_handler_fn_ptr) &spc_handler_unknown;
-
- spe->x_user = x_user;
- spe->y_user = y_user;
- spe->mag = mag;
- spe->pg = pdf_doc_current_page_number(); /* _FIXME_ */
-
- args->curptr = p;
- args->endptr = args->curptr + size;
- args->base = args->curptr;
- args->command = NULL;
-
- return;
-}
-
-static void
-check_garbage (struct spc_arg *args)
-{
- ASSERT(args);
-
- if (args->curptr >= args->endptr)
- return;
-
- skip_white(&args->curptr, args->endptr);
- if (args->curptr < args->endptr) {
- WARN("Unparsed material at end of special ignored.");
- dump(args->curptr, args->endptr);
- }
-
- return;
-}
-
-static struct {
- const char *key;
- int (*bodhk_func) ();
- int (*eodhk_func) ();
- int (*bophk_func) ();
- int (*eophk_func) ();
- int (*check_func) (const char *, long);
- int (*setup_func) (struct spc_handler *, struct spc_env *, struct spc_arg *);
-} known_specials[] = {
-
- {"pdf:",
- spc_pdfm_at_begin_document,
- spc_pdfm_at_end_document,
- NULL,
- NULL,
- spc_pdfm_check_special,
- spc_pdfm_setup_handler
- },
-
-#ifdef XETEX
- {"x:",
- NULL,
- NULL,
- NULL,
- NULL,
- spc_xtx_check_special,
- spc_xtx_setup_handler
- },
-#endif
-
- {"ps:",
-#ifdef XETEX
- spc_dvips_at_begin_document,
- spc_dvips_at_end_document,
- spc_dvips_at_begin_page,
-#else
- NULL,
- NULL,
- NULL,
-#endif
- spc_dvips_at_end_page,
- spc_dvips_check_special,
- spc_dvips_setup_handler
- },
-
- {"color",
- NULL,
- NULL,
- NULL,
- NULL,
- spc_color_check_special,
- spc_color_setup_handler
- },
-
- {"tpic",
- spc_tpic_at_begin_document,
- spc_tpic_at_end_document,
- spc_tpic_at_begin_page,
- spc_tpic_at_end_page,
- spc_tpic_check_special,
- spc_tpic_setup_handler
- },
-
- {"html:",
- spc_html_at_begin_document,
- spc_html_at_end_document,
- spc_html_at_begin_page,
- spc_html_at_end_page,
- spc_html_check_special,
- spc_html_setup_handler
- },
-
- {"unknown",
- NULL,
- NULL,
- NULL,
- NULL,
- spc_misc_check_special,
- spc_misc_setup_handler
- },
-
- {NULL} /* end */
-};
-
-int
-spc_exec_at_begin_page (void)
-{
- int error = 0;
- int i;
-
- for (i = 0; known_specials[i].key != NULL; i++) {
- if (known_specials[i].bophk_func) {
- error = known_specials[i].bophk_func();
- }
- }
-
- return error;
-}
-
-int
-spc_exec_at_end_page (void)
-{
- int error = 0;
- int i;
-
- for (i = 0; known_specials[i].key != NULL; i++) {
- if (known_specials[i].eophk_func) {
- error = known_specials[i].eophk_func();
- }
- }
-
- return error;
-}
-
-int
-spc_exec_at_begin_document (void)
-{
- int error = 0;
- int i;
-
- ASSERT(!named_objects);
-
- named_objects = pdf_new_name_tree();
-
- for (i = 0; known_specials[i].key != NULL; i++) {
- if (known_specials[i].bodhk_func) {
- error = known_specials[i].bodhk_func();
- }
- }
-
- return error;
-}
-
-int
-spc_exec_at_end_document (void)
-{
- int error = 0;
- int i;
-
- for (i = 0; known_specials[i].key != NULL; i++) {
- if (known_specials[i].eodhk_func) {
- error = known_specials[i].eodhk_func();
- }
- }
-
- if (named_objects) {
- pdf_delete_name_tree(&named_objects);
- }
-
- return error;
-}
-
-static void
-print_error (const char *name, struct spc_env *spe, struct spc_arg *ap)
-{
- const char *p;
- char ebuf[64];
- int i;
- long pg = spe->pg;
- pdf_coord c;
-
- c.x = spe->x_user; c.y = spe->y_user;
- pdf_dev_transform(&c, NULL);
-
- if (ap->command && name) {
- WARN("Interpreting special command %s (%s) failed.", ap->command, name);
- WARN(">> at page=\"%ld\" position=\"(%g, %g)\" (in PDF)", pg, c.x, c.y);
- }
- for (i = 0, p = ap->base; i < 63 && p < ap->endptr; p++) {
- if (isprint(*p))
- ebuf[i++] = *p;
- else if (i + 4 < 63)
- i += sprintf(ebuf + i, "\\x%02x", (unsigned char)*p);
- else
- break;
- }
- ebuf[i] = '\0';
- if (ap->curptr < ap->endptr) {
- while (i-- > 60)
- ebuf[i] = '.';
- }
- WARN(">> xxx \"%s\"", ebuf);
-
- if (ap->curptr < ap->endptr) {
- for (i = 0, p = ap->curptr; i < 63 && p < ap->endptr; p++) {
- if (isprint(*p))
- ebuf[i++] = *p;
- else if (i + 4 < 63)
- i += sprintf(ebuf + i, "\\x%02x", (unsigned char)*p);
- else
- break;
- }
- ebuf[i] = '\0';
- if (ap->curptr < ap->endptr) {
- while (i-- > 60)
- ebuf[i] = '.';
- }
- WARN(">> Reading special command stopped around >>%s<<", ebuf);
-
- ap->curptr = ap->endptr;
- }
-}
-
-int
-spc_exec_special (const char *buffer, long size,
- double x_user, double y_user, double mag)
-{
- int error = -1;
- int i, found;
- struct spc_env spe;
- struct spc_arg args;
- struct spc_handler special;
-
- if (verbose > 3) {
- dump(buffer, buffer + size);
- }
-
- init_special(&special, &spe, &args, buffer, size, x_user, y_user, mag);
-
- for (i = 0; known_specials[i].key != NULL; i++) {
- found = known_specials[i].check_func(buffer, size);
- if (found) {
- error = known_specials[i].setup_func(&special, &spe, &args);
- if (!error) {
- error = special.exec(&spe, &args);
- }
- if (error) {
- print_error(known_specials[i].key, &spe, &args);
- }
- break;
- }
- }
-
- check_garbage(&args);
-
- return error;
-}
-
diff --git a/Build/source/texk/dvipdfm-x/xsrc/tfm.c b/Build/source/texk/dvipdfm-x/xsrc/tfm.c
deleted file mode 100644
index 98fbdf530f9..00000000000
--- a/Build/source/texk/dvipdfm-x/xsrc/tfm.c
+++ /dev/null
@@ -1,1209 +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 <string.h>
-
-#include "system.h"
-#include "mem.h"
-#include "mfileio.h"
-#include "error.h"
-
-#include "numbers.h"
-#include "dpxutil.h"
-
-#include "tfm.h"
-
-#define TFM_FORMAT 1
-#define OFM_FORMAT 2
-
-#define FWBASE ((double) (1<<20))
-
-static int verbose = 0;
-
-
-#ifndef WITHOUT_ASCII_PTEX
-/*
- * ID is 9 for vertical JFM file.
- */
-#define JFM_ID 11
-#define JFMV_ID 9
-#define IS_JFM(i) ((i) == JFM_ID || (i) == JFMV_ID)
-#endif /* !WITHOUT_ASCII_PTEX */
-
-/*
- * TFM Record structure:
- * Multiple TFM's may be read in at once.
- */
-
-struct tfm_font
-{
-#ifndef WITHOUT_ASCII_PTEX
- UNSIGNED_BYTE id;
- UNSIGNED_BYTE nt;
-#endif /* !WITHOUT_ASCII_PTEX */
-#ifndef WITHOUT_OMEGA
- SIGNED_QUAD level;
-#endif /* !WITHOUT_OMEGA */
- UNSIGNED_QUAD wlenfile;
- UNSIGNED_QUAD wlenheader;
- UNSIGNED_QUAD bc, ec;
- UNSIGNED_QUAD nwidths, nheights, ndepths;
- UNSIGNED_QUAD nitcor, nlig, nkern, nextens;
- UNSIGNED_QUAD nfonparm;
-#ifndef WITHOUT_OMEGA
- UNSIGNED_QUAD fontdir;
- UNSIGNED_QUAD nco, ncw, npc;
-#endif /* !WITHOUT_OMEGA */
- SIGNED_QUAD *header;
-#ifndef WITHOUT_ASCII_PTEX
- UNSIGNED_PAIR *chartypes;
-#endif /* !WITHOUT_ASCII_PTEX */
- UNSIGNED_QUAD *char_info;
- UNSIGNED_PAIR *width_index;
- UNSIGNED_BYTE *height_index;
- UNSIGNED_BYTE *depth_index;
- SIGNED_QUAD *width;
- SIGNED_QUAD *height;
- SIGNED_QUAD *depth;
-};
-
-static void
-tfm_font_init (struct tfm_font *tfm)
-{
- tfm->header = NULL;
-#ifndef WITHOUT_ASCII_PTEX
- tfm->id = 0;
- tfm->nt = 0;
- tfm->chartypes = NULL;
-#endif /* !WITHOUT_ASCII_PTEX */
-#ifndef WITHOUT_OMEGA
- tfm->level = 0;
- tfm->fontdir = 0;
- tfm->nco = tfm->ncw = tfm->npc = 0;
-#endif
- tfm->char_info = NULL;
- tfm->width_index = NULL;
- tfm->height_index = NULL;
- tfm->depth_index = NULL;
- tfm->width = tfm->height = tfm->depth = NULL;
-}
-
-static void
-tfm_font_clear (struct tfm_font *tfm)
-{
- if (tfm) {
- if (tfm->header) {
- RELEASE(tfm->header);
- tfm->header = NULL;
- }
- if (tfm->char_info) {
- RELEASE(tfm->char_info);
- tfm->char_info = NULL;
- }
- if (tfm->width) {
- RELEASE(tfm->width);
- tfm->width = NULL;
- }
- if (tfm->height) {
- RELEASE(tfm->height);
- tfm->height = NULL;
- }
- if (tfm->depth) {
- RELEASE(tfm->depth);
- tfm->depth = NULL;
- }
-#ifndef WITHOUT_ASCII_PTEX
- if (tfm->chartypes) {
- RELEASE(tfm->chartypes);
- tfm->chartypes = NULL;
- }
-#endif /* !WITHOUT_ASCII_PTEX */
- if (tfm->width_index) {
- RELEASE(tfm->width_index);
- tfm->width_index = NULL;
- }
- if (tfm->height_index) {
- RELEASE(tfm->height_index);
- tfm->height_index = NULL;
- }
- if (tfm->depth_index) {
- RELEASE(tfm->depth_index);
- tfm->depth_index = NULL;
- }
- }
-}
-
-
-struct coverage
-{
- long first_char;
- unsigned short num_chars;
-};
-
-/*
- * All characters in the same range have same metrics.
- */
-
-struct range_map {
- unsigned short num_coverages;
- struct coverage *coverages;
- unsigned short *indices;
-};
-
-/* Special case of num_coverages = 1 */
-struct char_map
-{
- struct coverage coverage;
- unsigned short *indices;
-};
-
-static void
-release_char_map (struct char_map *map)
-{
- if (map->indices)
- RELEASE(map->indices);
- map->indices = NULL;
- RELEASE(map);
-}
-
-static void
-release_range_map (struct range_map *map)
-{
- if (map->coverages)
- RELEASE(map->coverages);
- if (map->indices)
- RELEASE(map->indices);
- map->coverages = NULL;
- map->indices = NULL;
- RELEASE(map);
-}
-
-static long
-lookup_char (const struct char_map *map, long charcode)
-{
- if (charcode >= map->coverage.first_char &&
- charcode <= map->coverage.first_char + map->coverage.num_chars)
- return map->indices[charcode - map->coverage.first_char];
- else
- return -1;
-
- return -1;
-}
-
-static long
-lookup_range (const struct range_map *map, long charcode)
-{
- long idx;
-
- for (idx = map->num_coverages - 1; idx >= 0 &&
- charcode >= map->coverages[idx].first_char; idx--) {
- if (charcode <=
- map->coverages[idx].first_char + map->coverages[idx].num_chars)
- return map->indices[idx];
- }
-
- return -1;
-}
-
-#define SOURCE_TYPE_TFM 0
-#define SOURCE_TYPE_JFM 1
-#define SOURCE_TYPE_OFM 2
-
-#define MAPTYPE_NONE 0
-#define MAPTYPE_CHAR 1
-#define MAPTYPE_RANGE 2
-
-#define FONT_DIR_HORIZ 0
-#define FONT_DIR_VERT 1
-
-struct font_metric
-{
- char *tex_name;
- fixword designsize;
- char *codingscheme;
-
- int fontdir;
- long firstchar, lastchar;
-
- fixword *widths;
- fixword *heights;
- fixword *depths;
-
- struct {
- int type;
- void *data;
- } charmap;
-
- int source;
-};
-
-static void
-fm_init (struct font_metric *fm)
-{
- fm->tex_name = NULL;
- fm->firstchar = 0;
- fm->lastchar = 0;
- fm->fontdir = FONT_DIR_HORIZ;
- fm->codingscheme = NULL;
- fm->designsize = 0;
-
- fm->widths = NULL;
- fm->heights = NULL;
- fm->depths = NULL;
-
- fm->charmap.type = MAPTYPE_NONE;
- fm->charmap.data = NULL;
-
- fm->source = SOURCE_TYPE_TFM;
-}
-
-static void
-fm_clear (struct font_metric *fm)
-{
- if (fm) {
- if (fm->tex_name)
- RELEASE(fm->tex_name);
- if (fm->widths)
- RELEASE(fm->widths);
- if (fm->heights)
- RELEASE(fm->heights);
- if (fm->depths)
- RELEASE(fm->depths);
- if (fm->codingscheme)
- RELEASE(fm->codingscheme);
-
- switch (fm->charmap.type) {
- case MAPTYPE_CHAR:
- release_char_map(fm->charmap.data);
- break;
- case MAPTYPE_RANGE:
- release_range_map(fm->charmap.data);
- break;
- }
- }
-}
-
-#ifndef MAX_FONTS
-#define MAX_FONTS 16
-#endif
-
-struct font_metric *fms = NULL;
-static unsigned numfms = 0, max_fms = 0;
-
-static void
-fms_need (unsigned n)
-{
- if (n > max_fms) {
- max_fms = MAX(max_fms + MAX_FONTS, n);
- fms = RENEW(fms, max_fms, struct font_metric);
- }
-}
-
-void
-tfm_set_verbose (void)
-{
- verbose++;
-}
-
-
-static long
-fread_fwords (SIGNED_QUAD *words, SIGNED_QUAD nmemb, FILE *fp)
-{
- long i;
-
- for (i = 0; i < nmemb; i++)
- words[i] = get_signed_quad(fp);
-
- return nmemb*4;
-}
-
-static long
-fread_uquads (UNSIGNED_QUAD *quads, SIGNED_QUAD nmemb, FILE *fp)
-{
- long i;
-
- for (i = 0; i < nmemb; i++) {
- quads[i] = get_unsigned_quad(fp);
- }
-
- return nmemb*4;
-}
-
-/*
- * TFM and JFM
- */
-static void
-tfm_check_size (struct tfm_font *tfm, SIGNED_QUAD tfm_file_size)
-{
- UNSIGNED_QUAD expected_size = 6;
-
- /* Removed the warning message caused by EC TFM metric files.
- *
- if (tfm->wlenfile != tfm_file_size / 4) {
- WARN("TFM file size is %ld bytes but it says it is %ld bytes!",
- tfm_file_size, tfm->wlenfile * 4);
- if (tfm_file_size > tfm->wlenfile * 4) {
- WARN("Proceeding nervously...");
- } else {
- ERROR("Can't proceed...");
- }
- }
- */
- if (tfm_file_size < tfm->wlenfile * 4) {
- ERROR("Can't proceed...");
- }
-
- expected_size += (tfm->ec - tfm->bc + 1);
- expected_size += tfm->wlenheader;
- expected_size += tfm->nwidths;
- expected_size += tfm->nheights;
- expected_size += tfm->ndepths;
- expected_size += tfm->nitcor;
- expected_size += tfm->nlig;
- expected_size += tfm->nkern;
- expected_size += tfm->nextens;
- expected_size += tfm->nfonparm;
-#ifndef WITHOUT_ASCII_PTEX
- if (IS_JFM(tfm->id)) {
- expected_size += tfm->nt + 1;
- }
-#endif /* !WITHOUT_ASCII_PTEX */
- if (expected_size != tfm->wlenfile) {
- WARN("TFM file size is expected to be %ld bytes but it says it is %ld bytes!",
- expected_size * 4, tfm->wlenfile * 4);
- if (tfm_file_size > expected_size *4) {
- WARN("Proceeding nervously...");
- } else {
- ERROR("Can't proceed...");
- }
- }
-}
-
-static void
-tfm_get_sizes (FILE *tfm_file, SIGNED_QUAD tfm_file_size, struct tfm_font *tfm)
-{
-#ifndef WITHOUT_ASCII_PTEX
- {
- UNSIGNED_PAIR first_hword;
-
- /*
- * The first half word of TFM/JFM is TFM ID for JFM or size of
- * TFM file in word for TFM. TFM with 9*4 or 11*4 bytes is not
- * expected to be a valid TFM. So, we always assume that TFMs
- * starting with 00 09 or 00 0B is JFM.
- */
- first_hword = get_unsigned_pair(tfm_file);
- if (IS_JFM(first_hword)) {
- tfm->id = first_hword;
- tfm->nt = get_unsigned_pair(tfm_file);
- tfm->wlenfile = get_unsigned_pair(tfm_file);
- } else {
- tfm->wlenfile = first_hword;
- }
- }
-#else /* WITHOUT_ASCII_PTEX */
- tfm->wlenfile = get_unsigned_pair(tfm_file);
-#endif /* !WITHOUT_ASCII_PTEX */
-
- tfm->wlenheader = get_unsigned_pair(tfm_file);
- tfm->bc = get_unsigned_pair(tfm_file);
- tfm->ec = get_unsigned_pair(tfm_file);
- if (tfm->ec < tfm->bc) {
- ERROR("TFM file error: ec(%u) < bc(%u) ???", tfm->ec, tfm->bc);
- }
- tfm->nwidths = get_unsigned_pair(tfm_file);
- tfm->nheights = get_unsigned_pair(tfm_file);
- tfm->ndepths = get_unsigned_pair(tfm_file);
- tfm->nitcor = get_unsigned_pair(tfm_file);
- tfm->nlig = get_unsigned_pair(tfm_file);
- tfm->nkern = get_unsigned_pair(tfm_file);
- tfm->nextens = get_unsigned_pair(tfm_file);
- tfm->nfonparm = get_unsigned_pair(tfm_file);
-
- tfm_check_size(tfm, tfm_file_size);
-
- return;
-}
-
-#ifndef WITHOUT_ASCII_PTEX
-static void
-jfm_do_char_type_array (FILE *tfm_file, struct tfm_font *tfm)
-{
- UNSIGNED_PAIR charcode;
- UNSIGNED_PAIR chartype;
- long i;
-
- tfm->chartypes = NEW(65536, UNSIGNED_PAIR);
- for (i = 0; i < 65536; i++) {
- tfm->chartypes[i] = 0;
- }
- for (i = 0; i < tfm->nt; i++) {
- charcode = get_unsigned_pair(tfm_file);
- chartype = get_unsigned_pair(tfm_file);
- tfm->chartypes[charcode] = chartype;
- }
-}
-
-static void
-jfm_make_charmap (struct font_metric *fm, struct tfm_font *tfm)
-{
- if (tfm->nt > 1) {
- struct char_map *map;
- long code;
-
- fm->charmap.type = MAPTYPE_CHAR;
- fm->charmap.data = map = NEW(1, struct char_map);
- map->coverage.first_char = 0;
- map->coverage.num_chars = 0xFFFFu;
- map->indices = NEW(0x10000L, unsigned short);
-
- for (code = 0; code <= 0xFFFFu; code++) {
- map->indices[code] = tfm->chartypes[code];
- }
- } else {
- struct range_map *map;
-
- fm->charmap.type = MAPTYPE_RANGE;
- fm->charmap.data = map = NEW(1, struct range_map);
- map->num_coverages = 1;
- map->coverages = NEW(map->num_coverages, struct coverage);
- map->coverages[0].first_char = 0;
- map->coverages[0].num_chars = 0xFFFFu;
- map->indices = NEW(1, unsigned short);
- map->indices[0] = 0; /* Only default type used. */
- }
-}
-#endif /* !WITHOUT_ASCII_PTEX */
-
-static void
-tfm_unpack_arrays (struct font_metric *fm, struct tfm_font *tfm)
-{
- UNSIGNED_QUAD charinfo;
- UNSIGNED_PAIR width_index, height_index, depth_index;
- int i;
-
- fm->widths = NEW(256, fixword);
- fm->heights = NEW(256, fixword);
- fm->depths = NEW(256, fixword);
- for (i = 0; i < 256; i++) {
- fm->widths [i] = 0;
- fm->heights[i] = 0;
- fm->depths [i] = 0;
- }
-
- for (i = tfm->bc; i <= tfm->ec; i++ ) {
- charinfo = tfm->char_info[i - tfm->bc];
- width_index = (charinfo / 16777216ul);
- height_index = (charinfo / 0x100000ul) & 0xf;
- depth_index = (charinfo / 0x10000ul) & 0xf;
- fm->widths [i] = tfm->width [width_index];
- fm->heights[i] = tfm->height[height_index];
- fm->depths [i] = tfm->depth [depth_index];
- }
-
- return;
-}
-
-static int
-sput_bigendian (char *s, SIGNED_QUAD v, int n)
-{
- int i;
-
- for (i = n-1; i >= 0; i--) {
- s[i] = (char) (v & 0xff);
- v >>= 8;
- }
-
- return n;
-}
-
-static void
-tfm_unpack_header (struct font_metric *fm, struct tfm_font *tfm)
-{
- if (tfm->wlenheader < 12) {
- fm->codingscheme = NULL;
- } else {
- int i, len;
- char *p;
-
- len = (tfm->header[2] >> 24);
- if (len < 0 || len > 39)
- ERROR("Invalid TFM header.");
- if (len > 0) {
- fm->codingscheme = NEW(40, char);
- p = fm->codingscheme;
- p += sput_bigendian(p, tfm->header[2], 3);
- for (i = 1; i <= len / 4; i++) {
- p += sput_bigendian(p, tfm->header[2+i], 4);
- }
- fm->codingscheme[len] = '\0';
- } else {
- fm->codingscheme = NULL;
- }
- }
-
- fm->designsize = tfm->header[1];
-}
-
-#ifndef WITHOUT_OMEGA
-
-static void
-ofm_check_size_one (struct tfm_font *tfm, SIGNED_QUAD ofm_file_size)
-{
- UNSIGNED_QUAD ofm_size = 14;
-
- ofm_size += 2*(tfm->ec - tfm->bc + 1);
- ofm_size += tfm->wlenheader;
- ofm_size += tfm->nwidths;
- ofm_size += tfm->nheights;
- ofm_size += tfm->ndepths;
- ofm_size += tfm->nitcor;
- ofm_size += 2*(tfm->nlig);
- ofm_size += tfm->nkern;
- ofm_size += 2*(tfm->nextens);
- ofm_size += tfm->nfonparm;
- if (tfm->wlenfile != ofm_file_size / 4 ||
- tfm->wlenfile != ofm_size) {
- ERROR("OFM file problem. Table sizes don't agree.");
- }
-}
-
-static void
-ofm_get_sizes (FILE *ofm_file, UNSIGNED_QUAD ofm_file_size, struct tfm_font *tfm)
-{
- tfm->level = get_signed_quad(ofm_file);
-
- tfm->wlenfile = get_signed_quad(ofm_file);
- tfm->wlenheader = get_signed_quad(ofm_file);
- tfm->bc = get_signed_quad(ofm_file);
- tfm->ec = get_signed_quad(ofm_file);
- if (tfm->ec < tfm->bc) {
- ERROR("OFM file error: ec(%u) < bc(%u) ???", tfm->ec, tfm->bc);
- }
- tfm->nwidths = get_signed_quad(ofm_file);
- tfm->nheights = get_signed_quad(ofm_file);
- tfm->ndepths = get_signed_quad(ofm_file);
- tfm->nitcor = get_signed_quad(ofm_file);
- tfm->nlig = get_signed_quad(ofm_file);
- tfm->nkern = get_signed_quad(ofm_file);
- tfm->nextens = get_signed_quad(ofm_file);
- tfm->nfonparm = get_signed_quad(ofm_file);
- tfm->fontdir = get_signed_quad(ofm_file);
- if (tfm->fontdir) {
- WARN("I may be interpreting a font direction incorrectly.");
- }
- if (tfm->level == 0) {
- ofm_check_size_one(tfm, ofm_file_size);
- } else if (tfm->level == 1) {
- tfm->nco = get_signed_quad(ofm_file);
- tfm->ncw = get_signed_quad(ofm_file);
- tfm->npc = get_signed_quad(ofm_file);
- seek_absolute(ofm_file, 4*(tfm->nco - tfm->wlenheader));
- } else {
- ERROR("Can't handle OFM files with level > 1");
- }
-
- return;
-}
-
-static void
-ofm_do_char_info_zero (FILE *tfm_file, struct tfm_font *tfm)
-{
- UNSIGNED_QUAD num_chars;
-
- num_chars = tfm->ec - tfm->bc + 1;
- if (num_chars != 0) {
- UNSIGNED_QUAD i;
-
- tfm->width_index = NEW(num_chars, UNSIGNED_PAIR);
- tfm->height_index = NEW(num_chars, UNSIGNED_BYTE);
- tfm->depth_index = NEW(num_chars, UNSIGNED_BYTE);
- for (i = 0; i < num_chars; i++) {
- tfm->width_index [i] = get_unsigned_pair(tfm_file);
- tfm->height_index[i] = get_unsigned_byte(tfm_file);
- tfm->depth_index [i] = get_unsigned_byte(tfm_file);
- /* Ignore remaining quad */
- get_unsigned_quad(tfm_file);
- }
- }
-}
-
-static void
-ofm_do_char_info_one (FILE *tfm_file, struct tfm_font *tfm)
-{
- UNSIGNED_QUAD num_char_infos;
- UNSIGNED_QUAD num_chars;
-
- num_char_infos = tfm->ncw / (3 + (tfm->npc / 2));
- num_chars = tfm->ec - tfm ->bc + 1;
-
- if (num_chars != 0) {
- UNSIGNED_QUAD i;
- UNSIGNED_QUAD char_infos_read;
-
- tfm->width_index = NEW(num_chars, UNSIGNED_PAIR);
- tfm->height_index = NEW(num_chars, UNSIGNED_BYTE);
- tfm->depth_index = NEW(num_chars, UNSIGNED_BYTE);
- char_infos_read = 0;
- for (i = 0; i < num_chars &&
- char_infos_read < num_char_infos; i++) {
- int repeats, j;
-
- tfm->width_index [i] = get_unsigned_pair(tfm_file);
- tfm->height_index[i] = get_unsigned_byte(tfm_file);
- tfm->depth_index [i] = get_unsigned_byte(tfm_file);
- /* Ignore next quad */
- get_unsigned_quad(tfm_file);
- repeats = get_unsigned_pair(tfm_file);
- /* Skip params */
- for (j = 0; j < tfm->npc; j++) {
- get_unsigned_pair(tfm_file);
- }
- /* Remove word padding if necessary */
- if (ISEVEN(tfm->npc)){
- get_unsigned_pair(tfm_file);
- }
- char_infos_read++;
- if (i + repeats > num_chars) {
- ERROR("Repeats causes number of characters to be exceeded.");
- }
- for (j = 0; j < repeats; j++) {
- tfm->width_index [i+j+1] = tfm->width_index [i];
- tfm->height_index[i+j+1] = tfm->height_index[i];
- tfm->depth_index [i+j+1] = tfm->depth_index [i];
- }
- /* Skip ahead because we have already handled repeats */
- i += repeats;
- }
- }
-}
-
-static void
-ofm_unpack_arrays (struct font_metric *fm,
- struct tfm_font *tfm, UNSIGNED_QUAD num_chars)
-{
- long i;
-
- fm->widths = NEW(tfm->bc + num_chars, fixword);
- fm->heights = NEW(tfm->bc + num_chars, fixword);
- fm->depths = NEW(tfm->bc + num_chars, fixword);
- for (i = 0; i < num_chars; i++) {
- fm->widths [tfm->bc + i] = tfm->width [ tfm->width_index [i] ];
- fm->heights[tfm->bc + i] = tfm->height[ tfm->height_index[i] ];
- fm->depths [tfm->bc + i] = tfm->depth [ tfm->depth_index [i] ];
- }
-}
-
-static void
-read_ofm (struct font_metric *fm, FILE *ofm_file, UNSIGNED_QUAD ofm_file_size)
-{
- struct tfm_font tfm;
-
- tfm_font_init(&tfm);
-
- ofm_get_sizes(ofm_file, ofm_file_size, &tfm);
-
- if (tfm.level < 0 || tfm.level > 1)
- ERROR ("OFM level %d not supported.", tfm.level);
-
- if (tfm.wlenheader > 0) {
- tfm.header = NEW(tfm.wlenheader, fixword);
- fread_fwords(tfm.header, tfm.wlenheader, ofm_file);
- }
- if (tfm.level == 0) {
- ofm_do_char_info_zero(ofm_file, &tfm);
- } else if (tfm.level == 1) {
- ofm_do_char_info_one(ofm_file, &tfm);
- }
- if (tfm.nwidths > 0) {
- tfm.width = NEW(tfm.nwidths, fixword);
- fread_fwords(tfm.width, tfm.nwidths, ofm_file);
- }
- if (tfm.nheights > 0) {
- tfm.height = NEW(tfm.nheights, fixword);
- fread_fwords(tfm.height, tfm.nheights, ofm_file);
- }
- if (tfm.ndepths > 0) {
- tfm.depth = NEW(tfm.ndepths, fixword);
- fread_fwords(tfm.depth, tfm.ndepths, ofm_file);
- }
-
- ofm_unpack_arrays(fm, &tfm, tfm.ec - tfm.bc + 1);
- tfm_unpack_header(fm, &tfm);
- fm->firstchar = tfm.bc;
- fm->lastchar = tfm.ec;
- fm->source = SOURCE_TYPE_OFM;
-
- tfm_font_clear(&tfm);
-
- return;
-}
-#endif /* !WITHOUT_OMEGA */
-
-static void
-read_tfm (struct font_metric *fm, FILE *tfm_file, UNSIGNED_QUAD tfm_file_size)
-{
- struct tfm_font tfm;
-
- tfm_font_init(&tfm);
-
- tfm_get_sizes(tfm_file, tfm_file_size, &tfm);
- fm->firstchar = tfm.bc;
- fm->lastchar = tfm.ec;
- if (tfm.wlenheader > 0) {
- tfm.header = NEW(tfm.wlenheader, fixword);
- fread_fwords(tfm.header, tfm.wlenheader, tfm_file);
- }
-#ifndef WITHOUT_ASCII_PTEX
- if (IS_JFM(tfm.id)) {
- jfm_do_char_type_array(tfm_file, &tfm);
- jfm_make_charmap(fm, &tfm);
- fm->firstchar = 0;
- fm->lastchar = 0xFFFFl;
- fm->fontdir = (tfm.id == JFMV_ID) ? FONT_DIR_VERT : FONT_DIR_HORIZ;
- fm->source = SOURCE_TYPE_JFM;
- }
-#endif /* !WITHOUT_ASCII_PTEX */
- if (tfm.ec - tfm.bc + 1 > 0) {
- tfm.char_info = NEW(tfm.ec - tfm.bc + 1, UNSIGNED_QUAD);
- fread_uquads(tfm.char_info, tfm.ec - tfm.bc + 1, tfm_file);
- }
- if (tfm.nwidths > 0) {
- tfm.width = NEW(tfm.nwidths, fixword);
- fread_fwords(tfm.width, tfm.nwidths, tfm_file);
- }
- if (tfm.nheights > 0) {
- tfm.height = NEW(tfm.nheights, fixword);
- fread_fwords(tfm.height, tfm.nheights, tfm_file);
- }
- if (tfm.ndepths > 0) {
- tfm.depth = NEW(tfm.ndepths, fixword);
- fread_fwords(tfm.depth, tfm.ndepths, tfm_file);
- }
- tfm_unpack_arrays(fm, &tfm);
- tfm_unpack_header(fm, &tfm);
-
- tfm_font_clear(&tfm);
-
- return;
-}
-
-int
-tfm_open (const char *tfm_name, int must_exist)
-{
- FILE *tfm_file;
- int i, format = TFM_FORMAT;
- UNSIGNED_QUAD tfm_file_size;
- char *file_name = NULL;
-
- for (i = 0; i < numfms; i++) {
- if (!strcmp(tfm_name, fms[i].tex_name))
- return i;
- }
-
- /*
- * The procedure to search tfm or ofm files:
- * 1. Search tfm file with the given name with the must_exist flag unset.
- * 2. Search ofm file with the given name with the must_exist flag unset.
- * 3. If not found and must_exist flag is set, try again to search
- * tfm file with the must_exist flag set.
- * 4. If not found and must_exist flag is not set, return -1.
- */
-
-
- /*
- * We first look for OFM and then TFM.
- * The reason for this change is incompatibility introduced when dvipdfmx
- * started to write correct glyph metrics to output PDF for CID fonts.
- * I'll not explain this in detail... This change is mostly specific to
- * Japanese support.
- */
-#if 0
- if ((file_name = kpse_find_file(tfm_name, kpse_tfm_format, 0))) {
- format = TFM_FORMAT;
- } else if ((file_name = kpse_find_file(tfm_name, kpse_ofm_format, 0))) {
- format = OFM_FORMAT;
- }
-#endif
- {
- char *ofm_name, *suffix;
-
- suffix = strrchr(tfm_name, '.');
- if (!suffix || (strcmp(suffix, ".tfm") != 0 &&
- strcmp(suffix, ".ofm") != 0)) {
- ofm_name = NEW(strlen(tfm_name) + strlen(".ofm") + 1, char);
- strcpy(ofm_name, tfm_name);
- strcat(ofm_name, ".ofm");
- } else {
- ofm_name = NULL;
- }
- if (ofm_name &&
- (file_name = kpse_find_file(ofm_name, kpse_ofm_format, 0)) != NULL) {
- format = OFM_FORMAT;
- } else if ((file_name =
- kpse_find_file(tfm_name, kpse_tfm_format, 0)) != NULL) {
- format = TFM_FORMAT;
- } else if ((file_name =
- kpse_find_file(tfm_name, kpse_ofm_format, 0)) != NULL) {
- format = OFM_FORMAT;
- }
- if (ofm_name)
- RELEASE(ofm_name);
- }
-
- /*
- * In case that must_exist is set, MiKTeX returns always non-NULL value
- * even if the tfm file is not found.
- */
- if (file_name == NULL) {
- if (must_exist) {
- if ((file_name = kpse_find_file(tfm_name, kpse_tfm_format, 1)) != NULL)
- format = TFM_FORMAT;
- else {
- ERROR("Unable to find TFM file \"%s\".", tfm_name);
- }
- } else {
- return -1;
- }
- }
-
- tfm_file = MFOPEN(file_name, FOPEN_RBIN_MODE);
- if (!tfm_file) {
- ERROR("Could not open specified TFM/OFM file \"%s\".", tfm_name);
- }
-
- if (verbose) {
- if (format == TFM_FORMAT)
- MESG("(TFM:%s", tfm_name);
- else if (format == OFM_FORMAT)
- MESG("(OFM:%s", tfm_name);
- if (verbose > 1)
- MESG("[%s]", file_name);
- }
-
- RELEASE(file_name);
-
- tfm_file_size = file_size(tfm_file);
- if (tfm_file_size < 24) {
- ERROR("TFM/OFM file too small to be a valid file.");
- }
-
- fms_need(numfms + 1);
- fm_init(fms + numfms);
-
-#ifndef WITHOUT_OMEGA
- if (format == OFM_FORMAT)
- read_ofm(&fms[numfms], tfm_file, tfm_file_size);
- else
-#endif /* !WITHOUT_OMEGA */
- {
- read_tfm(&fms[numfms], tfm_file, tfm_file_size);
- }
-
- MFCLOSE(tfm_file);
-
- fms[numfms].tex_name = NEW(strlen(tfm_name)+1, char);
- strcpy(fms[numfms].tex_name, tfm_name);
-
- if (verbose)
- MESG(")");
-
- return numfms++;
-}
-
-void
-tfm_close_all (void)
-{
- int i;
-
- if (fms) {
- for (i = 0; i < numfms; i++) {
- fm_clear(&(fms[i]));
- }
- RELEASE(fms);
- }
-}
-
-#define CHECK_ID(n) do {\
- if ((n) < 0 || (n) >= numfms)\
- ERROR("TFM: Invalid TFM ID: %d", (n));\
-} while (0)
-
-fixword
-tfm_get_fw_width (int font_id, SIGNED_QUAD ch)
-{
- struct font_metric *fm;
- long idx = 0;
-
- CHECK_ID(font_id);
-
- fm = &(fms[font_id]);
- if (ch >= fm->firstchar && ch <= fm->lastchar) {
- switch (fm->charmap.type) {
- case MAPTYPE_CHAR:
- idx = lookup_char(fm->charmap.data, ch);
- if (idx < 0)
- ERROR("Invalid char: %ld\n", ch);
- break;
- case MAPTYPE_RANGE:
- idx = lookup_range(fm->charmap.data, ch);
- if (idx < 0)
- ERROR("Invalid char: %ld\n", ch);
- break;
- default:
- idx = ch;
- }
- } else {
- ERROR("Invalid char: %ld\n", ch);
- }
-
- return fm->widths[idx];
-}
-
-fixword
-tfm_get_fw_height (int font_id, SIGNED_QUAD ch)
-{
- struct font_metric *fm;
- long idx = 0;
-
- CHECK_ID(font_id);
-
- fm = &(fms[font_id]);
- if (ch >= fm->firstchar && ch <= fm->lastchar) {
- switch (fm->charmap.type) {
- case MAPTYPE_CHAR:
- idx = lookup_char(fm->charmap.data, ch);
- if (idx < 0)
- ERROR("Invalid char: %ld\n", ch);
- break;
- case MAPTYPE_RANGE:
- idx = lookup_range(fm->charmap.data, ch);
- if (idx < 0)
- ERROR("Invalid char: %ld\n", ch);
- break;
- default:
- idx = ch;
- }
- } else {
- ERROR("Invalid char: %ld\n", ch);
- }
-
- return fm->heights[idx];
-}
-
-fixword
-tfm_get_fw_depth (int font_id, SIGNED_QUAD ch)
-{
- struct font_metric *fm;
- long idx = 0;
-
- CHECK_ID(font_id);
-
- fm = &(fms[font_id]);
- if (ch >= fm->firstchar && ch <= fm->lastchar) {
- switch (fm->charmap.type) {
- case MAPTYPE_CHAR:
- idx = lookup_char(fm->charmap.data, ch);
- if (idx < 0)
- ERROR("Invalid char: %ld\n", ch);
- break;
- case MAPTYPE_RANGE:
- idx = lookup_range(fm->charmap.data, ch);
- if (idx < 0)
- ERROR("Invalid char: %ld\n", ch);
- break;
- default:
- idx = ch;
- }
- } else {
- ERROR("Invalid char: %ld\n", ch);
- }
-
- return fm->depths[idx];
-}
-
-
-/*
- * tfm_get_width returns the width of the font
- * as a (double) fraction of the design size.
- */
-double
-tfm_get_width (int font_id, SIGNED_QUAD ch)
-{
- return ((double) tfm_get_fw_width(font_id, ch)/FWBASE);
-}
-
-#if 0
-double
-tfm_get_height (int font_id, SIGNED_QUAD ch)
-{
- return ((double) tfm_get_fw_height(font_id, ch)/FWBASE);
-}
-
-double
-tfm_get_depth (int font_id, SIGNED_QUAD ch)
-{
- return ((double) tfm_get_fw_depth(font_id, ch)/FWBASE);
-}
-#endif
-
-/* tfm_string_xxx() do not work for OFM... */
-fixword
-tfm_string_width (int font_id, const unsigned char *s, unsigned len)
-{
- fixword result = 0;
- struct font_metric *fm;
- unsigned i;
-
- CHECK_ID(font_id);
-
- fm = &(fms[font_id]);
-#ifndef WITHOUT_ASCII_PTEX
- if (fm->source == SOURCE_TYPE_JFM) {
- for (i = 0; i < len/2; i++) {
- SIGNED_QUAD ch;
-
- ch = (s[2*i] << 8)|s[2*i+1];
- result += tfm_get_fw_width(font_id, ch);
- }
- } else
-#endif
- for (i = 0; i < len; i++) {
- result += tfm_get_fw_width(font_id, s[i]);
- }
-
- return result;
-}
-
-fixword
-tfm_string_depth (int font_id, const unsigned char *s, unsigned len)
-{
- fixword result = 0;
- struct font_metric *fm;
- unsigned i;
-
- CHECK_ID(font_id);
-
- fm = &(fms[font_id]);
-#ifndef WITHOUT_ASCII_PTEX
- if (fm->source == SOURCE_TYPE_JFM) {
- for (i = 0; i < len/2; i++) {
- SIGNED_QUAD ch;
-
- ch = (s[2*i] << 8)|s[2*i+1];
- result += tfm_get_fw_depth(font_id, ch);
- }
- } else
-#endif
- for (i = 0; i < len; i++) {
- result = MAX(result, tfm_get_fw_depth(font_id, s[i]));
- }
-
- return result;
-}
-
-fixword
-tfm_string_height (int font_id, const unsigned char *s, unsigned len)
-{
- fixword result = 0;
- struct font_metric *fm;
- unsigned i;
-
- CHECK_ID(font_id);
-
- fm = &(fms[font_id]);
-#ifndef WITHOUT_ASCII_PTEX
- if (fm->source == SOURCE_TYPE_JFM) {
- for (i = 0; i < len/2; i++) {
- SIGNED_QUAD ch;
-
- ch = (s[2*i] << 8)|s[2*i+1];
- result += tfm_get_fw_height(font_id, ch);
- }
- } else
-#endif
- for (i = 0; i < len; i++) {
- result = MAX(result, tfm_get_fw_height(font_id, s[i]));
- }
-
- return result;
-}
-
-double
-tfm_get_design_size (int font_id)
-{
- CHECK_ID(font_id);
-
- return (double) (fms[font_id].designsize)/FWBASE*(72.0/72.27);
-}
-
-#if 0
-char *
-tfm_get_codingscheme (int font_id)
-{
- CHECK_ID(font_id);
-
- return fms[font_id].codingscheme;
-}
-
-#ifndef WITHOUT_ASCII_PTEX
-/* Vertical version of JFM */
-int
-tfm_is_vert (int font_id)
-{
- CHECK_ID(font_id);
-
- return (fms[font_id].fontdir == FONT_DIR_VERT) ? 1 : 0;
-}
-#else /* WITHOUT_ASCII_PTEX */
-int
-tfm_is_vert (int font_id)
-{
- return 0;
-}
-#endif /* !WITHOUT_ASCII_PTEX */
-#endif
-
-int
-tfm_exists (const char *tfm_name)
-{
- char *fullname;
-
- fullname = kpse_find_file(tfm_name, kpse_ofm_format, 0);
- if (fullname) {
- RELEASE(fullname);
- return 1;
- }
- fullname = kpse_find_file(tfm_name, kpse_tfm_format, 0);
- if (fullname) {
- RELEASE(fullname);
- return 1;
- }
-
- return 0;
-}
diff --git a/Build/source/texk/dvipdfm-x/xsrc/truetype.c b/Build/source/texk/dvipdfm-x/xsrc/truetype.c
deleted file mode 100644
index 9e968a11f66..00000000000
--- a/Build/source/texk/dvipdfm-x/xsrc/truetype.c
+++ /dev/null
@@ -1,1008 +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.
-
- 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 "numbers.h"
-#include "error.h"
-#include "mem.h"
-
-#include "dpxfile.h"
-#include "dpxutil.h"
-
-#include "pdfobj.h"
-#include "pdfresource.h"
-#include "pdffont.h"
-
-#include "pdfencoding.h"
-#include "unicode.h"
-#include "agl.h"
-
-/* TrueType */
-#include "sfnt.h"
-#include "tt_cmap.h"
-#include "tt_table.h"
-#include "tt_glyf.h"
-#include "tt_post.h"
-#include "tt_gsub.h"
-#include "tt_aux.h"
-
-#include "truetype.h"
-
-#include "tfm.h"
-
-/* Modifying this has no effect :P */
-#ifdef ENABLE_NOEMBED
-# undef ENABLE_NOEMBED
-#endif
-
-int
-pdf_font_open_truetype (pdf_font *font)
-{
- char *ident;
- int index, encoding_id;
- pdf_obj *fontdict, *descriptor;
- sfnt *sfont;
- int embedding = 1; /* Must be embedded. */
- FILE *fp = NULL;
- int length, error = 0;
-
- ASSERT( font );
-
- ident = pdf_font_get_ident(font);
- index = pdf_font_get_index(font);
-
- ASSERT( ident );
-
-#ifdef XETEX
- sfont = sfnt_open(pdf_font_get_ft_face(font), SFNT_TYPE_TTC | SFNT_TYPE_TRUETYPE);
- if (!sfont)
- return -1;
-#else
- fp = DPXFOPEN(ident, DPX_RES_TYPE_TTFONT);
- if (!fp) {
- fp = DPXFOPEN(ident, DPX_RES_TYPE_DFONT);
- if (!fp) return -1;
- sfont = dfont_open(fp, index);
- } else {
- sfont = sfnt_open(fp);
- }
-#endif
-
- if (!sfont) {
- WARN("Could not open TrueType font: %s", ident);
- if (fp)
- DPXFCLOSE(fp);
- return -1;
- }
-
- if (sfont->type == SFNT_TYPE_TTC) {
- unsigned long offset;
- offset = ttc_read_offset(sfont, index);
- if (offset == 0) ERROR("Invalid TTC index in %s.", ident);
- error = sfnt_read_table_directory(sfont, offset);
- } else {
- error = sfnt_read_table_directory(sfont, sfont->offset);
- }
-
- if (error) {
- sfnt_close(sfont);
- if (fp)
- DPXFCLOSE(fp);
- return -1; /* Silently */
- }
-
- /* Reading fontdict before checking fonttype conflicts with PKFONT
- * because pdf_font_get_resource() always makes a dictionary.
- */
- encoding_id = pdf_font_get_encoding(font);
- fontdict = pdf_font_get_resource(font);
- descriptor = pdf_font_get_descriptor(font);
-#ifdef ENABLE_NOEMBED
- embedding = pdf_font_get_flag(font, PDF_FONT_FLAG_NOEMBED) ? 0 : 1;
-#endif /* ENABLE_NOEMBED */
-
- ASSERT( fontdict && descriptor );
-
- {
- char fontname[256];
- int n;
- pdf_obj *tmp;
-
- memset(fontname, 0, 256);
- length = tt_get_ps_fontname(sfont, fontname, 255);
- if (length < 1) {
- length = MIN(strlen(ident), 255);
- strncpy(fontname, ident, length);
- }
- fontname[length] = '\0';
- for (n = 0; n < length; n++) {
- if (fontname[n] == 0) {
- memmove(fontname + n, fontname + n + 1, length - n - 1);
- }
- }
- if (strlen(fontname) == 0)
- ERROR("Can't find valid fontname for \"%s\".", ident);
- pdf_font_set_fontname(font, fontname);
-
- tmp = tt_get_fontdesc(sfont, &embedding, -1, 1, fontname);
- if (!tmp) {
- ERROR("Could not obtain necessary font info.");
- sfnt_close(sfont);
- if (fp)
- DPXFCLOSE(fp);
- return -1;
- }
- ASSERT(pdf_obj_typeof(tmp) == PDF_DICT);
-
- pdf_merge_dict(descriptor, tmp);
- pdf_release_obj(tmp);
- }
-
- if (!embedding) {
- if (encoding_id >= 0 &&
- !pdf_encoding_is_predefined(encoding_id)) {
- ERROR("Custom encoding not allowed for non-embedded TrueType font.");
- sfnt_close(sfont);
- return -1;
- } else {
- /* There are basically no guarantee for font substitution
- * can work with "symblic" fonts. At least all glyphs
- * contained in the font must be identified; glyphs covers
- * by this instance of font should contain glyphs only from
- * Adobe Standard Latin Set. We allow non-embedded font
- * only to predefined encodings for this reason. Note that
- * "builtin" encoding means "MacRoman" here.
- */
- pdf_obj *tmp;
- long flags;
-
-#ifndef ENABLE_NOEMBED
- ERROR("Font file=\"%s\" can't be embedded due to liscence restrictions.", ident);
-#endif /* ENABLE_NOEMBED */
- pdf_font_set_flags(font, PDF_FONT_FLAG_NOEMBED);
- tmp = pdf_lookup_dict(descriptor, "Flags");
- if (tmp && pdf_obj_typeof(tmp) == PDF_NUMBER) {
- flags = (long) pdf_number_value(tmp);
- flags &= (1 << 2); /* clear Symbolic */
- flags |= (1 << 5); /* set Nonsymbolic */
- pdf_add_dict(descriptor, pdf_new_name("Flags"), pdf_new_number(flags));
- }
- }
- }
-
- sfnt_close(sfont);
- if (fp)
- DPXFCLOSE(fp);
-
- pdf_add_dict(fontdict,
- pdf_new_name("Type"), pdf_new_name("Font"));
- pdf_add_dict(fontdict,
- pdf_new_name("Subtype"), pdf_new_name("TrueType"));
-
- return 0;
-}
-
-/*
- * The 'name' table should be preserved since it contains copyright
- * information, but it might cause problem when there are invalid
- * table entries (wrongly encoded text which is often the case in
- * CJK fonts). Acrobat does not use 'name' table. Unicode TrueType
- * fonts may have 10K bytes 'name' table...
- *
- * We preserve the 'OS/2' table too, since it contains the license
- * information. PDF applications should use this table to decide
- * whether the font is embedded only for the purpose of preview &
- * printing. Otherwise, we must encrypt the document. Acrobat does
- * not use 'OS/2' table, though...
- */
-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}, {"cmap", 1}, {NULL, 0}
-};
-
-static void
-do_widths (pdf_font *font, double *widths)
-{
- pdf_obj *fontdict;
- pdf_obj *tmparray;
- int code, firstchar, lastchar, tfm_id;
- char *usedchars;
-
- fontdict = pdf_font_get_resource (font);
- usedchars = pdf_font_get_usedchars (font);
-
- tmparray = pdf_new_array();
- for (firstchar = 255, lastchar = 0, code = 0; code < 256; code++) {
- if (usedchars[code]) {
- if (code < firstchar) firstchar = code;
- if (code > lastchar) lastchar = code;
- }
- }
- if (firstchar > lastchar) {
- WARN("No glyphs actually used???");
- pdf_release_obj(tmparray);
- return;
- }
- tfm_id = tfm_open(pdf_font_get_mapname(font), 0);
- for (code = firstchar; code <= lastchar; code++) {
- if (usedchars[code]) {
- double width;
- if (tfm_id < 0) /* tfm is not found */
- width = widths[code];
- else
- width = 1000. * tfm_get_width(tfm_id, code);
- pdf_add_array(tmparray,
- pdf_new_number(ROUND(width, 0.1)));
- } else {
- pdf_add_array(tmparray, pdf_new_number(0.0));
- }
- }
-
- if (pdf_array_length(tmparray) > 0) {
- pdf_add_dict(fontdict,
- pdf_new_name("Widths"), pdf_ref_obj(tmparray));
- }
- pdf_release_obj(tmparray);
-
- pdf_add_dict(fontdict,
- pdf_new_name("FirstChar"), pdf_new_number(firstchar));
- pdf_add_dict(fontdict,
- pdf_new_name("LastChar"), pdf_new_number(lastchar));
-
- return;
-}
-
-static int verbose = 0;
-
-#define PDFUNIT(v) ((double) (ROUND(1000.0*(v)/(glyphs->emsize), 1)))
-
-/*
- * There are several issues in TrueType font support in PDF.
- * How PDF viewers select TrueType cmap table is not so clear.
- * Most reliable way seem to reencode font and sort glyphs as
- * charcode == gid and to use Mac-Roman format 0 subtable.
- * It does not work with encodings that uses full 256 range since
- * GID = 0 is reserved for .notdef, so GID = 256 is not accessible.
- */
-static int
-do_builtin_encoding (pdf_font *font, const char *usedchars, sfnt *sfont)
-{
- struct tt_glyphs *glyphs;
- char *cmap_table;
- tt_cmap *ttcm;
- USHORT gid, idx;
- int code, count;
- double widths[256];
-
- ttcm = tt_cmap_read(sfont, TT_MAC, TT_MAC_ROMAN);
- if (!ttcm) {
- WARN("Could not read Mac-Roman TrueType cmap table...");
- return -1;
- }
-
- cmap_table = NEW(274, char);
- memset(cmap_table, 0, 274);
- sfnt_put_ushort(cmap_table, 0); /* Version */
- sfnt_put_ushort(cmap_table+2, 1); /* Number of subtables */
- sfnt_put_ushort(cmap_table+4, TT_MAC); /* Platform ID */
- sfnt_put_ushort(cmap_table+6, TT_MAC_ROMAN); /* Encoding ID */
- sfnt_put_ulong (cmap_table+8, 12); /* Offset */
- sfnt_put_ushort(cmap_table+12, 0); /* Format */
- sfnt_put_ushort(cmap_table+14, 262); /* Length */
- sfnt_put_ushort(cmap_table+16, 0); /* Language */
-
- glyphs = tt_build_init();
-
- if (verbose > 2)
- MESG("[glyphs:/.notdef");
-
- count = 1; /* .notdef */
- for (code = 0; code < 256; code++) {
- if (!usedchars[code])
- continue;
-
- if (verbose > 2)
- MESG("/.c0x%02x", code);
-
- gid = tt_cmap_lookup(ttcm, code);
- if (gid == 0) {
- WARN("Glyph for character code=0x%02x missing in font font-file=\"%s\".",
- code, pdf_font_get_ident(font));
- idx = 0;
- } else {
- idx = tt_find_glyph(glyphs, gid);
- if (idx == 0)
- idx = tt_add_glyph(glyphs, (USHORT)gid, (USHORT)count); /* count returned. */
- }
- cmap_table[18+code] = idx & 0xff; /* bug here */
- count++;
- }
- tt_cmap_release(ttcm);
-
- if (verbose > 2)
- MESG("]");
-
- if (tt_build_tables(sfont, glyphs) < 0) {
- WARN("Packing TrueType font into SFNT failed!");
- tt_build_finish(glyphs);
- RELEASE(cmap_table);
- return -1;
- }
-
- for (code = 0; code < 256; code++) {
- if (usedchars[code]) {
- idx = tt_get_index(glyphs, (USHORT) cmap_table[18+code]);
- widths[code] = PDFUNIT(glyphs->gd[idx].advw);
- } else {
- widths[code] = 0.0;
- }
- }
- do_widths(font, widths);
-
- if (verbose > 1)
- MESG("[%d glyphs]", glyphs->num_glyphs);
-
- tt_build_finish(glyphs);
-
- sfnt_set_table(sfont, "cmap", cmap_table, 274);
-
- return 0;
-}
-
-/* Order of lookup should be
- * post, unicode+otl
- */
-struct glyph_mapper
-{
- tt_cmap *codetogid;
- otl_gsub *gsub;
- sfnt *sfont;
- struct tt_post_table *nametogid;
-};
-
-
-/* WARNING: This modifies glyphname itself */
-static int
-agl_decompose_glyphname (char *glyphname, char **nptrs, int size, char **suffix)
-{
- char *q, *p = glyphname;
- int n;
-
- q = strchr(p, '.'); /* chop every thing after *first* dot */
- if (!q)
- *suffix = NULL;
- else {
- *q = '\0'; q++;
- *suffix = q;
- }
-
- nptrs[0] = p;
- for (n = 1; p && *p; n++) {
- p = strchr(p, '_');
- if (!p || p[1] == '\0')
- break;
- if (n >= size)
- ERROR("Uh ah..."); /* _FIXME_ */
- *p = '\0'; p++;
- nptrs[n] = p;
- }
-
- return n;
-}
-
-static int
-select_gsub (const char *feat, struct glyph_mapper *gm)
-{
- int idx, error = 0;
-
- if (!feat || *feat == 0 || !gm || !gm->gsub)
- return -1;
-
- /* First treat as is */
- idx = otl_gsub_select(gm->gsub, "*", "*", feat);
- if (idx >= 0)
- return 0;
-
- if (verbose > 1)
- MESG("\ntrutype>> Try loading OTL GSUB for \"*.*.%s\"...", feat);
- error = otl_gsub_add_feat(gm->gsub, "*", "*", feat, gm->sfont);
- if (!error) {
- idx = otl_gsub_select(gm->gsub, "*", "*", feat);
- return (idx >= 0 ? 0 : -1);
- }
-
- return -1;
-}
-
-static int findparanoiac (const char *glyph_name, USHORT *gid, struct glyph_mapper *gm);
-static int resolve_glyph (const char *glyph_name, USHORT *gid, struct glyph_mapper *gm);
-
-/* Apply GSUB. This is a bit tricky... */
-static int
-selectglyph (USHORT in, const char *suffix, struct glyph_mapper *gm, USHORT *out)
-{
- char *s, *q, t[5];
- const char *r;
- int n, error = 0;
-
- ASSERT(suffix && gm && out);
- ASSERT(suffix && *suffix != 0);
-
- s = NEW(strlen(suffix) + 1, char);
- strcpy(s, suffix);
-
- /* First try converting suffix to feature tag.
- * agl.c currently only knows less ambiguos cases;
- * e.g., 'sc', 'superior', etc.
- */
- r = agl_suffix_to_otltag(s);
- if (r) { /* We found feature tag for 'suffix'. */
- error = select_gsub(r, gm); /* no fallback for this */
- if (!error)
- error = otl_gsub_apply(gm->gsub, &in);
- } else { /* 'suffix' may represent feature tag. */
- /* Try loading GSUB only when length of 'suffix' is less
- * than or equal to 4. tt_gsub give a warning otherwise.
- */
- if (strlen(s) > 4)
- error = -1; /* Uh */
- else if (strlen(s) == 4)
- error = select_gsub(s, gm);
- else { /* less than 4. pad ' '. */
- memset(t, ' ', 4); t[4] = '\0';
- memcpy(t, s, strlen(s));
- error = select_gsub(t, gm);
- }
- if (!error) /* 'suffix' represents feature tag. */
- error = otl_gsub_apply(gm->gsub, &in);
- else { /* other case: alt1, nalt10... (alternates) */
- for (q = s + strlen(s) - 1; q > s && *q >= '0' && *q <= '9'; q--);
- if (q == s)
- error = -1;
- else { /* starting at 1 */
- n = atoi(q + 1) - 1; q[1] = '\0';
- if (strlen(s) > 4)
- error = -1;
- else { /* This may be alternate substitution. */
- memset(t, ' ', 4); t[4] = '\0';
- memcpy(t, s, strlen(s));
- error = select_gsub(s, gm);
- if (!error)
- error = otl_gsub_apply_alt(gm->gsub, (USHORT)n, (USHORT *)&in);
- }
- }
- }
- }
- RELEASE(s);
-
- *out = in;
- return error;
-}
-
-
-/* Compose glyphs via ligature substitution. */
-static int
-composeglyph (USHORT *glyphs, int n_glyphs,
- const char *feat, struct glyph_mapper *gm, USHORT *gid)
-{
- int error = 0;
- char t[5] = {' ', ' ', ' ', ' ', 0};
-
- ASSERT(glyphs && n_glyphs > 0 && gm && gid);
-
- if (!feat || feat[0] == '\0') /* meaning "Unknown" */
- error = select_gsub("(?lig|lig?|?cmp|cmp?|frac|afrc)", gm);
- else {
- if (strlen(feat) > 4)
- error = -1;
- else {
- memcpy(t, feat, strlen(feat));
- error = select_gsub(t, gm);
- }
- }
-
- if (!error)
- error = otl_gsub_apply_lig(gm->gsub, (USHORT *)glyphs, (USHORT)n_glyphs,
- (USHORT *)gid);
-
- return error;
-}
-
-/* This may be called by findparanoiac(). */
-static int
-composeuchar (long *unicodes, int n_unicodes,
- const char *feat, struct glyph_mapper *gm, USHORT *gid)
-{
- USHORT *gids;
- int i, error = 0;
-
- if (!gm->codetogid)
- return -1;
-
- gids = NEW(n_unicodes, USHORT);
- for (i = 0;
- !error && i < n_unicodes; i++) {
- gids[i] = tt_cmap_lookup(gm->codetogid, unicodes[i]);
- error = (gids[i] == 0) ? -1 : 0;
- }
-
- if (!error)
- error = composeglyph(gids, n_unicodes, feat, gm, gid);
-
- RELEASE(gids);
-
- return error;
-}
-
-/* Search 'post' table. */
-static int
-findposttable (const char *glyph_name, USHORT *gid, struct glyph_mapper *gm)
-{
- if (!gm->nametogid)
- return -1;
-
- *gid = tt_lookup_post_table(gm->nametogid, glyph_name);
-#if 0
- if (verbose > 1)
- {
- if (*gid > 0)
- MESG("%s =post=> 0x%04X\n", glyph_name, *gid);
- }
-#endif
-
- return (*gid == 0 ? -1 : 0);
-}
-
-/* This is wrong. We must care about '.'. */
-#define is_comp(n) (strchr((n), '_') != NULL)
-
-/* Glyph names are concatinated with '_'. */
-static int
-findcomposite (const char *glyphname, USHORT *gid, struct glyph_mapper *gm)
-{
- char *gname, *suffix = NULL;
- USHORT gids[32];
- char *nptrs[32];
- int i, n_comp;
- int error = 0;
-
- error = findposttable(glyphname, gid, gm);
- if (!error)
- return 0;
-
- gname = NEW(strlen(glyphname) + 1, char);
- strcpy(gname, glyphname);
-
- memset(gids, 0, 32 * sizeof(USHORT));
- n_comp = agl_decompose_glyphname(gname, nptrs, 32, &suffix);
- for (error = 0, i = 0; !error && i < n_comp; i++) {
- error = resolve_glyph(nptrs[i], &gids[i], gm);
- if (error)
- WARN("Could not resolve glyph \"%s\" (%dth component of glyph \"%s\").",
- nptrs[i], i, glyphname);
- }
-
- if (!error) {
- if (suffix &&
- (!strcmp(suffix, "liga") || !strcmp(suffix, "dlig") ||
- !strcmp(suffix, "hlig") || !strcmp(suffix, "frac") ||
- !strcmp(suffix, "ccmp") || !strcmp(suffix, "afrc")
- )
- ) {
- error = composeglyph(gids, n_comp, suffix, gm, gid);
- } else { /* first try composing glyph */
- error = composeglyph(gids, n_comp, NULL, gm, gid);
- if (!error && suffix) /* a_b_c.vert */
- error = selectglyph(*gid, suffix, gm, gid);
- }
- }
- RELEASE(gname);
-
- return error;
-}
-
-/* glyphname should not have suffix here */
-static int
-findparanoiac (const char *glyphname, USHORT *gid, struct glyph_mapper *gm)
-{
- agl_name *agln;
- USHORT idx = 0U;
- int error = 0;
-
- agln = agl_lookup_list(glyphname);
- while (agln && idx == 0) {
- if (agln->suffix) {
- error = findparanoiac(agln->name, &idx, gm);
- if (error)
- return error;
-
- error = selectglyph(idx, agln->suffix, gm, &idx);
- if (error) {
- WARN("Variant \"%s\" for glyph \"%s\" might not be found.",
- agln->suffix, agln->name);
- WARN("Using glyph name without suffix instead...");
- error = 0; /* ignore */
- }
- } else {
- if (agln->n_components == 1)
- idx = tt_cmap_lookup(gm->codetogid, agln->unicodes[0]);
- else if (agln->n_components > 1) {
- if (verbose >= 0) /* give warning */
- WARN("Glyph \"%s\" looks like a composite glyph...",
- agln->name);
- error = composeuchar(agln->unicodes, agln->n_components, NULL, gm, &idx);
- if (verbose >= 0) {
- if (error)
- WARN("Not found...");
- else {
- int _i, _n = 0;
- char *_p, _buf[256];
- WARN(">> Composite glyph glyph-name=\"%s\" found at glyph-id=\"%u\".",
- agln->name, idx);
- for (_p = _buf, _i = 0; _i < agln->n_components && _n < 245; _i++) {
- _p[_n++] = _i == 0 ? '<' : ' ';
- if (agln->unicodes[_i] >= 0x10000)
- _n += sprintf(_p+_n, "U+%06lX", agln->unicodes[_i]);
- else
- _n += sprintf(_p+_n, "U+%04lX", agln->unicodes[_i]);
- _p[_n++] = _i == agln->n_components - 1 ? '>' : ',';
- }
- _p[_n++] = '\0';
- WARN(">> Input Unicode seq.=\"%s\" ==> glyph-id=\"%u\" in font-file=\"_please_try_-v_\".", _buf, idx);
- }
- }
- } else ASSERT(0); /* Boooo */
- }
- agln = agln->alternate;
- }
-
- *gid = idx;
- return (idx == 0 ? -1 : 0);
-}
-
-static int
-resolve_glyph (const char *glyphname, USHORT *gid, struct glyph_mapper *gm)
-{
- int error = 0;
- char *name, *suffix = NULL;
- long ucv;
-
- ASSERT(glyphname);
-
- /*
- * First we try glyph name to GID mapping using post table if post table
- * is available. If post table is not available or glyph is not listed
- * in the post table, then we try Unicode if Windows-Unicode TrueType
- * cmap is available.
- */
- error = findposttable(glyphname, gid, gm);
- if (!error)
- return 0;
-
- if (!gm->codetogid)
- return -1;
-
- name = agl_chop_suffix(glyphname, &suffix);
- if (!name) /* .notdef, .foo */
- error = -1;
- else if (agl_name_is_unicode(name)) {
- ucv = agl_name_convert_unicode(name);
- *gid = tt_cmap_lookup(gm->codetogid, ucv);
- error = (*gid == 0) ? -1 : 0;
- } else {
- error = findparanoiac(name, gid, gm);
- }
- if (!error && suffix) {
- error = selectglyph(*gid, suffix, gm, gid);
- if (error) {
- WARN("Variant \"%s\" for glyph \"%s\" might not be found.",
- suffix, name);
- WARN("Using glyph name without suffix instead...");
- error = 0; /* ignore */
- }
- }
- if (suffix)
- RELEASE(suffix);
- if (name)
- RELEASE(name);
-
- return error;
-}
-
-/* Things are complicated. We still need to use PostScript
- * glyph names. But OpenType fonts may not have PS name to
- * glyph mapping. We use Unicode plus OTL GSUB for finding
- * glyphs in this case.
- */
-static int
-setup_glyph_mapper (struct glyph_mapper *gm, sfnt *sfont)
-{
- gm->sfont = sfont;
- gm->nametogid = tt_read_post_table(sfont);
- gm->codetogid = tt_cmap_read(sfont, TT_WIN, TT_WIN_UCS4);
- if (!gm->codetogid)
- gm->codetogid = tt_cmap_read(sfont, TT_WIN, TT_WIN_UNICODE);
-
- if (!gm->nametogid && !gm->codetogid)
- return -1;
-
- gm->gsub = otl_gsub_new();
-
- return 0;
-}
-
-static void
-clean_glyph_mapper (struct glyph_mapper *gm)
-{
- if (gm->gsub)
- otl_gsub_release(gm->gsub);
- if (gm->codetogid)
- tt_cmap_release (gm->codetogid);
- if (gm->nametogid)
- tt_release_post_table(gm->nametogid);
-
- gm->gsub = NULL;
- gm->codetogid = NULL;
- gm->nametogid = NULL;
- gm->sfont = NULL;
-
- return;
-}
-
-static int
-do_custom_encoding (pdf_font *font,
- char **encoding, const char *usedchars, sfnt *sfont)
-{
- struct tt_glyphs *glyphs;
- char *cmap_table;
- int code, count;
- double widths[256];
- struct glyph_mapper gm;
- USHORT idx, gid;
- int error = 0;
-
- ASSERT(font && encoding && usedchars && sfont);
-
- error = setup_glyph_mapper(&gm, sfont);
- if (error) {
- WARN("No post table nor Unicode cmap found in font: %s",
- pdf_font_get_ident(font));
- WARN(">> I can't find glyphs without this!");
- return -1;
- }
-
- cmap_table = NEW(274, char);
- memset(cmap_table, 0, 274);
- sfnt_put_ushort(cmap_table, 0); /* Version */
- sfnt_put_ushort(cmap_table+2, 1); /* Number of subtables */
- sfnt_put_ushort(cmap_table+4, TT_MAC); /* Platform ID */
- sfnt_put_ushort(cmap_table+6, TT_MAC_ROMAN); /* Encoding ID */
- sfnt_put_ulong (cmap_table+8, 12); /* Offset */
- sfnt_put_ushort(cmap_table+12, 0); /* Format */
- sfnt_put_ushort(cmap_table+14, 262); /* Length */
- sfnt_put_ushort(cmap_table+16, 0); /* Language */
-
- glyphs = tt_build_init();
-
- count = 1; /* +1 for .notdef */
- for (code = 0; code < 256; code++) {
- if (!usedchars[code])
- continue;
-
- if (!encoding[code] || !strcmp(encoding[code], ".notdef")) {
- WARN("Character code=\"0x%02X\" mapped to \".notdef\" glyph used in font font-file=\"%s\"",
- code, pdf_font_get_ident(font));
- WARN(">> Maybe incorrect encoding specified?");
- idx = 0;
- } else {
- if (is_comp(encoding[code]))
- error = findcomposite(encoding[code], &gid, &gm);
- else
- error = resolve_glyph(encoding[code], &gid, &gm);
-
- /*
- * Older versions of gs had problem with glyphs (other than .notdef)
- * mapped to gid = 0.
- */
- if (error) {
- WARN("Glyph \"%s\" not available in font \"%s\".",
- encoding[code], pdf_font_get_ident(font));
- } else {
- if (verbose > 1)
- MESG("truetype>> Glyph glyph-name=\"%s\" found at glyph-id=\"%u\".\n", encoding[code], gid);
- }
- idx = tt_find_glyph(glyphs, gid);
- if (idx == 0) {
- idx = tt_add_glyph(glyphs, (USHORT)gid, (USHORT)count); /* count returned. */
- count++;
- }
- }
- cmap_table[18 + code] = idx & 0xff; /* bug here */
- }
- clean_glyph_mapper(&gm);
-
- if (tt_build_tables(sfont, glyphs) < 0) {
- WARN("Packing TrueType font into SFNT file faild..."); /* _FIXME_: wrong message */
- tt_build_finish(glyphs);
- RELEASE(cmap_table);
- return -1;
- }
-
- for (code = 0; code < 256; code++) {
- if (usedchars[code]) {
- idx = tt_get_index(glyphs, (USHORT) cmap_table[18+code]);
- widths[code] = PDFUNIT(glyphs->gd[idx].advw);
- } else {
- widths[code] = 0.0;
- }
- }
- do_widths(font, widths);
-
- if (verbose > 1)
- MESG("[%d glyphs]", glyphs->num_glyphs);
-
- tt_build_finish(glyphs);
-
- sfnt_set_table(sfont, "cmap", cmap_table, 274);
-
- return 0;
-}
-
-int
-pdf_font_load_truetype (pdf_font *font)
-{
- pdf_obj *descriptor = pdf_font_get_descriptor(font);
- char *ident = pdf_font_get_ident(font);
- int encoding_id = pdf_font_get_encoding(font);
- char *usedchars = pdf_font_get_usedchars(font);
-#ifdef ENABLE_NOEMBED
- int embedding = pdf_font_get_flag(font, PDF_FONT_FLAG_NOEMBED) ? 0 : 1;
-#endif /* ENABLE_NOEMBED */
- int index = pdf_font_get_index(font);
- char **enc_vec;
- pdf_obj *fontfile;
- FILE *fp = NULL;
- sfnt *sfont;
- int i, error = 0;
-
- if (!pdf_font_is_in_use(font))
- return 0;
-
- verbose = pdf_font_get_verbose();
-
-#ifdef XETEX
- sfont = sfnt_open(pdf_font_get_ft_face(font), SFNT_TYPE_TTC | SFNT_TYPE_TRUETYPE);
-#else
- if (!fp) {
- fp = DPXFOPEN(ident, DPX_RES_TYPE_DFONT);
- if (!fp) ERROR("Unable to open TrueType/dfont font file: %s", ident); /* Should find *truetype* here */
- sfont = dfont_open(fp, index);
- } else {
- sfont = sfnt_open(fp);
- }
-#endif
-
- if (!sfont) {
- ERROR("Unable to open TrueType/dfont file: %s", ident);
- if (fp)
- DPXFCLOSE(fp);
- return -1;
- } else if (sfont->type != SFNT_TYPE_TRUETYPE &&
- sfont->type != SFNT_TYPE_TTC &&
- sfont->type != SFNT_TYPE_DFONT) {
- ERROR("Font \"%s\" not a TrueType/dfont font?", ident);
- sfnt_close(sfont);
- if (fp)
- DPXFCLOSE(fp);
- return -1;
- }
-
- if (sfont->type == SFNT_TYPE_TTC) {
- unsigned long offset;
- offset = ttc_read_offset(sfont, index);
- if (offset == 0) ERROR("Invalid TTC index in %s.", ident);
- error = sfnt_read_table_directory(sfont, ttc_read_offset(sfont, offset));
- } else {
- error = sfnt_read_table_directory(sfont, sfont->offset);
- }
-
- if (error) {
- ERROR("Reading SFND table dir failed for font-file=\"%s\"... Not a TrueType font?", ident);
- sfnt_close(sfont);
- if (fp)
- DPXFCLOSE(fp);
- return -1;
- }
-
- /*
- * Create new TrueType cmap table with MacRoman encoding.
- */
- if (encoding_id < 0)
- error = do_builtin_encoding(font, usedchars, sfont);
- else {
- enc_vec = pdf_encoding_get_encoding(encoding_id);
- error = do_custom_encoding(font, enc_vec, usedchars, sfont);
- }
- if (error) {
- ERROR("Error occured while creating font subfont for \"%s\"", ident);
- sfnt_close(sfont);
- if (fp)
- DPXFCLOSE(fp);
- return -1;
- }
-
-#if ENABLE_NOEMBED
- if (!embedding) {
- sfnt_close(sfont);
- if (fp)
- DPXFCLOSE(fp);
- return 0;
- }
-#endif /* ENABLE_NOEMBED */
-
- /*
- * TODO: post table?
- */
-
- for (i = 0; required_table[i].name != NULL; i++) {
- if (sfnt_require_table(sfont,
- required_table[i].name,
- required_table[i].must_exist) < 0) {
- ERROR("Required TrueType table \"%s\" does not exist in font: %s",
- required_table[i].name, ident);
- sfnt_close(sfont);
- if (fp)
- DPXFCLOSE(fp);
- return -1;
- }
- }
-
- /*
- * FontFile2
- */
- fontfile = sfnt_create_FontFile_stream(sfont);
- if (!fontfile)
- ERROR("Could not created FontFile stream for \"%s\".", ident);
-
- sfnt_close(sfont);
- if (fp)
- DPXFCLOSE(fp);
-
- if (verbose > 1)
- MESG("[%ld bytes]", pdf_stream_length(fontfile));
-
- pdf_add_dict(descriptor,
- pdf_new_name("FontFile2"), pdf_ref_obj(fontfile)); /* XXX */
- pdf_release_obj(fontfile);
-
- return 0;
-}
diff --git a/Build/source/texk/dvipdfm-x/xsrc/tt_cmap.c b/Build/source/texk/dvipdfm-x/xsrc/tt_cmap.c
index a2d800890eb..9bf9f4506da 100644
--- a/Build/source/texk/dvipdfm-x/xsrc/tt_cmap.c
+++ b/Build/source/texk/dvipdfm-x/xsrc/tt_cmap.c
@@ -851,7 +851,7 @@ handle_subst_glyphs (CMap *cmap,
{
USHORT count;
USHORT i, gid;
-
+
for (count = 0, i = 0; i < 8192; i++) {
int j;
long len, inbytesleft, outbytesleft;
@@ -1062,6 +1062,7 @@ create_ToUnicode_cmap12 (struct cmap12 *map,
return stream;
}
+#ifdef XETEX
typedef struct {
short platform;
short encoding;
@@ -1074,6 +1075,7 @@ static cmap_plat_enc_rec cmap_plat_encs[] = {
{ 3, 1 },
{ 0, 1 }
};
+#endif
pdf_obj *
otf_create_ToUnicode_stream (const char *font_name,
@@ -1688,8 +1690,8 @@ otf_load_Unicode_CMap (const char *map_name, int ttc_index, /* 0 for non-TTC fon
return -1; /* Sorry for this... */
}
-fprintf(stderr, "otf_load_Unicode_CMap(%s, %d)\n", map_name, ttc_index);
#ifdef XETEX
+ fprintf(stderr, "otf_load_Unicode_CMap(%s, %d)\n", map_name, ttc_index);
sfont = NULL; /* FIXME */
#else
fp = DPXFOPEN(map_name, DPX_RES_TYPE_TTFONT);
diff --git a/Build/source/texk/dvipdfm-x/xsrc/type1.c b/Build/source/texk/dvipdfm-x/xsrc/type1.c
deleted file mode 100644
index 2864e45f993..00000000000
--- a/Build/source/texk/dvipdfm-x/xsrc/type1.c
+++ /dev/null
@@ -1,805 +0,0 @@
-/*
-
- This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
-
- Copyright (C) 2008-2012 by Jin-Hwan Cho, Matthias Franz, 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 <string.h>
-#include <math.h>
-
-#include "system.h"
-#include "mem.h"
-#include "error.h"
-
-#include "dpxfile.h"
-
-#include "numbers.h"
-
-#include "pdfobj.h"
-#include "pdffont.h"
-
-#include "pdfencoding.h"
-#include "unicode.h"
-
-#include "dpxutil.h"
-
-#include "pst_obj.h"
-#include "pst.h"
-
-#include "cff_limits.h"
-#include "cff_types.h"
-#include "cff_dict.h"
-#include "cff.h"
-
-#include "t1_load.h"
-#include "t1_char.h"
-
-#include "type1.h"
-
-#include "tfm.h"
-
-#define FONT_FLAG_FIXEDPITCH (1 << 0) /* Fixed-width font */
-#define FONT_FLAG_SERIF (1 << 1) /* Serif font */
-#define FONT_FLAG_SYMBOLIC (1 << 2) /* Symbolic font */
-#define FONT_FLAG_SCRIPT (1 << 3) /* Script font */
-#define FONT_FLAG_STANDARD (1 << 5) /* Adobe Standard Character Set */
-#define FONT_FLAG_ITALIC (1 << 6) /* Italic */
-#define FONT_FLAG_ALLCAP (1 << 16) /* All-cap font */
-#define FONT_FLAG_SMALLCAP (1 << 17) /* Small-cap font */
-#define FONT_FLAG_FORCEBOLD (1 << 18) /* Force bold at small text sizes */
-
-static int
-is_basefont (const char *name)
-{
- static const char *basefonts[] = {
- "Courier", "Courier-Bold", "Courier-Oblique",
- "Courier-BoldOblique", "Helvetica", "Helvetica-Bold",
- "Helvetica-Oblique", "Helvetica-BoldOblique", "Symbol",
- "Times-Roman", "Times-Bold", "Times-Italic",
- "Times-BoldItalic", "ZapfDingbats"
- };
- int i;
-
- for (i = 0; i < 14; i++) {
- if (!strcmp(name, basefonts[i]))
- return 1;
- }
-
- return 0;
-}
-
-int
-pdf_font_open_type1 (pdf_font *font)
-{
- char *ident;
- FILE *fp;
- char fontname[PDF_NAME_LEN_MAX+1];
-
- ASSERT(font);
-
- ident = pdf_font_get_ident(font);
-
- if (is_basefont(ident)) {
- pdf_font_set_fontname(font, ident);
- pdf_font_set_subtype (font, PDF_FONT_FONTTYPE_TYPE1);
- pdf_font_set_flags (font,
- (PDF_FONT_FLAG_NOEMBED|PDF_FONT_FLAG_BASEFONT));
- } else {
- fp = DPXFOPEN(ident, DPX_RES_TYPE_T1FONT);
- if (!fp)
- return -1;
-
- memset(fontname, 0, PDF_NAME_LEN_MAX+1);
- if (!is_pfb(fp) || t1_get_fontname(fp, fontname) < 0) {
- ERROR("Failed to read Type 1 font \"%s\".", ident);
- }
- DPXFCLOSE(fp);
-
- pdf_font_set_fontname(font, fontname);
- pdf_font_set_subtype (font, PDF_FONT_FONTTYPE_TYPE1);
- }
-
- return 0;
-}
-
-static void
-get_font_attr (pdf_font *font, cff_font *cffont)
-{
- char *fontname;
- pdf_obj *descriptor;
- double capheight, ascent, descent;
- double italicangle, stemv;
- double defaultwidth, nominalwidth;
- long flags = 0, gid, i;
- static const char *L_c[] = {
- "H", "P", "Pi", "Rho", NULL
- };
- static const char *L_d[] = {
- "p", "q", "mu", "eta", NULL
- };
- static const char *L_a[] = {
- "b", "h", "lambda", NULL
- };
- t1_ginfo gm;
-
- defaultwidth = 500.0;
- nominalwidth = 0.0;
-
- /*
- * CapHeight, Ascent, and Descent is meaningfull only for Latin/Greek/Cyrillic.
- * The BlueValues and OtherBlues also have those information.
- */
- if (cff_dict_known(cffont->topdict, "FontBBox")) {
- /* Default values */
- capheight = ascent = cff_dict_get(cffont->topdict, "FontBBox", 3);
- descent = cff_dict_get(cffont->topdict, "FontBBox", 1);
- } else {
- capheight = 680.0;
- ascent = 690.0;
- descent = -190.0;
- }
- if (cff_dict_known(cffont->private[0], "StdVW")) {
- stemv = cff_dict_get(cffont->private[0], "StdVW", 0);
- } else {
- /*
- * We may use the following values for StemV:
- * Thin - ExtraLight: <= 50
- * Light: 71
- * Regular(Normal): 88
- * Medium: 109
- * SemiBold(DemiBold): 135
- * Bold - Heavy: >= 166
- */
- stemv = 88.0;
- }
- if (cff_dict_known(cffont->topdict, "ItalicAngle")) {
- italicangle = cff_dict_get(cffont->topdict, "ItalicAngle", 0);
- if (italicangle != 0.0)
- flags |= FONT_FLAG_ITALIC;
- } else {
- italicangle = 0.0;
- }
-
- /*
- * Use "space", "H", "p", and "b" for various values.
- * Those characters should not "seac". (no accent)
- */
- gid = cff_glyph_lookup(cffont, "space");
- if (gid >= 0 && gid < cffont->cstrings->count) {
- t1char_get_metrics(cffont->cstrings->data + cffont->cstrings->offset[gid] - 1,
- cffont->cstrings->offset[gid+1] - cffont->cstrings->offset[gid],
- cffont->subrs[0], &gm);
- defaultwidth = gm.wx;
- }
-
- for (i = 0; L_c[i] != NULL; i++) {
- gid = cff_glyph_lookup(cffont, L_c[i]);
- if (gid >= 0 && gid < cffont->cstrings->count) {
- t1char_get_metrics(cffont->cstrings->data + cffont->cstrings->offset[gid] - 1,
- cffont->cstrings->offset[gid+1] - cffont->cstrings->offset[gid],
- cffont->subrs[0], &gm);
- capheight = gm.bbox.ury;
- break;
- }
- }
-
- for (i = 0; L_d[i] != NULL; i++) {
- gid = cff_glyph_lookup(cffont, L_d[i]);
- if (gid >= 0 && gid < cffont->cstrings->count) {
- t1char_get_metrics(cffont->cstrings->data + cffont->cstrings->offset[gid] - 1,
- cffont->cstrings->offset[gid+1] - cffont->cstrings->offset[gid],
- cffont->subrs[0], &gm);
- descent = gm.bbox.lly;
- break;
- }
- }
-
- for (i = 0; L_a[i] != NULL; i++) {
- gid = cff_glyph_lookup(cffont, L_a[i]);
- if (gid >= 0 && gid < cffont->cstrings->count) {
- t1char_get_metrics(cffont->cstrings->data + cffont->cstrings->offset[gid] - 1,
- cffont->cstrings->offset[gid+1] - cffont->cstrings->offset[gid],
- cffont->subrs[0], &gm);
- ascent = gm.bbox.ury;
- break;
- }
- }
-
- if (defaultwidth != 0.0) {
- cff_dict_add(cffont->private[0], "defaultWidthX", 1);
- cff_dict_set(cffont->private[0], "defaultWidthX", 0, defaultwidth);
- }
- if (nominalwidth != 0.0) {
- cff_dict_add(cffont->private[0], "nominalWidthX", 1);
- cff_dict_set(cffont->private[0], "nominalWidthX", 0, nominalwidth);
- }
- if (cff_dict_known(cffont->private[0], "ForceBold") &&
- cff_dict_get(cffont->private[0], "ForceBold", 0)) {
- flags |= FONT_FLAG_FORCEBOLD;
- }
- if (cff_dict_known(cffont->private[0], "IsFixedPitch") &&
- cff_dict_get(cffont->private[0], "IsFixedPitch", 0)) {
- flags |= FONT_FLAG_FIXEDPITCH;
- }
-
- fontname = pdf_font_get_fontname (font);
- descriptor = pdf_font_get_descriptor(font);
-
- if (fontname && !strstr(fontname, "Sans")) {
- flags |= FONT_FLAG_SERIF;
- }
- if (fontname && strstr(fontname, "Caps")) {
- flags |= FONT_FLAG_SMALLCAP;
- }
- flags |= FONT_FLAG_SYMBOLIC; /* FIXME */
-
- pdf_add_dict(descriptor,
- pdf_new_name("CapHeight"), pdf_new_number(capheight));
- pdf_add_dict(descriptor,
- pdf_new_name("Ascent"), pdf_new_number(ascent));
- pdf_add_dict(descriptor,
- pdf_new_name("Descent"), pdf_new_number(descent));
- pdf_add_dict(descriptor,
- pdf_new_name("ItalicAngle"), pdf_new_number(italicangle));
- pdf_add_dict(descriptor,
- pdf_new_name("StemV"), pdf_new_number(stemv));
- pdf_add_dict(descriptor,
- pdf_new_name("Flags"), pdf_new_number(flags));
-}
-
-static void
-add_metrics (pdf_font *font, cff_font *cffont, char **enc_vec, double *widths, long num_glyphs)
-{
- pdf_obj *fontdict, *descriptor;
- pdf_obj *tmp_array;
- int code, firstchar, lastchar;
- double val;
- int i, tfm_id;
- char *usedchars;
- double scaling;
-
- fontdict = pdf_font_get_resource (font);
- descriptor = pdf_font_get_descriptor(font);
- usedchars = pdf_font_get_usedchars (font);
-
- /*
- * The original FontBBox of the font is preserved, instead
- * of replacing it with tight bounding box calculated from
- * charstrings, to prevent Acrobat 4 from greeking text as
- * much as possible.
- */
- if (!cff_dict_known(cffont->topdict, "FontBBox")) {
- ERROR("No FontBBox?");
- }
-
- /* The widhts array in the font dictionary must be given relative
- * to the default scaling of 1000:1, not relative to the scaling
- * given by the font matrix.
- */
- if (cff_dict_known(cffont->topdict, "FontMatrix"))
- scaling = 1000*cff_dict_get(cffont->topdict, "FontMatrix", 0);
- else
- scaling = 1;
-
- tmp_array = pdf_new_array();
- for (i = 0; i < 4; i++) {
- val = cff_dict_get(cffont->topdict, "FontBBox", i);
- pdf_add_array(tmp_array, pdf_new_number(ROUND(val, 1.0)));
- }
- pdf_add_dict(descriptor, pdf_new_name("FontBBox"), tmp_array);
-
- tmp_array = pdf_new_array();
- if (num_glyphs <= 1) { /* This must be an error. */
- firstchar = lastchar = 0;
- pdf_add_array(tmp_array, pdf_new_number(0.0));
- } else {
- for (firstchar = 255, lastchar = 0, code = 0; code < 256; code++) {
- if (usedchars[code]) {
- if (code < firstchar) firstchar = code;
- if (code > lastchar) lastchar = code;
- }
- }
- if (firstchar > lastchar) {
- WARN("No glyphs actually used???");
- pdf_release_obj(tmp_array);
- return;
- }
- tfm_id = tfm_open(pdf_font_get_mapname(font), 0);
- for (code = firstchar; code <= lastchar; code++) {
- if (usedchars[code]) {
- double width;
- if (tfm_id < 0) /* tfm is not found */
- width = scaling * widths[cff_glyph_lookup(cffont, enc_vec[code])];
- else
- width = 1000. * tfm_get_width(tfm_id, code);
- pdf_add_array(tmp_array,
- pdf_new_number(ROUND(width, 0.1)));
- } else {
- pdf_add_array(tmp_array, pdf_new_number(0.0));
- }
- }
- }
-
- if (pdf_array_length(tmp_array) > 0) {
- pdf_add_dict(fontdict,
- pdf_new_name("Widths"), pdf_ref_obj(tmp_array));
- }
- pdf_release_obj(tmp_array);
-
- pdf_add_dict(fontdict,
- pdf_new_name("FirstChar"), pdf_new_number(firstchar));
- pdf_add_dict(fontdict,
- pdf_new_name("LastChar"), pdf_new_number(lastchar));
-
- return;
-}
-
-
-static long
-write_fontfile (pdf_font *font, cff_font *cffont, long num_glyphs)
-{
- pdf_obj *descriptor;
- pdf_obj *fontfile, *stream_dict;
- cff_index *topdict;
- long private_size, stream_data_len, charstring_len;
- long topdict_offset, offset;
-#define WBUF_SIZE 1024
- card8 *stream_data_ptr, wbuf[WBUF_SIZE];
-
- descriptor = pdf_font_get_descriptor(font);
-
- topdict = cff_new_index(1);
- /*
- * Force existence of Encoding.
- */
- if (!cff_dict_known(cffont->topdict, "CharStrings"))
- cff_dict_add(cffont->topdict, "CharStrings", 1);
- if (!cff_dict_known(cffont->topdict, "charset"))
- cff_dict_add(cffont->topdict, "charset", 1);
- if (!cff_dict_known(cffont->topdict, "Encoding"))
- cff_dict_add(cffont->topdict, "Encoding", 1);
- private_size = cff_dict_pack((cffont->private)[0], wbuf, WBUF_SIZE);
- if (private_size > 0 && !cff_dict_known(cffont->topdict, "Private"))
- cff_dict_add(cffont->topdict, "Private", 2);
- topdict->offset[1] = cff_dict_pack(cffont->topdict, wbuf, WBUF_SIZE) + 1;
-
- /*
- * Estimate total size of fontfile.
- */
- charstring_len = cff_index_size(cffont->cstrings);
-
- stream_data_len = 4; /* header size */
- stream_data_len += cff_index_size(cffont->name);
- stream_data_len += cff_index_size(topdict);
- stream_data_len += cff_index_size(cffont->string);
- stream_data_len += cff_index_size(cffont->gsubr);
- /* We are using format 1 for Encoding and format 0 for charset.
- * TODO: Should implement cff_xxx_size().
- */
- stream_data_len += 2 + (cffont->encoding->num_entries)*2 + 1 + (cffont->encoding->num_supps)*3;
- stream_data_len += 1 + (cffont->charsets->num_entries)*2;
- stream_data_len += charstring_len;
- stream_data_len += private_size;
-
- /*
- * Now we create FontFile data.
- */
- stream_data_ptr = NEW(stream_data_len, card8);
- /*
- * Data Layout order as described in CFF spec., sec 2 "Data Layout".
- */
- offset = 0;
- /* Header */
- offset += cff_put_header(cffont,
- stream_data_ptr + offset, stream_data_len - offset);
- /* Name */
- offset += cff_pack_index(cffont->name,
- stream_data_ptr + offset, stream_data_len - offset);
- /* Top DICT */
- topdict_offset = offset;
- offset += cff_index_size(topdict);
- /* Strings */
- offset += cff_pack_index(cffont->string,
- stream_data_ptr + offset, stream_data_len - offset);
- /* Global Subrs */
- offset += cff_pack_index(cffont->gsubr,
- stream_data_ptr + offset, stream_data_len - offset);
- /* Encoding */
- /* TODO: don't write Encoding entry if the font is always used
- * with PDF Encoding information. Applies to type1c.c as well.
- */
- cff_dict_set(cffont->topdict, "Encoding", 0, offset);
- offset += cff_pack_encoding(cffont,
- stream_data_ptr + offset, stream_data_len - offset);
- /* charset */
- cff_dict_set(cffont->topdict, "charset", 0, offset);
- offset += cff_pack_charsets(cffont,
- stream_data_ptr + offset, stream_data_len - offset);
- /* CharStrings */
- cff_dict_set(cffont->topdict, "CharStrings", 0, offset);
- offset += cff_pack_index(cffont->cstrings,
- stream_data_ptr + offset, charstring_len);
- /* Private */
- if ((cffont->private)[0] && private_size > 0) {
- private_size = cff_dict_pack(cffont->private[0],
- stream_data_ptr + offset, private_size);
- cff_dict_set(cffont->topdict, "Private", 1, offset);
- cff_dict_set(cffont->topdict, "Private", 0, private_size);
- }
- offset += private_size;
-
- /* Finally Top DICT */
- topdict->data = NEW(topdict->offset[1] - 1, card8);
- cff_dict_pack (cffont->topdict, topdict->data, topdict->offset[1] - 1);
- cff_pack_index(topdict,
- stream_data_ptr + topdict_offset, cff_index_size(topdict));
- cff_release_index(topdict);
-
- /* Copyright and Trademark Notice ommited. */
-
- /* Flush Font File */
- fontfile = pdf_new_stream(STREAM_COMPRESS);
- stream_dict = pdf_stream_dict(fontfile);
- pdf_add_dict(descriptor,
- pdf_new_name("FontFile3"), pdf_ref_obj (fontfile));
- pdf_add_dict(stream_dict,
- pdf_new_name("Subtype"), pdf_new_name("Type1C"));
- pdf_add_stream (fontfile, (void *) stream_data_ptr, offset);
- pdf_release_obj(fontfile);
-
- RELEASE(stream_data_ptr);
-
- return offset;
-}
-
-
-int
-pdf_font_load_type1 (pdf_font *font)
-{
- pdf_obj *fontdict;
- int encoding_id;
- char *usedchars, *ident;
- char *fontname, *uniqueTag;
- char *fullname; /* With pseudo unique tag */
- cff_font *cffont;
- cff_charsets *charset;
- char **enc_vec;
- double defaultwidth, nominalwidth;
- double *widths;
- card16 *GIDMap, num_glyphs = 0;
- FILE *fp;
- long offset;
- int code, verbose;
-
- ASSERT(font);
-
- if (!pdf_font_is_in_use(font)) {
- return 0;
- }
-
- verbose = pdf_font_get_verbose();
-
- encoding_id = pdf_font_get_encoding (font);
- fontdict = pdf_font_get_resource (font);
-
- pdf_font_get_descriptor(font);
- usedchars = pdf_font_get_usedchars (font);
- ident = pdf_font_get_ident (font);
- fontname = pdf_font_get_fontname (font);
- uniqueTag = pdf_font_get_uniqueTag (font);
- if (!usedchars || !ident || !fontname) {
- ERROR("Type1: Unexpected error.");
- }
-
- fp = DPXFOPEN(ident, DPX_RES_TYPE_T1FONT);
- if (!fp) {
- ERROR("Type1: Could not open Type1 font: %s", ident);
- }
-
- GIDMap = NULL;
- num_glyphs = 0;
-
- if (encoding_id >= 0) {
- enc_vec = NULL;
- } else {
- enc_vec = NEW(256, char *);
- for (code = 0; code <= 0xff; code++) {
- enc_vec[code] = NULL;
- }
- }
-
- cffont = t1_load_font(enc_vec, 0, fp);
- if (!cffont) {
- ERROR("Could not load Type 1 font: %s", ident);
- }
- DPXFCLOSE(fp);
-
- fullname = NEW(strlen(fontname) + 8, char);
- sprintf(fullname, "%6s+%s", uniqueTag, fontname);
-
- /*
- * Encoding related things.
- */
- if (encoding_id >= 0) {
- enc_vec = pdf_encoding_get_encoding(encoding_id);
- } else {
- pdf_obj *tounicode;
-
- /*
- * Create enc_vec and ToUnicode CMap for built-in encoding.
- */
- if (!pdf_lookup_dict(fontdict, "ToUnicode")) {
- tounicode = pdf_create_ToUnicode_CMap(fullname,
- enc_vec, usedchars);
- if (tounicode) {
- pdf_add_dict(fontdict,
- pdf_new_name("ToUnicode"),
- pdf_ref_obj (tounicode));
- pdf_release_obj(tounicode);
- }
- }
- }
-
- cff_set_name(cffont, fullname);
- RELEASE(fullname);
-
- /* defaultWidthX, CapHeight, etc. */
- get_font_attr(font, cffont);
- if (cff_dict_known(cffont->private[0], "defaultWidthX")) {
- defaultwidth = cff_dict_get(cffont->private[0], "defaultWidthX", 0);
- } else {
- defaultwidth = 0.0;
- }
- if (cff_dict_known(cffont->private[0], "nominalWidthX")) {
- nominalwidth = cff_dict_get(cffont->private[0], "nominalWidthX", 0);
- } else {
- nominalwidth = 0.0;
- }
-
- /* Create CFF encoding, charset, sort glyphs */
-#define MAX_GLYPHS 1024
- GIDMap = NEW(MAX_GLYPHS, card16);
- {
- int prev, duplicate;
- long gid;
- char *glyph;
- s_SID sid;
-
- cffont->encoding = NEW(1, cff_encoding);
- cffont->encoding->format = 1;
- cffont->encoding->num_entries = 0;
- cffont->encoding->data.range1 = NEW(256, cff_range1);
- cffont->encoding->num_supps = 0;
- cffont->encoding->supp = NEW(256, cff_map);
-
- charset = NEW(1, cff_charsets);
- charset->format = 0;
- charset->num_entries = 0;
- charset->data.glyphs = NEW(MAX_GLYPHS, s_SID);
-
- gid = cff_glyph_lookup(cffont, ".notdef");
- if (gid < 0)
- ERROR("Type 1 font with no \".notdef\" glyph???");
- GIDMap[0] = (card16) gid;
- if (verbose > 2)
- MESG("[glyphs:/.notdef");
- num_glyphs = 1;
- for (prev = -2, code = 0; code <= 0xff; code++) {
- glyph = enc_vec[code];
-
- if (!usedchars[code])
- continue;
- if (glyph && !strcmp(glyph, ".notdef")) {
- WARN("Character mapped to .notdef used in font: %s",
- fontname);
- usedchars[code] = 0;
- continue;
- }
-
- gid = cff_glyph_lookup(cffont, glyph);
- if (gid < 1 || gid >= cffont->cstrings->count) {
- WARN("Glyph \"%s\" missing in font \"%s\".", glyph, fontname);
- usedchars[code] = 0;
- continue;
- }
-
- for (duplicate = 0; duplicate < code; duplicate++) {
- if (usedchars[duplicate] &&
- enc_vec[duplicate] && !strcmp(enc_vec[duplicate], glyph))
- break;
- }
-
- sid = cff_add_string(cffont, glyph, 1); /* FIXME */
- if (duplicate < code) { /* found duplicates */
- cffont->encoding->supp[cffont->encoding->num_supps].code = duplicate;
- cffont->encoding->supp[cffont->encoding->num_supps].glyph = sid;
- cffont->encoding->num_supps += 1;
- } else {
- GIDMap[num_glyphs] = (card16) gid;
- charset->data.glyphs[charset->num_entries] = sid;
- charset->num_entries += 1;
- if (code != prev + 1) {
- cffont->encoding->num_entries += 1;
- cffont->encoding->data.range1[cffont->encoding->num_entries-1].first = code;
- cffont->encoding->data.range1[cffont->encoding->num_entries-1].n_left = 0;
- } else {
- cffont->encoding->data.range1[cffont->encoding->num_entries-1].n_left += 1;
- }
- prev = code;
- num_glyphs++;
-
- if (verbose > 2) {
- MESG("/%s", glyph);
- }
-
- }
- }
- if (cffont->encoding->num_supps > 0) {
- cffont->encoding->format |= 0x80;
- } else {
- RELEASE(cffont->encoding->supp); /* FIXME */
- cffont->encoding->supp = NULL;
- }
- }
-
- widths = NEW(cffont->cstrings->count, double);
- /*
- * No more string will be added.
- * The Type 1 seac operator may add another glyph but the glyph name of
- * those glyphs are contained in standard string. The String Index will
- * not be modified after here.
- * BUT: We cannot update the String Index yet because then we wouldn't be
- * able to find the GIDs of the base and accent characters (unless they
- * have been used already).
- */
-
- {
- cff_index *cstring;
- t1_ginfo gm;
- card16 gid, gid_orig;
- long dstlen_max, srclen;
- card8 *srcptr, *dstptr;
-
- offset = dstlen_max = 0L;
- cstring = cff_new_index(cffont->cstrings->count);
- cstring->data = NULL;
- cstring->offset[0] = 1;
-
- /* The num_glyphs increases if "seac" operators are used. */
- for (gid = 0; gid < num_glyphs; gid++) {
- if (offset + CS_STR_LEN_MAX >= dstlen_max) {
- dstlen_max += CS_STR_LEN_MAX * 2;
- cstring->data = RENEW(cstring->data, dstlen_max, card8);
- }
- gid_orig = GIDMap[gid];
-
- dstptr = cstring->data + cstring->offset[gid] - 1;
- srcptr = cffont->cstrings->data + cffont->cstrings->offset[gid_orig] - 1;
- srclen = cffont->cstrings->offset[gid_orig + 1] - cffont->cstrings->offset[gid_orig];
-
- offset += t1char_convert_charstring(dstptr, CS_STR_LEN_MAX,
- srcptr, srclen,
- cffont->subrs[0], defaultwidth, nominalwidth, &gm);
- cstring->offset[gid + 1] = offset + 1;
- if (gm.use_seac) {
- long bchar_gid, achar_gid, i;
- const char *bchar_name, *achar_name;
-
- /*
- * NOTE:
- * 1. seac.achar and seac.bchar must be contained in the CFF standard string.
- * 2. Those characters need not to be encoded.
- * 3. num_glyphs == charsets->num_entries + 1.
- */
- achar_name = t1_get_standard_glyph(gm.seac.achar);
- achar_gid = cff_glyph_lookup(cffont, achar_name);
- bchar_name = t1_get_standard_glyph(gm.seac.bchar);
- bchar_gid = cff_glyph_lookup(cffont, bchar_name);
- if (achar_gid < 0) {
- WARN("Accent char \"%s\" not found. Invalid use of \"seac\" operator.",
- achar_name);
- continue;
- }
- if (bchar_gid < 0) {
- WARN("Base char \"%s\" not found. Invalid use of \"seac\" operator.",
- bchar_name);
- continue;
- }
-
- for (i = 0; i < num_glyphs; i++) {
- if (GIDMap[i] == achar_gid)
- break;
- }
- if (i == num_glyphs) {
- if (verbose > 2)
- MESG("/%s", achar_name);
- GIDMap[num_glyphs++] = achar_gid;
- charset->data.glyphs[charset->num_entries] = cff_get_seac_sid(cffont, achar_name);
- charset->num_entries += 1;
- }
-
- for (i = 0; i < num_glyphs; i++) {
- if (GIDMap[i] == bchar_gid)
- break;
- }
- if (i == num_glyphs) {
- if (verbose > 2)
- MESG("/%s", bchar_name);
- GIDMap[num_glyphs++] = bchar_gid;
- charset->data.glyphs[charset->num_entries] = cff_get_seac_sid(cffont, bchar_name);
- charset->num_entries += 1;
- }
- }
- widths[gid] = gm.wx;
- }
- cstring->count = num_glyphs;
-
- cff_release_index(cffont->subrs[0]);
- cffont->subrs[0] = NULL;
- RELEASE(cffont->subrs);
- cffont->subrs = NULL;
-
- cff_release_index(cffont->cstrings);
- cffont->cstrings = cstring;
-
- cff_release_charsets(cffont->charsets);
- cffont->charsets = charset;
- }
- if (verbose > 2)
- MESG("]");
-
- /* Now we can update the String Index */
- cff_dict_update (cffont->topdict, cffont);
- cff_dict_update (cffont->private[0], cffont);
- cff_update_string(cffont);
-
- add_metrics(font, cffont, enc_vec, widths, num_glyphs);
-
- offset = write_fontfile(font, cffont, num_glyphs);
- if (verbose > 1)
- MESG("[%u glyphs][%ld bytes]", num_glyphs, offset);
-
- cff_close(cffont);
-
- /* Cleanup */
- if (encoding_id < 0 && enc_vec) {
- for (code = 0; code < 256; code++) {
- if (enc_vec[code])
- RELEASE(enc_vec[code]);
- enc_vec[code] = NULL;
- }
- RELEASE(enc_vec);
- }
- if (widths)
- RELEASE(widths);
- if (GIDMap)
- RELEASE(GIDMap);
-
- /*
- * Maybe writing Charset is recommended for subsetted font.
- */
-
- return 0;
-}
diff --git a/Build/source/texk/dvipdfm-x/xsrc/xbb.c b/Build/source/texk/dvipdfm-x/xsrc/xbb.c
index a8564b1e042..da771659c78 100644
--- a/Build/source/texk/dvipdfm-x/xsrc/xbb.c
+++ b/Build/source/texk/dvipdfm-x/xsrc/xbb.c
@@ -119,8 +119,6 @@ static char *make_xbb_filename(const char *name)
return result;
}
-static const char *xbb_file_mode = FOPEN_W_MODE;
-
static void write_xbb(char *fname,
double bbllx_f, double bblly_f,
double bburx_f, double bbury_f,
@@ -208,29 +206,6 @@ static void do_png (FILE *fp, char *filename)
#endif /* HAVE_LIBPNG */
#ifdef XETEX
-static void write_xbb_old(char *fname, int bbllx, int bblly, int bburx, int bbury)
-{
- char *outname;
- FILE *fp;
-
- outname = make_xbb_filename(fname);
- if ((fp = MFOPEN(outname, xbb_file_mode)) == NULL) {
- fprintf(stderr, "Unable to open output file: %s\n", outname);
- RELEASE(outname);
- return;
- }
- if (verbose) {
- MESG("Writing to %s: ", outname);
- MESG("Bounding box: %d %d %d %d\n", bbllx, bblly, bburx, bbury);
- }
- fprintf(fp, "%%%%Title: %s\n", fname);
- fprintf(fp, "%%%%Creator: %s %s\n", XBB_PROGRAM, XBB_VERSION);
- fprintf(fp, "%%%%BoundingBox: %d %d %d %d\n", bbllx, bblly, bburx, bbury);
- do_time(fp);
- RELEASE(outname);
- MFCLOSE(fp);
-}
-
static int rect_equal (pdf_obj *rect1, pdf_obj *rect2)
{
int i;
@@ -241,7 +216,8 @@ static int rect_equal (pdf_obj *rect1, pdf_obj *rect2)
return 1;
}
-static int pdf_get_info (FILE *image_file, char *filename, int *llx, int *lly, int *urx, int *ury)
+static int pdf_get_info (FILE *image_file, char *filename, int *version,
+ double *llx, double *lly, double *urx, double *ury)
{
pdf_obj *page_tree;
pdf_obj *bbox;
@@ -342,10 +318,12 @@ static int pdf_get_info (FILE *image_file, char *filename, int *llx, int *lly, i
return -1;
}
- *llx = (int)pdf_number_value(pdf_get_array(bbox, 0));
- *lly = (int)pdf_number_value(pdf_get_array(bbox, 1));
- *urx = (int)pdf_number_value(pdf_get_array(bbox, 2));
- *ury = (int)pdf_number_value(pdf_get_array(bbox, 3));
+ *version = pdf_file_get_version(pf);
+
+ *llx = pdf_number_value(pdf_get_array(bbox, 0));
+ *lly = pdf_number_value(pdf_get_array(bbox, 1));
+ *urx = pdf_number_value(pdf_get_array(bbox, 2));
+ *ury = pdf_number_value(pdf_get_array(bbox, 3));
pdf_release_obj(bbox);
@@ -355,13 +333,14 @@ static int pdf_get_info (FILE *image_file, char *filename, int *llx, int *lly, i
static void do_pdf (FILE *fp, char *filename)
{
- int llx, lly, urx, ury;
+ double llx, lly, urx, ury;
+ int version;
- if (pdf_get_info(fp, filename, &llx, &lly, &urx, &ury) < 0) {
+ if (pdf_get_info(fp, filename, &version, &llx, &lly, &urx, &ury) < 0) {
fprintf (stderr, "%s does not look like a PDF file...\n", filename);
return;
}
- write_xbb_old(filename, llx, lly, urx, ury);
+ write_xbb(filename, llx, lly, urx, ury, version, 1);
return;
}
#else
@@ -405,7 +384,6 @@ int extractbb (int argc, char *argv[])
while (argc > 0 && *argv[0] == '-') {
switch (*(argv[0]+1)) {
case 'b':
- xbb_file_mode = FOPEN_WBIN_MODE;
argc -= 1; argv += 1;
break;
case 'm':