⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 texfont_pk.cpp

📁 okular
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; c-brace-offset: 0; -*-/* * Copyright (c) 1994 Paul Vojta.  All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * NOTE: *        xdvi is based on prior work as noted in the modification history, below. *//* * DVI previewer for X. * * Eric Cooper, CMU, September 1985. * * Code derived from dvi-imagen.c. * * Modification history: * 1/1986        Modified for X.10        --Bob Scheifler, MIT LCS. * 7/1988        Modified for X.11        --Mark Eichin, MIT * 12/1988        Added 'R' option, toolkit, magnifying glass *                                        --Paul Vojta, UC Berkeley. * 2/1989        Added tpic support       --Jeffrey Lee, U of Toronto * 4/1989        Modified for System V    --Donald Richardson, Clarkson Univ. * 3/1990        Added VMS support        --Scott Allendorf, U of Iowa * 7/1990        Added reflection mode    --Michael Pak, Hebrew U of Jerusalem * 1/1992        Added greyscale code     --Till Brychcy, Techn. Univ. Muenchen *                                          and Lee Hetherington, MIT * 4/1994        Added DPS support, bounding box *                                        --Ricardo Telichevesky *                                          and Luis Miguel Silveira, MIT RLE. */#include <config.h>#include "TeXFont_PK.h"#include "fontpool.h"#include "kvs_debug.h"#include "xdvi.h"#include <klocale.h>#include <QFile>#include <QImage>#include <cmath>//#define DEBUG_PK#define        PK_PRE          247#define        PK_ID           89#define        PK_MAGIC        (PK_PRE << 8) + PK_IDextern void oops(const QString& message);TeXFont_PK::TeXFont_PK(TeXFontDefinition *parent)  : TeXFont(parent){#ifdef DEBUG_PK  kDebug(kvs::dvi) << "TeXFont_PK::TeXFont_PK( parent=" << parent << ")" << endl;#endif  for(unsigned int i=0; i<TeXFontDefinition::max_num_of_chars_in_font; i++)    characterBitmaps[i] = 0;  file = fopen(QFile::encodeName(parent->filename), "r");  if (file == 0)    kError(kvs::dvi) << i18n("Cannot open font file %1.", parent->filename) << endl;#ifdef DEBUG_PK  else    kDebug(kvs::dvi) << "TeXFont_PK::TeXFont_PK(): file opened successfully" << endl;#endif  read_PK_index();#ifdef DEBUG_PK  kDebug(kvs::dvi) << "TeXFont_PK::TeXFont_PK() ended" << endl;#endif}TeXFont_PK::~TeXFont_PK(){  //@@@ Release bitmaps  if (file != 0) {    fclose(file);    file = 0;  }}glyph* TeXFont_PK::getGlyph(quint16 ch, bool generateCharacterPixmap, const QColor& color){#ifdef DEBUG_PK  kDebug(kvs::dvi) << "TeXFont_PK::getGlyph( ch=" << ch << ", generateCharacterPixmap=" << generateCharacterPixmap << " )" << endl;#endif  // Paranoia checks  if (ch >= TeXFontDefinition::max_num_of_chars_in_font) {    kError(kvs::dvi) << "TeXFont_PK::getGlyph(): Argument is too big." << endl;    return glyphtable;  }  // This is the address of the glyph that will be returned.  struct glyph *g = glyphtable+ch;  // Check if the glyph is loaded. If not, load it now.  if (characterBitmaps[ch] == 0) {    // If the character is not defined in the PK file, mark the    // character as missing, and print an error message    if (g->addr == 0) {      kError(kvs::dvi) << i18n("TexFont_PK::operator[]: Character %1 not defined in font %2", ch, parent->filename) << endl;      g->addr = -1;      return g;    }    // If the character has already been marked as missing, just    // return a pointer to the glyph (which will then be empty)    if (g->addr == -1)      return g;    // Otherwise, try to load the character    fseek(file, g->addr, 0);    read_PK_char(ch);    // Check if the character could be loaded. If not, mark the    // character as 'missing', and return a pointer.    if (characterBitmaps[ch]->bits == 0) {      g->addr = -1;      return g;    }  }  // At this point, g points to a properly loaded character. Generate  // a smoothly scaled QPixmap if the user asks for it.  if ((generateCharacterPixmap == true) &&      ((g->shrunkenCharacter.isNull()) || (color != g->color)) &&      (characterBitmaps[ch]->w != 0)) {    g->color = color;    double shrinkFactor = 1200 / parent->displayResolution_in_dpi;    // All is fine? Then we rescale the bitmap in order to produce the    // required pixmap.  Rescaling a character, however, is an art    // that requires some explanation...    //    // If we would just divide the size of the character and the    // coordinates by the shrink factor, then the result would look    // quite ugly: due to the ineviatable rounding errors in the    // integer arithmetic, the characters would be displaced by up to    // a pixel. That doesn't sound much, but on low-resolution    // devices, such as a notebook screen, the effect would be a    // "dancing line" of characters, which looks really bad.    // Calculate the coordinates of the hot point in the shrunken    // bitmap. For simplicity, let us consider the x-coordinate    // first. In principle, the hot point should have an x-coordinate    // of (g->x/shrinkFactor). That, however, will generally NOT be an    // integral number. The cure is to translate the source image    // somewhat, so that the x-coordinate of the hot point falls onto    // the round-up of this number, i.e.    g->x2 = (int)ceil(g->x/shrinkFactor);    // Translating and scaling then means that the pixel in the scaled    // image which covers the range [x,x+1) corresponds to the range    // [x*shrinkFactor+srcXTrans, (x+1)*shrinkFactor+srcXTrans), where    // srcXTrans is the following NEGATIVE number    double srcXTrans = shrinkFactor * (g->x/shrinkFactor - ceil(g->x/shrinkFactor));    // How big will the shrunken bitmap then become? If shrunk_width    // denotes that width of the scaled image, and    // characterBitmaps[ch]->w the width of the orininal image, we    // need to make sure that the following inequality holds:    //    // shrunk_width*shrinkFactor+srcXTrans >= characterBitmaps[ch]->w    //    // in other words,    int shrunk_width  = (int)ceil( (characterBitmaps[ch]->w - srcXTrans)/shrinkFactor );    // Now do the same for the y-coordinate    g->y2 = (int)ceil(g->y/shrinkFactor);    double srcYTrans = shrinkFactor * (g->y/shrinkFactor - ceil(g->y/shrinkFactor ));    int shrunk_height = (int)ceil( (characterBitmaps[ch]->h - srcYTrans)/shrinkFactor );    // Turn the image into 8 bit    QByteArray translated(characterBitmaps[ch]->w * characterBitmaps[ch]->h, '\0');    quint8 *data = (quint8 *)translated.data();    for(int x=0; x<characterBitmaps[ch]->w; x++)      for(int y=0; y<characterBitmaps[ch]->h; y++) {        quint8 bit = *(characterBitmaps[ch]->bits + characterBitmaps[ch]->bytes_wide*y + (x >> 3));        bit = bit >> (x & 7);        bit = bit & 1;        data[characterBitmaps[ch]->w*y + x] = bit;      }    // Now shrink the image. We shrink the X-direction first    QByteArray xshrunk(shrunk_width*characterBitmaps[ch]->h, '\0');    quint8 *xdata = (quint8 *)xshrunk.data();    // Do the shrinking. The pixel (x,y) that we want to calculate    // corresponds to the line segment from    //    // [shrinkFactor*x+srcXTrans, shrinkFactor*(x+1)+srcXTrans)    //    // The trouble is, these numbers are in general no integers.    for(int y=0; y<characterBitmaps[ch]->h; y++)      for(int x=0; x<shrunk_width; x++) {        quint32 value = 0;        double destStartX = shrinkFactor*x+srcXTrans;        double destEndX   = shrinkFactor*(x+1)+srcXTrans;        for(int srcX=(int)ceil(destStartX); srcX<floor(destEndX); srcX++)          if ((srcX >= 0) && (srcX < characterBitmaps[ch]->w))            value += data[characterBitmaps[ch]->w*y + srcX] * 255;        if (destStartX >= 0.0)          value += (quint32) (255.0*(ceil(destStartX)-destStartX) * data[characterBitmaps[ch]->w*y + (int)floor(destStartX)]);        if (floor(destEndX) < characterBitmaps[ch]->w)          value += (quint32) (255.0*(destEndX-floor(destEndX)) * data[characterBitmaps[ch]->w*y + (int)floor(destEndX)]);        xdata[shrunk_width*y + x] = (int)(value/shrinkFactor + 0.5);      }    // Now shrink the Y-direction    QByteArray xyshrunk(shrunk_width*shrunk_height, '\0');    quint8 *xydata = (quint8 *)xyshrunk.data();    for(int x=0; x<shrunk_width; x++)      for(int y=0; y<shrunk_height; y++) {        quint32 value = 0;        double destStartY = shrinkFactor*y+srcYTrans;        double destEndY   = shrinkFactor*(y+1)+srcYTrans;        for(int srcY=(int)ceil(destStartY); srcY<floor(destEndY); srcY++)          if ((srcY >= 0) && (srcY < characterBitmaps[ch]->h))            value += xdata[shrunk_width*srcY + x];        if (destStartY >= 0.0)          value += (quint32) ((ceil(destStartY)-destStartY) * xdata[shrunk_width*(int)floor(destStartY) + x]);        if (floor(destEndY) < characterBitmaps[ch]->h)          value += (quint32) ((destEndY-floor(destEndY)) * xdata[shrunk_width*(int)floor(destEndY) + x]);        xydata[shrunk_width*y + x] = (int)(value/shrinkFactor);      }    QImage im32(shrunk_width, shrunk_height, QImage::Format_ARGB32);    // Do QPixmaps fully support the alpha channel? If yes, we use    // that. Otherwise, use other routines as a fallback    if (parent->font_pool->QPixmapSupportsAlpha) {      // If the alpha channel is properly supported, we set the      // character glyph to a colored rectangle, and define the      // character outline only using the alpha channel. That ensures      // good quality rendering for overlapping characters.      im32.fill(qRgb(color.red(), color.green(), color.blue()));      for(quint16 y=0; y<shrunk_height; y++) {        quint8 *destScanLine = (quint8 *)im32.scanLine(y);        for(quint16 col=0; col<shrunk_width; col++)          destScanLine[4*col+3] = xydata[shrunk_width*y + col];      }    } else {      // If the alpha channel is not supported... QT seems to turn the      // alpha channel into a crude bitmap which is used to mask the      // resulting QPixmap. In this case, we define the character      // outline using the image data, and use the alpha channel only      // to store "maximally opaque" or "completely transparent"      // values. When characters are rendered, overlapping characters      // are no longer correctly drawn, but quality is still      // sufficient for most purposes. One notable exception is output      // from the gftodvi program, which will be partially unreadable.      quint16 rInv = 0xFF - color.red();      quint16 gInv = 0xFF - color.green();      quint16 bInv = 0xFF - color.blue();      quint8 *srcScanLine = xydata;      for(quint16 y=0; y<shrunk_height; y++) {        unsigned int *destScanLine = (unsigned int *)im32.scanLine(y);        for(quint16 col=0; col<shrunk_width; col++) {          quint16 data =  *srcScanLine;          // The value stored in "data" now has the following meaning:          // data = 0 -> white; data = 0xff -> use "color"          *destScanLine = qRgba(0xFF - (rInv*data + 0x7F) / 0xFF,                                0xFF - (gInv*data + 0x7F) / 0xFF,                                0xFF - (bInv*data + 0x7F) / 0xFF,                                (data > 0x03) ? 0xff : 0x00);          destScanLine++;          srcScanLine++;        }      }    }    g->shrunkenCharacter = im32;  }  return g;}#define        ADD(a, b)        ((quint32 *) (((char *) a) + b))#define        SUB(a, b)        ((quint32 *) (((char *) a) - b))// This table is used for changing the bit order in a byte. The// expression bitflp[byte] takes a byte in big endian and gives the// little endian equivalent of that.static const uchar bitflip[256] = {  0, 128, 64, 192, 32, 160, 96, 224, 16, 144, 80, 208, 48, 176, 112, 240,  8, 136, 72, 200, 40, 168, 104, 232, 24, 152, 88, 216, 56, 184, 120, 248,  4, 132, 68, 196, 36, 164, 100, 228, 20, 148, 84, 212, 52, 180, 116, 244,  12, 140, 76, 204, 44, 172, 108, 236, 28, 156, 92, 220, 60, 188, 124, 252,  2, 130, 66, 194, 34, 162, 98, 226, 18, 146, 82, 210, 50, 178, 114, 242,  10, 138, 74, 202, 42, 170, 106, 234, 26, 154, 90, 218, 58, 186, 122, 250,  6, 134, 70, 198, 38, 166, 102, 230, 22, 150, 86, 214, 54, 182, 118, 246,  14, 142, 78, 206, 46, 174, 110, 238, 30, 158, 94, 222, 62, 190, 126, 254,  1, 129, 65, 193, 33, 161, 97, 225, 17, 145, 81, 209, 49, 177, 113, 241,  9, 137, 73, 201, 41, 169, 105, 233, 25, 153, 89, 217, 57, 185, 121, 249,  5, 133, 69, 197, 37, 165, 101, 229, 21, 149, 85, 213, 53, 181, 117, 245,  13, 141, 77, 205, 45, 173, 109, 237, 29, 157, 93, 221, 61, 189, 125, 253,  3, 131, 67, 195, 35, 163, 99, 227, 19, 147, 83, 211, 51, 179, 115, 243,  11, 139, 75, 203, 43, 171, 107, 235, 27, 155, 91, 219, 59, 187, 123, 251,  7, 135, 71, 199, 39, 167, 103, 231, 23, 151, 87, 215, 55, 183, 119, 247,  15, 143, 79, 207, 47, 175, 111, 239, 31, 159, 95, 223, 63, 191, 127, 255};static quint32        bit_masks[33] = {        0x0,           0x1,            0x3,            0x7,        0xf,           0x1f,           0x3f,           0x7f,        0xff,          0x1ff,          0x3ff,          0x7ff,        0xfff,         0x1fff,         0x3fff,         0x7fff,        0xffff,        0x1ffff,        0x3ffff,        0x7ffff,        0xfffff,       0x1fffff,       0x3fffff,       0x7fffff,        0xffffff,      0x1ffffff,      0x3ffffff,      0x7ffffff,        0xfffffff,     0x1fffffff,     0x3fffffff,     0x7fffffff,        0xffffffff};#define PK_ID      89#define PK_CMD_START 240#define PK_X1     240#define PK_X2     241#define PK_X3     242#define PK_X4     243#define PK_Y      244#define PK_POST   245#define PK_NOOP   246#define PK_PRE    247int TeXFont_PK::PK_get_nyb(FILE *fp){#ifdef DEBUG_PK  kDebug(kvs::dvi) << "PK_get_nyb" << endl;#endif  unsigned temp;  if (PK_bitpos < 0) {    PK_input_byte = one(fp);    PK_bitpos = 4;  }  temp = PK_input_byte >> PK_bitpos;  PK_bitpos -= 4;  return (temp & 0xf);}int TeXFont_PK::PK_packed_num(FILE *fp){#ifdef DEBUG_PK  kDebug(kvs::dvi) << "PK_packed_num" << endl;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -