diff options
Diffstat (limited to 'Build/source/texk/lcdf-typetools/lcdf-typetools-src/libefont/t1rw.cc')
-rw-r--r-- | Build/source/texk/lcdf-typetools/lcdf-typetools-src/libefont/t1rw.cc | 613 |
1 files changed, 0 insertions, 613 deletions
diff --git a/Build/source/texk/lcdf-typetools/lcdf-typetools-src/libefont/t1rw.cc b/Build/source/texk/lcdf-typetools/lcdf-typetools-src/libefont/t1rw.cc deleted file mode 100644 index 35e9f57a72c..00000000000 --- a/Build/source/texk/lcdf-typetools/lcdf-typetools-src/libefont/t1rw.cc +++ /dev/null @@ -1,613 +0,0 @@ -// -*- related-file-name: "../include/efont/t1rw.hh" -*- - -/* t1rw.{cc,hh} -- Type 1 font reading and writing - * - * Copyright (c) 1998-2019 Eddie Kohler - * - * 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. - */ - -#ifdef HAVE_CONFIG_H -# include <config.h> -#endif -#include <efont/t1rw.hh> -#include <efont/t1cs.hh> -#include <lcdf/straccum.hh> -#include <stdlib.h> -#include <ctype.h> -#include <string.h> -namespace Efont { - -unsigned char Type1Reader::xvalue_store[257]; -unsigned char *Type1Reader::xvalue = &Type1Reader::xvalue_store[1]; - -void -Type1Reader::static_initialize() -{ - if (xvalue['A']) - return; - // rely on static data being initialized to 0 - xvalue['0'] = 0; xvalue['1'] = 1; xvalue['2'] = 2; xvalue['3'] = 3; - xvalue['4'] = 4; xvalue['5'] = 5; xvalue['6'] = 6; xvalue['7'] = 7; - xvalue['8'] = 8; xvalue['9'] = 9; - xvalue['A'] = 10; xvalue['B'] = 11; xvalue['C'] = 12; xvalue['D'] = 13; - xvalue['E'] = 14; xvalue['F'] = 15; - xvalue['a'] = 10; xvalue['b'] = 11; xvalue['c'] = 12; xvalue['d'] = 13; - xvalue['e'] = 14; xvalue['f'] = 15; -} - - -Type1Reader::Type1Reader() - : _data(new unsigned char[DATA_SIZE]), _len(0), _pos(0), - _ungot(-1), _eexec(false) -{ - static_initialize(); -} - -Type1Reader::~Type1Reader() -{ - delete[] _data; -} - - -void -Type1Reader::set_charstring_definer(PermString x) -{ - _charstring_definer = x; -} - -void -Type1Reader::switch_eexec(bool on, unsigned char *data, int len) -{ - if (on) { - if (_pos < len + 3) { - unsigned char *new_data = new unsigned char[len + 3 + DATA_SIZE]; - assert(_len <= DATA_SIZE); - memcpy(new_data + len + 3, _data + _pos, _len - _pos); - _len = len + 3 + _len - _pos; - _pos = len + 3; - delete[] _data; - _data = new_data; - } - int original_pos = _pos; - // don't forget _ungot!! - if (_ungot >= 0) - _data[--_pos] = _ungot, _ungot = -1; - if (_crlf == 0 || _crlf == 2) - _data[--_pos] = '\n'; - if (_crlf == 1 || _crlf == 2) - _data[--_pos] = '\r'; - memcpy(_data + _pos - len, data, len); - _pos -= len; - start_eexec(original_pos - _pos); - } - _eexec = on; -} - - -int -Type1Reader::more_data() -{ - _pos = 0; - _len = more_data(_data, DATA_SIZE); - if (_len < 0) - return -1; - else - return _data[_pos++]; -} - - -inline int -Type1Reader::get_base() -{ - if (_pos >= _len) - return more_data(); - else - return _data[_pos++]; -} - - -inline int -Type1Reader::eexec(int c) -{ - unsigned char answer = (unsigned char)(c ^ (_r >> 8)); - _r = (((unsigned char)c + _r) * (uint32_t) t1C1 + t1C2) & 0xFFFF; - return answer; -} - - -int -Type1Reader::ascii_eexec_get() -{ - int d1 = get_base(); - while (isspace(d1)) - d1 = get_base(); - - int d2 = get_base(); - while (isspace(d2)) - d2 = get_base(); - if (d2 < 0) - return -1; - - return eexec((xvalue[d1] << 4) | (xvalue[d2])); -} - - -inline int -Type1Reader::get() -{ - if (!_eexec) - return get_base(); - - else if (_binary_eexec) { - int c = get_base(); - return c < 0 ? c : eexec(c); - - } else - return ascii_eexec_get(); -} - - -void -Type1Reader::start_eexec(int initial_ascii) -{ - /* God damn this _ungot thing!! It makes sense not to check it on every - char fetch, since it can only be set at the end of next_line; therefore, - only the first get() into a user-visible function might need to check - _ungot. The problem is I forgot start_eexec() was such a function! */ - int c = _ungot < 0 ? get_base() : _ungot; - initial_ascii--; - _ungot = -1; - - /* Strictly speaking, I should look for whitespace even in binary sections - of PFB fonts; but it turns out some PFBs would be unreadable with that - pedantic rule. */ - while (isspace(c) && (initial_ascii >= 0 || !preserve_whitespace())) - c = get_base(), initial_ascii--; - - /* Differentiate between ASCII eexec and binary eexec. */ - int rand_bytes[4]; - _binary_eexec = false; - for (int i = 0; i < 4; i++) { - if (i) - c = get_base(); - rand_bytes[i] = c; - if (!isxdigit(c)) - _binary_eexec = true; - } - - _r = t1R_ee; - if (_binary_eexec) - for (int i = 0; i < 4; i++) - eexec(rand_bytes[i]); - else { - for (int i = 0; i < 2; i++) { - c = xvalue[rand_bytes[i*2]] * 16 + xvalue[rand_bytes[i*2+1]]; - eexec(c); - } - ascii_eexec_get(); - ascii_eexec_get(); - } -} - - -bool -Type1Reader::test_charstring(StringAccum &str) -{ - /* PERFORMANCE NOTE: This function is definitely a bottleneck. Making it - more efficient cut time by about 40%. */ - - if (!_charstring_definer) - return false; - if (_charstring_len >= 0) - return str.length() <= _charstring_start + _charstring_len; - - str.append('\0'); // protect against running off end of string - char *s = str.data(); - char *start; - while (*s == ' ') - s++; - - if (s[0] == '/') - s++; - else if (s[0] == 'd' && s[1] == 'u' && s[2] == 'p' && isspace((unsigned char) s[3])) { - s += 4; - // 17.Jan.2000 -- some fonts have extra space here. - while (isspace((unsigned char) *s)) - s++; - } else - goto not_charstring; - - // Force one literal space rather than isspace(). - // Why? Consistency: we force 1 literal space around _charstring_definer. - while (*s != ' ' && *s) - s++; - if (*s++ != ' ' || !isdigit((unsigned char) *s)) - goto not_charstring; - start = s; - s++; - while (*s != ' ' && *s) - s++; - if (strncmp(s, _charstring_definer.c_str(), _charstring_definer.length()) != 0) - goto not_charstring; - - _charstring_len = strtol(start, 0, 10); - _charstring_start = (s - str.data()) + _charstring_definer.length(); - str.pop_back(); - return str.length() <= _charstring_start + _charstring_len; - - not_charstring: - str.pop_back(); - return false; -} - - -/* PERFORMANCE NOTE: All kinds of speedup tricks tried with eexec -- buffering - (doing eexec processing at more_data time), etc., and all this stuff -- and - found to have essentially zero effect for PFB fonts. Now, it might be - effective for PFAs; but who cares? I hate PFAs. */ - -bool -Type1Reader::next_line(StringAccum &s) -{ - if (_len < 0) - return false; - - // Can't be a charstring if incoming accumulator has nonzero length. - _charstring_start = 0; - _charstring_len = (s.length() > 0 ? 0 : -1); - - int first_char = _ungot < 0 ? get() : _ungot; - _ungot = -1; - - for (int c = first_char; c >= 0; c = get()) - switch (c) { - - case '\n': - if (test_charstring(s)) - goto normal; - else { - _crlf = 0; - goto done; - } - - case '\r': - // check for \r\n (counts as only one line ending) - if (test_charstring(s)) - goto normal; - c = get(); - if (c != '\n' || preserve_whitespace()) - _ungot = c, _crlf = 1; - else - _crlf = 2; - goto done; - - normal: - default: - s.append((char)c); - break; - - } - - done: - return true; -} - - -int -Type1Reader::get_data(unsigned char *data, int len) -{ - if (_len < 0) - return -1; - if (len <= 0) - return 0; - - int pos = 0; - if (_ungot >= 0) { - *data++ = _ungot; - pos++; - _ungot = -1; - } - - for (; pos < len; pos++) { - int c = get(); - if (c < 0) - break; - *data++ = c; - } - - return pos; -} - - -/***** - * Type1PFAReader - **/ - -Type1PFAReader::Type1PFAReader(FILE *f) - : _f(f) -{ -} - -int -Type1PFAReader::more_data(unsigned char *data, int len) -{ - size_t size = fread(data, 1, len, _f); - return size ? (int)size : -1; -} - - -/***** - * Type1PFBReader - **/ - -Type1PFBReader::Type1PFBReader(FILE *f) - : _f(f), _binary(false), _left(0) -{ -} - -int -Type1PFBReader::more_data(unsigned char *data, int len) -{ - while (_left == 0) { - int c = getc(_f); - if (c != 128) - return -1; - - c = getc(_f); - if (c == 3 || c < 1 || c > 3) - return -1; - _binary = (c == 2); - - _left = getc(_f); - _left |= getc(_f) << 8; - _left |= getc(_f) << 16; - _left |= getc(_f) << 24; - } - - if (_left < 0) - return -1; - - if (len > _left) - len = _left; - _left -= len; - - return fread(data, 1, len, _f); -} - -bool -Type1PFBReader::preserve_whitespace() const -{ - return _binary; -} - - -/***** - * Type1SubsetReader - **/ - -Type1SubsetReader::Type1SubsetReader(Type1Reader *r, int left) - : _reader(r), _left(left) -{ -} - -int -Type1SubsetReader::more_data(unsigned char *data, int len) -{ - if (_left <= 0) - return -1; - if (len > _left) - len = _left; - int how_much = _reader->get_data(data, len); - if (how_much > 0) - _left -= how_much; - return how_much; -} - -bool -Type1SubsetReader::preserve_whitespace() const -{ - return _reader->preserve_whitespace(); -} - - -/***** - * Writer - **/ - -Type1Writer::Type1Writer() - : _buf(new unsigned char[BufSize]), _pos(0), - _eexec(false), _eexec_start(-1), _eexec_end(-1), _lenIV(4) -{ -} - - -Type1Writer::~Type1Writer() -{ - assert(!_pos); - delete[] _buf; -} - - -inline unsigned char -Type1Writer::eexec(int p) -{ - unsigned char c = ((unsigned char)p ^ (_r >> 8)) & 0xFF; - _r = ((c + _r) * (uint32_t) t1C1 + t1C2) & 0xFFFF; - return c; -} - - -void -Type1Writer::flush() -{ - local_flush(); -} - - -/* PERFORMANCE NOTE: Doing eexec processing during flush -- which streamlines - code for the print() methods -- seems to save some time (4-5%). It also - makes write performance more consistent. But I have mixed feelings. */ - -void -Type1Writer::local_flush() -{ - if (_eexec_start >= 0 && _eexec_end < 0) - _eexec_end = _pos; - for (int p = _eexec_start; p < _eexec_end; p++) - _buf[p] = eexec(_buf[p]); - print0(_buf, _pos); - _pos = 0; - _eexec_start = _eexec ? 0 : -1; - _eexec_end = -1; -} - - -void -Type1Writer::print(const char *s, int n) -{ - while (n > 0) { - if (_pos >= BufSize) - local_flush(); - int copy = BufSize - _pos; - if (copy > n) copy = n; - memcpy(_buf + _pos, s, copy); - _pos += copy; - s += copy; - n -= copy; - } -} - - -Type1Writer & -Type1Writer::operator<<(int x) -{ - char str[128]; - sprintf(str, "%d", x); - print(str, strlen(str)); - return *this; -} - - -Type1Writer & -Type1Writer::operator<<(double x) -{ - char str[256]; - sprintf(str, "%g", x); - print(str, strlen(str)); - return *this; -} - - -void -Type1Writer::switch_eexec(bool on) -{ - _eexec = on; - if (_eexec) { - _eexec_start = _pos; - _r = t1R_ee; - print("SUCK", 4); - } else - _eexec_end = _pos; -} - - -/***** - * Type1PFAWriter - **/ - -Type1PFAWriter::Type1PFAWriter(FILE *f) - : _f(f), _hex_line(0) -{ -} - -Type1PFAWriter::~Type1PFAWriter() -{ - flush(); -} - - -void -Type1PFAWriter::switch_eexec(bool on) -{ - flush(); - _hex_line = 0; - Type1Writer::switch_eexec(on); -} - -void -Type1PFAWriter::print0(const unsigned char *c, int l) -{ - if (eexecing()) { - const char *hex = "0123456789ABCDEF"; - for (; l; c++, l--) { - putc(hex[*c / 16], _f); - putc(hex[*c % 16], _f); - if (++_hex_line == 39) { - putc('\n', _f); - _hex_line = 0; - } - } - } else { - ssize_t result = fwrite(c, 1, l, _f); - (void) result; - } -} - - -/***** - * Type1PFBWriter - **/ - -Type1PFBWriter::Type1PFBWriter(FILE *f) - : _f(f), _binary(false) -{ -} - -Type1PFBWriter::~Type1PFBWriter() -{ - flush(); - fputc(128, _f); - fputc(3, _f); -} - -void -Type1PFBWriter::flush() -{ - Type1Writer::flush(); - if (_save.length()) { - fputc(128, _f); - fputc(_binary ? 2 : 1, _f); - long l = _save.length(); - fputc(l & 0xFF, _f); - fputc((l >> 8) & 0xFF, _f); - fputc((l >> 16) & 0xFF, _f); - fputc((l >> 24) & 0xFF, _f); - ssize_t result = fwrite(_save.data(), 1, _save.length(), _f); - (void) result; - _save.clear(); - } -} - -void -Type1PFBWriter::switch_eexec(bool on) -{ - flush(); - Type1Writer::switch_eexec(on); - _binary = on; -} - -void -Type1PFBWriter::print0(const unsigned char *c, int l) -{ - char *m = _save.extend(l); - memcpy(m, c, l); -} - -} |