File indexing completed on 2024-05-12 04:34:00
0001 // -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; c-brace-offset: 0; -*- 0002 /* 0003 * SPDX-FileCopyrightText: 1994 Paul Vojta. All rights reserved. 0004 * 0005 * SPDX-License-Identifier: BSD-2-Clause 0006 */ 0007 0008 #include <config.h> 0009 0010 #include "debug_dvi.h" 0011 #include "dvi.h" 0012 #include "dviRenderer.h" 0013 #include "xdvi.h" 0014 0015 #include <KLocalizedString> 0016 0017 #include <cstdlib> 0018 #include <cstring> 0019 0020 extern void oops(const QString &message); 0021 0022 /*** 0023 *** VF font reading routines. 0024 *** Public routine is read_index---because virtual characters are presumed 0025 *** to be short, we read the whole virtual font in at once, instead of 0026 *** faulting in characters as needed. 0027 ***/ 0028 0029 #define LONG_CHAR 242 0030 0031 /* 0032 * These are parameters which determine whether macros are combined for 0033 * storage allocation purposes. Small macros ( <= VF_PARM_1 bytes) are 0034 * combined into chunks of size VF_PARM_2. 0035 */ 0036 0037 #ifndef VF_PARM_1 0038 #define VF_PARM_1 20 0039 #endif 0040 #ifndef VF_PARM_2 0041 #define VF_PARM_2 256 0042 #endif 0043 0044 /* 0045 * The main routine 0046 */ 0047 0048 void TeXFontDefinition::read_VF_index() 0049 { 0050 #ifdef DEBUG_FONTS 0051 qCDebug(OkularDviDebug) << "font::read_VF_index()"; 0052 #endif 0053 FILE *VF_file = file; 0054 unsigned char cmnd; 0055 // available space for macros 0056 unsigned char *avail, *availend; 0057 0058 flags |= FONT_VIRTUAL; 0059 set_char_p = &dviRenderer::set_vf_char; 0060 #ifdef DEBUG_FONTS 0061 qCDebug(OkularDviDebug) << "TeXFontDefinition::read_VF_index: reading VF pixel file " << filename; 0062 #endif 0063 // Read preamble. 0064 fseek(VF_file, (long)one(VF_file), 1); /* skip comment */ 0065 quint32 const file_checksum = four(VF_file); 0066 0067 if (file_checksum && checksum && file_checksum != checksum) { 0068 qCCritical(OkularDviDebug) << "Checksum mismatch dvi = " << checksum << "u, vf = " << file_checksum << "u) in font file" << filename; 0069 } 0070 (void)four(VF_file); /* skip design size */ 0071 0072 // Read the fonts. 0073 first_font = nullptr; 0074 while ((cmnd = one(VF_file)) >= FNTDEF1 && cmnd <= FNTDEF4) { 0075 int TeXnumber = num(VF_file, (int)cmnd - FNTDEF1 + 1); 0076 quint32 checksum = four(VF_file); 0077 quint32 scale = four(VF_file); 0078 quint32 design = four(VF_file); 0079 Q_UNUSED(design); 0080 quint16 len = one(VF_file) + one(VF_file); /* sequence point in the middle */ 0081 char *fontname = new char[len + 1]; 0082 fread(fontname, sizeof(char), len, VF_file); 0083 fontname[len] = '\0'; 0084 0085 #ifdef DEBUG_FONTS 0086 qCDebug(OkularDviDebug) << "Virtual font defines subfont \"" << fontname << "\" scale=" << scale << " design=" << design; 0087 #endif 0088 0089 // According to Knuth's documentation found in the web source code 0090 // of the "vftovp" program (which seems to be the standard 0091 // definition of virtual fonts), the "scale" is a fixed point 0092 // number which describes extra enlargement that the virtual font 0093 // imposes. One obtains the enlargement by dividing 2^20. 0094 double enlargement_factor = double(scale) / (1 << 20) * enlargement; 0095 0096 // TeXFontDefinition *newfontp = font_pool->appendx(fontname, checksum, (quint32)(scaled_size_in_DVI_units*enlargement_factor), enlargement_factor); 0097 TeXFontDefinition *newfontp = font_pool->appendx(QString::fromLocal8Bit(fontname), checksum, (quint32)((double(scale) / (1 << 20)) * scaled_size_in_DVI_units), enlargement_factor); 0098 0099 // Insert font in dictionary and make sure the dictionary is big 0100 // enough. 0101 if (vf_table.capacity() - 2 <= vf_table.count()) { 0102 // Not quite optimal. The size of the dictionary should be a 0103 // prime. I don't care. 0104 vf_table.reserve(vf_table.capacity() * 2); 0105 } 0106 vf_table.insert(TeXnumber, newfontp); 0107 0108 if (first_font == nullptr) { 0109 first_font = newfontp; 0110 } 0111 } 0112 0113 // Prepare macro array. 0114 macrotable = new macro[max_num_of_chars_in_font]; 0115 if (macrotable == nullptr) { 0116 qCCritical(OkularDviDebug) << "Could not allocate memory for a macro table."; 0117 exit(0); 0118 } 0119 0120 // Read macros. 0121 avail = availend = nullptr; 0122 for (; cmnd <= LONG_CHAR; cmnd = one(VF_file)) { 0123 macro *m; 0124 int len; 0125 unsigned long cc; 0126 long width; 0127 0128 if (cmnd == LONG_CHAR) { /* long form packet */ 0129 len = four(VF_file); 0130 cc = four(VF_file); 0131 width = four(VF_file); 0132 if (cc >= 256) { 0133 qCCritical(OkularDviDebug) << "Virtual character" << cc << "in font" << fontname << "ignored."; 0134 fseek(VF_file, (long)len, 1); 0135 continue; 0136 } 0137 } else { /* short form packet */ 0138 len = cmnd; 0139 cc = one(VF_file); 0140 width = num(VF_file, 3); 0141 } 0142 m = ¯otable[cc]; 0143 0144 m->dvi_advance_in_units_of_design_size_by_2e20 = width; 0145 if (len > 0) { 0146 if (len <= availend - avail) { 0147 m->pos = avail; 0148 avail += len; 0149 } else { 0150 m->free_me = true; 0151 if (len <= VF_PARM_1) { 0152 m->pos = avail = new unsigned char[VF_PARM_2]; 0153 availend = avail + VF_PARM_2; 0154 avail += len; 0155 } else { 0156 m->pos = new unsigned char[len]; 0157 } 0158 } 0159 fread((char *)m->pos, 1, len, VF_file); 0160 m->end = m->pos + len; 0161 } 0162 } 0163 if (cmnd != POST) { 0164 oops(i18n("Wrong command byte found in VF macro list: %1", cmnd)); 0165 } 0166 0167 fclose(VF_file); 0168 file = nullptr; 0169 }