further implementation of colored font specials

svn path=/trunk/kdegraphics/kdvi/; revision=217736
This commit is contained in:
Stefan Kebekus 2003-04-02 08:15:44 +00:00
parent 0d4ef35d19
commit 39ac84d05e
5 changed files with 79 additions and 32 deletions

View file

@ -88,9 +88,11 @@ glyph *TeXFont_PFB::getGlyph(Q_UINT16 ch, bool generateCharacterPixmap, QColor c
if (fatalErrorInFontLoading == true)
return g;
if ((generateCharacterPixmap == true) && (g->shrunkenCharacter.isNull())) {
if ((generateCharacterPixmap == true) && ((g->shrunkenCharacter.isNull()) || (color != g->color)) ) {
int error;
unsigned int res = (unsigned int)(parent->displayResolution_in_dpi/parent->enlargement +0.5);
g->color = color;
// Character height in 1/64th of points (reminder: 1 pt = 1/72 inch)
// Only approximate, may vary from file to file!!!! @@@@@
long int characterSize_in_printers_points_by_64 = (long int)(parent->scaled_size_in_DVI_units * 64.0 / (1<<16) + 0.5);
@ -150,9 +152,9 @@ glyph *TeXFont_PFB::getGlyph(Q_UINT16 ch, bool generateCharacterPixmap, QColor c
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] = 0;
destScanLine[4*col+1] = 0;
destScanLine[4*col+2] = 0;
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;

View file

@ -156,7 +156,10 @@ glyph *TeXFont_PK::getGlyph(Q_UINT16 ch, bool generateCharacterPixmap, QColor co
// 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()) && (characterBitmaps[ch]->w != 0)) {
if ((generateCharacterPixmap == true) &&
((g->shrunkenCharacter.isNull()) || (color != g->color)) &&
(characterBitmaps[ch]->w != 0)) {
g->color = color;
double shrinkFactor = MFResolutions[parent->font_pool->getMetafontMode()] / parent->displayResolution_in_dpi;
// All is fine? Then we rescale the bitmap in order to produce the
@ -223,15 +226,6 @@ glyph *TeXFont_PK::getGlyph(Q_UINT16 ch, bool generateCharacterPixmap, QColor co
// 8-bit.
QImage EightBitImage = g->shrunkenCharacter.convertToImage().smoothScale(shrunk_width, shrunk_height).convertDepth(32);
/*
QImage bm((uchar *)(characterBitmaps[ch]->bits),
characterBitmaps[ch]->bytes_wide*8, (int)characterBitmaps[ch]->h,
1, (QRgb *)0, 2, QImage::IgnoreEndian);
bm.setColor(0, qRgb(0x00,0x00,0x00));
bm.setColor(1, qRgb(0xFF,0xFF,0xFF));
QImage EightBitImage = bm.smoothScale(shrunk_width, shrunk_height).convertDepth(32);
*/
// Generate the alpha-channel. This again is highly inefficient.
// Would anybody please produce a faster routine?
QImage im32(shrunk_width, shrunk_height, 32);
@ -240,9 +234,9 @@ glyph *TeXFont_PK::getGlyph(Q_UINT16 ch, bool generateCharacterPixmap, QColor co
Q_UINT8 *srcScanLine = (Q_UINT8 *)EightBitImage.scanLine(y);
Q_UINT8 *destScanLine = (Q_UINT8 *)im32.scanLine(y);
for(Q_UINT16 col=0; col<shrunk_width; col++) {
destScanLine[4*col+0] = 0x00;
destScanLine[4*col+1] = 0x00;
destScanLine[4*col+2] = 0x00;
destScanLine[4*col+0] = color.blue();
destScanLine[4*col+1] = color.green();
destScanLine[4*col+2] = color.red();
destScanLine[4*col+3] = 0xFF-srcScanLine[4*col];
}
}

View file

@ -135,7 +135,8 @@ glyph *TeXFont_TFM::getGlyph(Q_UINT16 characterCode, bool generateCharacterPixma
// This is the address of the glyph that will be returned.
struct glyph *g = glyphtable+characterCode;
if ((generateCharacterPixmap) && (g->shrunkenCharacter.isNull())) {
if ((generateCharacterPixmap == true) && ((g->shrunkenCharacter.isNull()) || (color != g->color)) ) {
g->color = color;
Q_UINT16 pixelWidth = (Q_UINT16)(parent->displayResolution_in_dpi *
design_size_in_TeX_points.toDouble() *
characterWidth_in_units_of_design_size[characterCode].toDouble() * 100.0/7227.0 + 0.5);
@ -151,7 +152,7 @@ glyph *TeXFont_TFM::getGlyph(Q_UINT16 characterCode, bool generateCharacterPixma
pixelHeight = 50;
g->shrunkenCharacter.resize( pixelWidth, pixelHeight );
g->shrunkenCharacter.fill(QColor(100, 100, 100));
g->shrunkenCharacter.fill(color);
g->x2 = 0;
g->y2 = pixelHeight;
}

View file

@ -140,6 +140,7 @@ public:
void special(long nbytes);
void printErrorMsgForSpecials(QString msg);
void color_special(QString cp);
void html_href_special(QString cp);
void html_anchor_end(void);

View file

@ -4,7 +4,7 @@
// Methods for dviwin which deal with "\special" commands found in the
// DVI file
// Copyright 2000--2001, Stefan Kebekus (stefan.kebekus@uni-bayreuth.de).
// Copyright 2000--2003, Stefan Kebekus (kebekus@kde.org).
#include <kdebug.h>
@ -23,11 +23,50 @@
extern QPainter foreGroundPaint;
void dviWindow::printErrorMsgForSpecials(QString msg)
{
if (dviFile->errorCounter < 25) {
kdError(4300) << msg << endl;
dviFile->errorCounter++;
if (dviFile->errorCounter == 25)
kdError(4300) << i18n("That makes 25 errors. Further error messages will not be printed.") << endl;
}
}
// Parses a color specification, as explained in the manual to
// dvips. If the spec could not be parsed, an invalid color will be
// returned.
static QColor parseColorSpecification(QString colorSpec)
{
QString specType = KStringHandler::word(colorSpec, (unsigned int)0);
if (specType.find("rgb") == 0) {
bool ok;
double r = KStringHandler::word(colorSpec, (unsigned int)1).toDouble(&ok);
if ((ok == false) || (r < 0.0) || (r > 1.0))
return QColor();
double g = KStringHandler::word(colorSpec, (unsigned int)2).toDouble(&ok);
if ((ok == false) || (g < 0.0) || (g > 1.0))
return QColor();
double b = KStringHandler::word(colorSpec, (unsigned int)3).toDouble(&ok);
if ((ok == false) || (b < 0.0) || (b > 1.0))
return QColor();
return QColor((int)(r*255.0+0.5), (int)(g*255.0+0.5), (int)(b*255.0+0.5));
}
kdDebug() << "Spec not implemented : " << colorSpec << endl;
return Qt::green;
}
void dviWindow::color_special(QString cp)
{
kdDebug(4300) << "Color special: " << cp << endl;
// The color specials are ignore during the pre-scan phase, we use
// The color specials are ignored during the pre-scan phase, we use
// them only during rendering
if (PostScriptOutPutString == NULL) {
@ -37,17 +76,33 @@ void dviWindow::color_special(QString cp)
if (command == "pop") {
// Take color off the stack
if (colorStack.isEmpty())
printErrorMsgForSpecials( i18n("Error in DVIfile '%1', page %2. Color pop command issued when the color stack is empty." ).
arg(dviFile->filename).arg(current_page));
else
colorStack.pop();
return;
}
if (command == "push") {
// Get color specification
QColor col = parseColorSpecification(KStringHandler::word(cp, "1:"));
// Set color
if (col.isValid())
colorStack.push(col);
else
colorStack.push(Qt::black);
return;
}
// Get color specification
// Set color for the rest of this page
// Get color specification and set the color for the rest of this
// page
QColor col = parseColorSpecification(cp);
// Set color
if (col.isValid())
globalColor = col;
else
globalColor = Qt::black;
return;
}
}
@ -390,12 +445,6 @@ void dviWindow::applicationDoSpecial(char *cp)
return;
}
if (dviFile->errorCounter < 25) {
kdError(4300) << i18n("The special command \"") << special_command << i18n("\" is not implemented.") << endl;
dviFile->errorCounter++;
if (dviFile->errorCounter == 25)
kdError(4300) << i18n("That makes 25 errors. Further error messages will not be printed.") << endl;
}
printErrorMsgForSpecials(i18n("The special command '%1' is not implemented.").arg(special_command));
return;
}