File indexing completed on 2024-05-12 16:06:40
0001 // -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; c-brace-offset: 0; -*- 0002 #include <config.h> 0003 0004 #include "TeXFontDefinition.h" 0005 #include "debug_dvi.h" 0006 #include "dviRenderer.h" 0007 #ifdef HAVE_FREETYPE 0008 #include "TeXFont_PFB.h" 0009 #endif 0010 #include "TeXFont_PK.h" 0011 #include "TeXFont_TFM.h" 0012 #include "debug_dvi.h" 0013 #include "xdvi.h" 0014 0015 #include <KLocalizedString> 0016 0017 #include <QFile> 0018 #include <QLoggingCategory> 0019 0020 extern const int MFResolutions[]; 0021 0022 #define PK_PRE 247 0023 #define PK_ID 89 0024 #define PK_MAGIC (PK_PRE << 8) + PK_ID 0025 #define GF_PRE 247 0026 #define GF_ID 131 0027 #define GF_MAGIC (GF_PRE << 8) + GF_ID 0028 #define VF_PRE 247 0029 #define VF_ID_BYTE 202 0030 #define VF_MAGIC (VF_PRE << 8) + VF_ID_BYTE 0031 0032 // #define DEBUG_FONT 0033 0034 TeXFontDefinition::TeXFontDefinition(const QString &nfontname, double _displayResolution_in_dpi, quint32 chk, qint32 _scaled_size_in_DVI_units, class fontPool *pool, double _enlargement) 0035 { 0036 #ifdef DEBUG_FONT 0037 qCDebug(OkularDviDebug) << "TeXFontDefinition::TeXFontDefinition(...); fontname=" << nfontname << ", enlargement=" << _enlargement; 0038 #endif 0039 0040 enlargement = _enlargement; 0041 font_pool = pool; 0042 fontname = nfontname; 0043 font = nullptr; 0044 displayResolution_in_dpi = _displayResolution_in_dpi; 0045 checksum = chk; 0046 flags = TeXFontDefinition::FONT_IN_USE; 0047 file = nullptr; 0048 filename.clear(); 0049 scaled_size_in_DVI_units = _scaled_size_in_DVI_units; 0050 0051 macrotable = nullptr; 0052 0053 // By default, this font contains only empty characters. After the 0054 // font has been loaded, this function pointer will be replaced by 0055 // another one. 0056 set_char_p = &dviRenderer::set_empty_char; 0057 } 0058 0059 TeXFontDefinition::~TeXFontDefinition() 0060 { 0061 #ifdef DEBUG_FONT 0062 qCDebug(OkularDviDebug) << "discarding font " << fontname << " at " << (int)(enlargement * MFResolutions[font_pool->getMetafontMode()] + 0.5) << " dpi"; 0063 #endif 0064 0065 if (font != nullptr) { 0066 delete font; 0067 font = nullptr; 0068 } 0069 if (macrotable != nullptr) { 0070 delete[] macrotable; 0071 macrotable = nullptr; 0072 } 0073 0074 if (flags & FONT_LOADED) { 0075 if (file != nullptr) { 0076 fclose(file); 0077 file = nullptr; 0078 } 0079 if (flags & FONT_VIRTUAL) { 0080 vf_table.clear(); 0081 } 0082 } 0083 } 0084 0085 void TeXFontDefinition::fontNameReceiver(const QString &fname) 0086 { 0087 #ifdef DEBUG_FONT 0088 qCDebug(OkularDviDebug) << "void TeXFontDefinition::fontNameReceiver( " << fname << " )"; 0089 #endif 0090 0091 flags |= TeXFontDefinition::FONT_LOADED; 0092 filename = fname; 0093 #ifdef HAVE_FREETYPE 0094 fullFontName.clear(); 0095 fullEncodingName.clear(); 0096 #endif 0097 0098 file = fopen(QFile::encodeName(filename).constData(), "r"); 0099 // Check if the file could be opened. If not, try to find the file 0100 // in the DVI file's directory. If that works, modify the filename 0101 // accordingly and go on. 0102 if (file == nullptr) { 0103 QString filename_test(font_pool->getExtraSearchPath() + QLatin1Char('/') + filename); 0104 file = fopen(QFile::encodeName(filename_test).constData(), "r"); 0105 if (file == nullptr) { 0106 qCCritical(OkularDviDebug) << i18n("Cannot find font %1, file %2.", fontname, filename); 0107 return; 0108 } else { 0109 filename = filename_test; 0110 } 0111 } 0112 0113 set_char_p = &dviRenderer::set_char; 0114 int magic = two(file); 0115 0116 if (fname.endsWith(QLatin1String("pk"))) { 0117 if (magic == PK_MAGIC) { 0118 fclose(file); 0119 file = nullptr; 0120 font = new TeXFont_PK(this); 0121 set_char_p = &dviRenderer::set_char; 0122 if ((checksum != 0) && (checksum != font->checksum)) { 0123 qCWarning(OkularDviDebug) << i18n("Checksum mismatch for font file %1", filename); 0124 } 0125 fontType = TEX_PK; 0126 return; 0127 } 0128 } 0129 0130 if (fname.endsWith(QLatin1String(".vf"))) { 0131 if (magic == VF_MAGIC) { 0132 read_VF_index(); 0133 set_char_p = &dviRenderer::set_vf_char; 0134 fontType = TEX_VIRTUAL; 0135 return; 0136 } 0137 } 0138 0139 if (fname.endsWith(QLatin1String(".tfm"))) { 0140 fclose(file); 0141 file = nullptr; 0142 font = new TeXFont_TFM(this); 0143 set_char_p = &dviRenderer::set_char; 0144 fontType = TEX_FONTMETRIC; 0145 return; 0146 } 0147 0148 // None of these known types? Then it should be one of the font 0149 // formats that are handled by the FreeType library 0150 fclose(file); 0151 file = nullptr; 0152 #ifdef HAVE_FREETYPE 0153 // Find the encoding for that font 0154 const QString &enc = font_pool->fontsByTeXName.findEncoding(fontname); 0155 0156 if (enc.isEmpty() == false) { 0157 #ifdef DEBUG_FONT 0158 qCDebug(OkularDviDebug) << "Font " << fontname << " uses encoding " << enc; 0159 #endif 0160 font = new TeXFont_PFB(this, font_pool->encodingPool.findByName(enc), font_pool->fontsByTeXName.findSlant(fontname)); 0161 } else { 0162 #ifdef DEBUG_FONT 0163 qCDebug(OkularDviDebug) << "Font " << fontname << " does not have an encoding."; 0164 #endif 0165 font = new TeXFont_PFB(this); 0166 } 0167 0168 set_char_p = &dviRenderer::set_char; 0169 fontType = FREETYPE; 0170 return; 0171 #else 0172 // If we don't have the FreeType library, we should never have 0173 // reached this point. Complain, and leave this font blank 0174 qCCritical(OkularDviDebug) << i18n("Cannot recognize format for font file %1", filename); 0175 #endif 0176 } 0177 0178 void TeXFontDefinition::reset() 0179 { 0180 if (font != nullptr) { 0181 delete font; 0182 font = nullptr; 0183 } 0184 0185 if (macrotable != nullptr) { 0186 delete[] macrotable; 0187 macrotable = nullptr; 0188 } 0189 0190 if (flags & FONT_LOADED) { 0191 if (file != nullptr) { 0192 fclose(file); 0193 file = nullptr; 0194 } 0195 if (flags & FONT_VIRTUAL) { 0196 vf_table.clear(); 0197 } 0198 } 0199 0200 filename.clear(); 0201 flags = TeXFontDefinition::FONT_IN_USE; 0202 set_char_p = &dviRenderer::set_empty_char; 0203 } 0204 0205 void TeXFontDefinition::setDisplayResolution(double _displayResolution_in_dpi) 0206 { 0207 displayResolution_in_dpi = _displayResolution_in_dpi; 0208 if (font != nullptr) { 0209 font->setDisplayResolution(); 0210 } 0211 } 0212 0213 /** mark_as_used marks the font, and all the fonts it refers to, as 0214 used, i.e. their FONT_IN_USE-flag is set. */ 0215 0216 void TeXFontDefinition::mark_as_used() 0217 { 0218 #ifdef DEBUG_FONT 0219 qCDebug(OkularDviDebug) << "TeXFontDefinition::mark_as_used()"; 0220 #endif 0221 0222 if (flags & TeXFontDefinition::FONT_IN_USE) { 0223 return; 0224 } 0225 0226 flags |= TeXFontDefinition::FONT_IN_USE; 0227 0228 // For virtual fonts, also go through the list of referred fonts 0229 if (flags & TeXFontDefinition::FONT_VIRTUAL) { 0230 QHashIterator<int, TeXFontDefinition *> it(vf_table); 0231 while (it.hasNext()) { 0232 it.next(); 0233 it.value()->flags |= TeXFontDefinition::FONT_IN_USE; 0234 } 0235 } 0236 } 0237 0238 macro::macro() 0239 { 0240 pos = nullptr; /* address of first byte of macro */ 0241 end = nullptr; /* address of last+1 byte */ 0242 dvi_advance_in_units_of_design_size_by_2e20 = 0; /* DVI units to move reference point */ 0243 free_me = false; 0244 } 0245 0246 macro::~macro() 0247 { 0248 if ((pos != nullptr) && (free_me == true)) { 0249 delete[] pos; 0250 } 0251 }