"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "xpdf/HTMLGen.cc" between
xpdf-4.01.01.tar.gz and xpdf-4.02.tar.gz

About: Xpdf is a PDF viewer for X.

HTMLGen.cc  (xpdf-4.01.01):HTMLGen.cc  (xpdf-4.02)
skipping to change at line 37 skipping to change at line 37
#endif #endif
#include <stdlib.h> #include <stdlib.h>
#include <png.h> #include <png.h>
#include "gmem.h" #include "gmem.h"
#include "gmempp.h" #include "gmempp.h"
#include "GString.h" #include "GString.h"
#include "GList.h" #include "GList.h"
#include "SplashBitmap.h" #include "SplashBitmap.h"
#include "PDFDoc.h" #include "PDFDoc.h"
#include "GfxFont.h"
#include "TextOutputDev.h" #include "TextOutputDev.h"
#include "SplashOutputDev.h" #include "SplashOutputDev.h"
#include "ErrorCodes.h" #include "ErrorCodes.h"
#include "WebFont.h"
#include "HTMLGen.h" #include "HTMLGen.h"
#ifdef _WIN32 #ifdef _WIN32
# define strcasecmp stricmp # define strcasecmp stricmp
# define strncasecmp strnicmp # define strncasecmp strnicmp
#endif #endif
//------------------------------------------------------------------------ //------------------------------------------------------------------------
struct FontStyleTagInfo { struct FontStyleTagInfo {
skipping to change at line 65 skipping to change at line 67
// NB: these are compared, in order, against the tail of the font // NB: these are compared, in order, against the tail of the font
// name, so "BoldItalic" must come before "Italic", etc. // name, so "BoldItalic" must come before "Italic", etc.
static FontStyleTagInfo fontStyleTags[] = { static FontStyleTagInfo fontStyleTags[] = {
{"Roman", 5, gFalse, gFalse}, {"Roman", 5, gFalse, gFalse},
{"Regular", 7, gFalse, gFalse}, {"Regular", 7, gFalse, gFalse},
{"Condensed", 9, gFalse, gFalse}, {"Condensed", 9, gFalse, gFalse},
{"CondensedBold", 13, gTrue, gFalse}, {"CondensedBold", 13, gTrue, gFalse},
{"CondensedLight", 14, gFalse, gFalse}, {"CondensedLight", 14, gFalse, gFalse},
{"SemiBold", 8, gTrue, gFalse}, {"SemiBold", 8, gTrue, gFalse},
{"BoldItalicMT", 12, gTrue, gTrue},
{"BoldItalic", 10, gTrue, gTrue}, {"BoldItalic", 10, gTrue, gTrue},
{"Bold_Italic", 11, gTrue, gTrue}, {"Bold_Italic", 11, gTrue, gTrue},
{"BoldOblique", 11, gTrue, gTrue}, {"BoldOblique", 11, gTrue, gTrue},
{"Bold_Oblique", 12, gTrue, gTrue}, {"Bold_Oblique", 12, gTrue, gTrue},
{"BoldMT", 6, gTrue, gFalse},
{"Bold", 4, gTrue, gFalse}, {"Bold", 4, gTrue, gFalse},
{"ItalicMT", 8, gFalse, gTrue},
{"Italic", 6, gFalse, gTrue}, {"Italic", 6, gFalse, gTrue},
{"Oblique", 7, gFalse, gTrue}, {"Oblique", 7, gFalse, gTrue},
{"Light", 5, gFalse, gFalse}, {"Light", 5, gFalse, gFalse},
{NULL, 0, gFalse, gFalse} {NULL, 0, gFalse, gFalse}
}; };
struct StandardFontInfo { struct StandardFontInfo {
const char *name; const char *name;
GBool fixedWidth; GBool fixedWidth;
GBool serif; GBool serif;
skipping to change at line 174 skipping to change at line 179
static const char *vertAlignNames[] = { static const char *vertAlignNames[] = {
"baseline", "baseline",
"sub", "sub",
"super", "super",
"top" "top"
}; };
//------------------------------------------------------------------------ //------------------------------------------------------------------------
class HTMLGenFontDefn {
public:
HTMLGenFontDefn(Ref fontIDA, GString *fontFaceA, GString *fontSpecA,
double scaleA)
: fontID(fontIDA), fontFace(fontFaceA), fontSpec(fontSpecA)
, scale(scaleA), used(gFalse) {}
~HTMLGenFontDefn() { delete fontFace; delete fontSpec; }
GBool match(Ref fontIDA)
{ return fontIDA.num == fontID.num && fontIDA.gen == fontID.gen; }
Ref fontID;
GString *fontFace; // NULL for substituted fonts
GString *fontSpec;
double scale;
GBool used; // set when used (per page)
};
//------------------------------------------------------------------------
//------------------------------------------------------------------------ //------------------------------------------------------------------------
HTMLGen::HTMLGen(double backgroundResolutionA) { HTMLGen::HTMLGen(double backgroundResolutionA) {
TextOutputControl textOutControl; TextOutputControl textOutControl;
SplashColor paperColor; SplashColor paperColor;
ok = gTrue; ok = gTrue;
backgroundResolution = backgroundResolutionA; backgroundResolution = backgroundResolutionA;
zoom = 1.0; zoom = 1.0;
drawInvisibleText = gTrue; drawInvisibleText = gTrue;
allTextInvisible = gFalse; allTextInvisible = gFalse;
extractFontFiles = gFalse;
// set up the TextOutputDev // set up the TextOutputDev
textOutControl.mode = textOutReadingOrder; textOutControl.mode = textOutReadingOrder;
textOutControl.html = gTrue; textOutControl.html = gTrue;
textOut = new TextOutputDev(NULL, &textOutControl, gFalse); textOut = new TextOutputDev(NULL, &textOutControl, gFalse);
if (!textOut->isOk()) { if (!textOut->isOk()) {
ok = gFalse; ok = gFalse;
} }
// set up the SplashOutputDev // set up the SplashOutputDev
paperColor[0] = paperColor[1] = paperColor[2] = 0xff; paperColor[0] = paperColor[1] = paperColor[2] = 0xff;
splashOut = new SplashOutputDev(splashModeRGB8, 1, gFalse, paperColor); splashOut = new SplashOutputDev(splashModeRGB8, 1, gFalse, paperColor);
fontDefns = NULL;
} }
HTMLGen::~HTMLGen() { HTMLGen::~HTMLGen() {
delete textOut; delete textOut;
delete splashOut; delete splashOut;
if (fontDefns) {
deleteGList(fontDefns, HTMLGenFontDefn);
}
} }
void HTMLGen::startDoc(PDFDoc *docA) { void HTMLGen::startDoc(PDFDoc *docA) {
doc = docA; doc = docA;
splashOut->startDoc(doc->getXRef()); splashOut->startDoc(doc->getXRef());
if (fontDefns) {
deleteGList(fontDefns, HTMLGenFontDefn);
}
fontDefns = new GList();
nextFontFaceIdx = 0;
} }
static inline int pr(int (*writeFunc)(void *stream, const char *data, int size), static inline int pr(int (*writeFunc)(void *stream, const char *data, int size),
void *stream, const char *data) { void *stream, const char *data) {
return writeFunc(stream, data, (int)strlen(data)); return writeFunc(stream, data, (int)strlen(data));
} }
static int pf(int (*writeFunc)(void *stream, const char *data, int size), static int pf(int (*writeFunc)(void *stream, const char *data, int size),
void *stream, const char *fmt, ...) { void *stream, const char *fmt, ...) {
va_list args; va_list args;
skipping to change at line 242 skipping to change at line 279
}; };
static void pngWriteFunc(png_structp png, png_bytep data, png_size_t size) { static void pngWriteFunc(png_structp png, png_bytep data, png_size_t size) {
PNGWriteInfo *info; PNGWriteInfo *info;
info = (PNGWriteInfo *)png_get_progressive_ptr(png); info = (PNGWriteInfo *)png_get_progressive_ptr(png);
info->writePNG(info->pngStream, (char *)data, (int)size); info->writePNG(info->pngStream, (char *)data, (int)size);
} }
int HTMLGen::convertPage( int HTMLGen::convertPage(
int pg, const char *pngURL, int pg, const char *pngURL, const char *htmlDir,
int (*writeHTML)(void *stream, const char *data, int size), int (*writeHTML)(void *stream, const char *data, int size),
void *htmlStream, void *htmlStream,
int (*writePNG)(void *stream, const char *data, int size), int (*writePNG)(void *stream, const char *data, int size),
void *pngStream) { void *pngStream) {
png_structp png; png_structp png;
png_infop pngInfo; png_infop pngInfo;
PNGWriteInfo writeInfo; PNGWriteInfo writeInfo;
SplashBitmap *bitmap; SplashBitmap *bitmap;
Guchar *p; Guchar *p;
double pageW, pageH; double pageW, pageH;
TextPage *text; TextPage *text;
GList *cols, *pars, *lines, *words; GList *cols, *pars, *lines, *words;
TextFontInfo *font; TextFontInfo *font;
TextColumn *col; TextColumn *col;
TextParagraph *par; TextParagraph *par;
TextLine *line; TextLine *line;
HTMLGenFontDefn *fontDefn;
GString *s; GString *s;
double base; double base;
int primaryDir, spanDir; int primaryDir, spanDir;
int colIdx, parIdx, lineIdx, firstWordIdx, lastWordIdx; int colIdx, parIdx, lineIdx, firstWordIdx, lastWordIdx;
int y, i; int y, i;
// generate the background bitmap // generate the background bitmap
splashOut->setSkipText(!allTextInvisible, gFalse); splashOut->setSkipText(!allTextInvisible, gFalse);
doc->displayPage(splashOut, pg, backgroundResolution, backgroundResolution, doc->displayPage(splashOut, pg, backgroundResolution, backgroundResolution,
0, gFalse, gTrue, gFalse); 0, gFalse, gTrue, gFalse);
bitmap = splashOut->getBitmap(); bitmap = splashOut->getBitmap();
if (!(png = png_create_write_struct(PNG_LIBPNG_VER_STRING, if (!(png = png_create_write_struct(PNG_LIBPNG_VER_STRING,
NULL, NULL, NULL)) || NULL, NULL, NULL)) ||
!(pngInfo = png_create_info_struct(png))) { !(pngInfo = png_create_info_struct(png))) {
return errFileIO; return errFileIO;
} }
if (setjmp(png_jmpbuf(png))) { if (setjmp(png_jmpbuf(png))) {
return errFileIO; return errFileIO;
} }
writeInfo.writePNG = writePNG; writeInfo.writePNG = writePNG;
writeInfo.pngStream = pngStream; writeInfo.pngStream = pngStream;
png_set_write_fn(png, &writeInfo, pngWriteFunc, NULL); png_set_write_fn(png, &writeInfo, pngWriteFunc, NULL);
png_set_IHDR(png, pngInfo, bitmap->getWidth(), bitmap->getHeight(), png_set_IHDR(png, pngInfo, bitmap->getWidth(), bitmap->getHeight(),
skipping to change at line 316 skipping to change at line 354
primaryDir = text->primaryDirectionIsLR() ? 1 : -1; primaryDir = text->primaryDirectionIsLR() ? 1 : -1;
// HTML header // HTML header
pr(writeHTML, htmlStream, "<html>\n"); pr(writeHTML, htmlStream, "<html>\n");
pr(writeHTML, htmlStream, "<head>\n"); pr(writeHTML, htmlStream, "<head>\n");
pr(writeHTML, htmlStream, "<meta http-equiv=\"Content-Type\" content=\"text/ht ml; charset=UTF-8\">\n"); pr(writeHTML, htmlStream, "<meta http-equiv=\"Content-Type\" content=\"text/ht ml; charset=UTF-8\">\n");
pr(writeHTML, htmlStream, "<style type=\"text/css\">\n"); pr(writeHTML, htmlStream, "<style type=\"text/css\">\n");
pr(writeHTML, htmlStream, ".txt { white-space:nowrap; }\n"); pr(writeHTML, htmlStream, ".txt { white-space:nowrap; }\n");
fonts = text->getFonts(); fonts = text->getFonts();
fontScales = (double *)gmallocn(fonts->getLength(), sizeof(double)); fontScales = (double *)gmallocn(fonts->getLength(), sizeof(double));
for (i = 0; i < fontDefns->getLength(); ++i) {
fontDefn = (HTMLGenFontDefn *)fontDefns->get(i);
fontDefn->used = gFalse;
}
for (i = 0; i < fonts->getLength(); ++i) { for (i = 0; i < fonts->getLength(); ++i) {
font = (TextFontInfo *)fonts->get(i); font = (TextFontInfo *)fonts->get(i);
s = getFontDefn(font, &fontScales[i]); fontDefn = getFontDefn(font, htmlDir);
pf(writeHTML, htmlStream, "#f{0:d} {{ {1:t} }}\n", i, s); if (!fontDefn->used && fontDefn->fontFace) {
delete s; pr(writeHTML, htmlStream, fontDefn->fontFace->getCString());
}
pf(writeHTML, htmlStream, "#f{0:d} {{ {1:t} }}\n", i, fontDefn->fontSpec);
fontScales[i] = fontDefn->scale;
fontDefn->used = gTrue;
} }
pr(writeHTML, htmlStream, "</style>\n"); pr(writeHTML, htmlStream, "</style>\n");
pr(writeHTML, htmlStream, "</head>\n"); pr(writeHTML, htmlStream, "</head>\n");
if (primaryDir >= 0) { if (primaryDir >= 0) {
pr(writeHTML, htmlStream, "<body>\n"); pr(writeHTML, htmlStream, "<body>\n");
} else { } else {
pr(writeHTML, htmlStream, "<body dir=\"rtl\">\n"); pr(writeHTML, htmlStream, "<body dir=\"rtl\">\n");
} }
if (primaryDir >= 0) { if (primaryDir >= 0) {
pf(writeHTML, htmlStream, "<img id=\"background\" style=\"position:absolute; left:0px; top:0px;\" width=\"{0:d}\" height=\"{1:d}\" src=\"{2:s}\">\n", pf(writeHTML, htmlStream, "<img id=\"background\" style=\"position:absolute; left:0px; top:0px;\" width=\"{0:d}\" height=\"{1:d}\" src=\"{2:s}\">\n",
skipping to change at line 594 skipping to change at line 640
} else if (u <= 0x7fffffff) { } else if (u <= 0x7fffffff) {
s->append((char)(0xfc + (u >> 30))); s->append((char)(0xfc + (u >> 30)));
s->append((char)(0x80 + ((u >> 24) & 0x3f))); s->append((char)(0x80 + ((u >> 24) & 0x3f)));
s->append((char)(0x80 + ((u >> 18) & 0x3f))); s->append((char)(0x80 + ((u >> 18) & 0x3f)));
s->append((char)(0x80 + ((u >> 12) & 0x3f))); s->append((char)(0x80 + ((u >> 12) & 0x3f)));
s->append((char)(0x80 + ((u >> 6) & 0x3f))); s->append((char)(0x80 + ((u >> 6) & 0x3f)));
s->append((char)(0x80 + (u & 0x3f))); s->append((char)(0x80 + (u & 0x3f)));
} }
} }
GString *HTMLGen::getFontDefn(TextFontInfo *font, double *scale) { HTMLGenFontDefn *HTMLGen::getFontDefn(TextFontInfo *font,
const char *htmlDir) {
Ref id;
HTMLGenFontDefn *fontDefn;
int i;
// check the existing font defns
id = font->getFontID();
if (id.num >= 0) {
for (i = 0; i < fontDefns->getLength(); ++i) {
fontDefn = (HTMLGenFontDefn *)fontDefns->get(i);
if (fontDefn->match(id)) {
return fontDefn;
}
}
}
// try to extract a font file
if (!extractFontFiles ||
!(fontDefn = getFontFile(font, htmlDir))) {
// get a substitute font
fontDefn = getSubstituteFont(font);
}
fontDefns->append(fontDefn);
return fontDefn;
}
HTMLGenFontDefn *HTMLGen::getFontFile(TextFontInfo *font,
const char *htmlDir) {
Ref id;
HTMLGenFontDefn *fontDefn;
Object fontObj;
GfxFont *gfxFont;
WebFont *webFont;
GString *fontFile, *fontPath, *fontFace, *fontSpec;
const char *family, *weight, *style;
double scale;
id = font->getFontID();
if (id.num < 0) {
return NULL;
}
doc->getXRef()->fetch(id.num, id.gen, &fontObj);
if (!fontObj.isDict()) {
fontObj.free();
return NULL;
}
gfxFont = GfxFont::makeFont(doc->getXRef(), "F", id, fontObj.getDict());
webFont = new WebFont(gfxFont, doc->getXRef());
fontDefn = NULL;
if (webFont->canWriteTTF()) {
fontFile = GString::format("{0:d}.ttf", nextFontFaceIdx);
fontPath = GString::format("{0:s}/{1:t}", htmlDir, fontFile);
if (webFont->writeTTF(fontPath->getCString())) {
fontFace = GString::format("@font-face {{ font-family: ff{0:d}; src: url(\
"{1:t}\"); }}\n",
nextFontFaceIdx, fontFile);
getFontDetails(font, &family, &weight, &style, &scale);
fontSpec = GString::format("font-family:ff{0:d},{1:s}; font-weight:{2:s};
font-style:{3:s};",
nextFontFaceIdx, family, weight, style);
++nextFontFaceIdx;
fontDefn = new HTMLGenFontDefn(id, fontFace, fontSpec, 1.0);
}
delete fontPath;
delete fontFile;
} else if (webFont->canWriteOTF()) {
fontFile = GString::format("{0:d}.otf", nextFontFaceIdx);
fontPath = GString::format("{0:s}/{1:t}", htmlDir, fontFile);
if (webFont->writeOTF(fontPath->getCString())) {
fontFace = GString::format("@font-face {{ font-family: ff{0:d}; src: url(\
"{1:t}\"); }}\n",
nextFontFaceIdx, fontFile);
getFontDetails(font, &family, &weight, &style, &scale);
fontSpec = GString::format("font-family:ff{0:d},{1:s}; font-weight:{2:s};
font-style:{3:s};",
nextFontFaceIdx, family, weight, style);
fontDefn = new HTMLGenFontDefn(id, fontFace, fontSpec, 1.0);
}
delete fontPath;
delete fontFile;
}
delete webFont;
delete gfxFont;
fontObj.free();
return fontDefn;
}
HTMLGenFontDefn *HTMLGen::getSubstituteFont(TextFontInfo *font) {
const char *family, *weight, *style;
double scale;
GString *fontSpec;
getFontDetails(font, &family, &weight, &style, &scale);
fontSpec = GString::format("font-family:{0:s}; font-weight:{1:s}; font-style:{
2:s};",
family, weight, style);
return new HTMLGenFontDefn(font->getFontID(), NULL, fontSpec, scale);
}
void HTMLGen::getFontDetails(TextFontInfo *font, const char **family,
const char **weight, const char **style,
double *scale) {
GString *fontName; GString *fontName;
char *fontName2; char *fontName2;
FontStyleTagInfo *fst; FontStyleTagInfo *fst;
StandardFontInfo *sf; StandardFontInfo *sf;
GBool fixedWidth, serif, bold, italic; GBool fixedWidth, serif, bold, italic;
double s; double s;
int n, i; int n, i;
// get the font name, remove any subset tag // get the font name, remove any subset tag
fontName = font->getFontName(); fontName = font->getFontName();
skipping to change at line 668 skipping to change at line 819
// compute the scaling factor // compute the scaling factor
*scale = 1; *scale = 1;
if ((s = font->getMWidth())) { if ((s = font->getMWidth())) {
i = (fixedWidth ? 8 : serif ? 4 : 0) + (bold ? 2 : 0) + (italic ? 1 : 0); i = (fixedWidth ? 8 : serif ? 4 : 0) + (bold ? 2 : 0) + (italic ? 1 : 0);
if (s < substFonts[i].mWidth) { if (s < substFonts[i].mWidth) {
*scale = s / substFonts[i].mWidth; *scale = s / substFonts[i].mWidth;
} }
} }
// generate the CSS markup *family = fixedWidth ? "monospace" : serif ? "serif" : "sans-serif";
return GString::format("font-family:{0:s}; font-weight:{1:s}; font-style:{2:s} *weight = bold ? "bold" : "normal";
;", *style = italic ? "italic" : "normal";
fixedWidth ? "monospace"
: serif ? "serif"
: "sans-serif",
bold ? "bold" : "normal",
italic ? "italic" : "normal");
} }
 End of changes. 17 change blocks. 
14 lines changed or deleted 165 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)