bugfix: 60980, 61062

svn path=/trunk/kdegraphics/kdvi/; revision=240873
remotes/origin/kdvi-3.2
Stefan Kebekus 23 years ago
parent eb5246a328
commit 7ea3e7c0d1
  1. 58
      TeXFont_PFB.cpp
  2. 51
      TeXFont_PK.cpp
  3. 39
      fontpool.cpp
  4. 9
      fontpool.h

@ -195,17 +195,57 @@ glyph *TeXFont_PFB::getGlyph(Q_UINT16 ch, bool generateCharacterPixmap, QColor c
} else {
QImage imgi(slot->bitmap.width, slot->bitmap.rows, 32);
imgi.setAlphaBuffer(true);
uchar *srcScanLine = slot->bitmap.buffer;
for(int row=0; row<slot->bitmap.rows; row++) {
uchar *destScanLine = imgi.scanLine(row);
for(int col=0; col<slot->bitmap.width; col++) {
destScanLine[4*col+0] = color.blue();
destScanLine[4*col+1] = color.green();
destScanLine[4*col+2] = color.red();
destScanLine[4*col+3] = srcScanLine[col];
// 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.
uchar *srcScanLine = slot->bitmap.buffer;
for(int row=0; row<slot->bitmap.rows; row++) {
uchar *destScanLine = imgi.scanLine(row);
for(int col=0; col<slot->bitmap.width; col++) {
destScanLine[4*col+0] = color.blue();
destScanLine[4*col+1] = color.green();
destScanLine[4*col+2] = color.red();
destScanLine[4*col+3] = srcScanLine[col];
}
srcScanLine += slot->bitmap.pitch;
}
} 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.
Q_UINT16 rInv = 0xFF - color.red();
Q_UINT16 gInv = 0xFF - color.green();
Q_UINT16 bInv = 0xFF - color.blue();
for(Q_UINT16 y=0; y<slot->bitmap.rows; y++) {
Q_UINT8 *srcScanLine = slot->bitmap.buffer + y*slot->bitmap.pitch;
unsigned int *destScanLine = (unsigned int *)imgi.scanLine(y);
for(Q_UINT16 col=0; col<slot->bitmap.width; col++) {
Q_UINT16 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++;
}
}
srcScanLine += slot->bitmap.pitch;
}
g->shrunkenCharacter.convertFromImage (imgi, 0);
g->x2 = -slot->bitmap_left;
g->y2 = slot->bitmap_top;

@ -264,15 +264,52 @@ glyph *TeXFont_PK::getGlyph(Q_UINT16 ch, bool generateCharacterPixmap, QColor co
xydata[shrunk_width*y + x] = (int)(value/shrinkFactor);
}
// Generate the alpha-channel.
QImage im32(shrunk_width, shrunk_height, 32);
im32.fill(qRgb(color.red(), color.green(), color.blue()));
im32.setAlphaBuffer(TRUE);
for(Q_UINT16 y=0; y<shrunk_height; y++) {
Q_UINT8 *destScanLine = (Q_UINT8 *)im32.scanLine(y);
for(Q_UINT16 col=0; col<shrunk_width; col++)
destScanLine[4*col+3] = xydata[shrunk_width*y + col];
im32.setAlphaBuffer(true);
// 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(Q_UINT16 y=0; y<shrunk_height; y++) {
Q_UINT8 *destScanLine = (Q_UINT8 *)im32.scanLine(y);
for(Q_UINT16 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.
Q_UINT16 rInv = 0xFF - color.red();
Q_UINT16 gInv = 0xFF - color.green();
Q_UINT16 bInv = 0xFF - color.blue();
Q_UINT8 *srcScanLine = xydata;
for(Q_UINT16 y=0; y<shrunk_height; y++) {
unsigned int *destScanLine = (unsigned int *)im32.scanLine(y);
for(Q_UINT16 col=0; col<shrunk_width; col++) {
Q_UINT16 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.convertFromImage(im32,0);
g->shrunkenCharacter.setOptimization(QPixmap::BestOptim);
}

@ -14,7 +14,8 @@
#include <qapplication.h>
#include <qfile.h>
#include <qimage.h>
#include <qpainter.h>
#include <stdlib.h>
#include "fontpool.h"
@ -22,6 +23,10 @@
#include "performanceMeasurement.h"
#include "TeXFont.h"
// List of permissible MetaFontModes which are supported by kdvi.
const char *MFModes[] = { "cx", "ljfour", "lexmarks" };
@ -49,6 +54,7 @@ fontPool::fontPool(void)
MetafontMode = DefaultMFMode;
fontList.setAutoDelete(TRUE);
kdDebug() << "Checking Xft Extension 1" << endl;
#ifdef HAVE_FREETYPE
// Initialize the Freetype Library
@ -75,6 +81,37 @@ fontPool::fontPool(void)
qApp->connect(this, SIGNAL(show_progress(void)), progress, SLOT(show(void)));
qApp->connect(progress, SIGNAL(finished(void)), this, SLOT(abortGeneration(void)));
}
// Check if the QT library supports the alpha channel of
// pixmaps. Experiments show that --depending of the configuration
// of QT at compile and runtime or the availability of the XFt
// extension, alpha channels are either supported, or silently
// converted to 1-bit masks.
QImage start(1, 1, 32); // Generate a 1x1 image, black with alpha=0x10
start.setAlphaBuffer(true);
Q_UINT32 *destScanLine = (Q_UINT32 *)start.scanLine(0);
*destScanLine = 0x80000000;
QPixmap intermediate(start);
QPixmap dest(1,1);
dest.fill(Qt::white);
QPainter paint( &dest );
paint.drawPixmap(0, 0, intermediate);
paint.end();
start = dest.convertToImage().convertDepth(32);
Q_UINT8 result = *(start.scanLine(0)) & 0xff;
if ((result == 0xff) || (result == 0x00)) {
#ifdef DEBUG_FONTPOOL
kdDebug(4300) << "fontPool::fontPool(): QPixmap does not support the alpha channel" << endl;
#endif
QPixmapSupportsAlpha = false;
} else {
#ifdef DEBUG_FONTPOOL
kdDebug(4300) << "fontPool::fontPool(): QPixmap supports the alpha channel" << endl;
#endif
QPixmapSupportsAlpha = true;
}
}

@ -145,6 +145,15 @@ Q_OBJECT
fontEncodingPool encodingPool;
#endif
/** This flag is set during the construction of the fontPool
object. It indicates if the QT library supports the alpha
channel of pixmaps. Experiments show that --depending of the
configuration of QT at compile and runtime or the availability
of the XFt extension, alpha channels are either supported, or
silently converted to 1-bit masks. The redering routines in the
TeXFont implementation use this flag to choose the apropriate
drawing routines for the different setups. */
bool QPixmapSupportsAlpha;
signals:
/** Emitted to indicate that the progress dialog should show up now. */

Loading…
Cancel
Save