diff options
Diffstat (limited to 'Build/source/libs/xpdf/xpdf-src/xpdf/HTMLGen.cc')
-rw-r--r-- | Build/source/libs/xpdf/xpdf-src/xpdf/HTMLGen.cc | 173 |
1 files changed, 160 insertions, 13 deletions
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/HTMLGen.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/HTMLGen.cc index d6cbc24680d..036f1116c01 100644 --- a/Build/source/libs/xpdf/xpdf-src/xpdf/HTMLGen.cc +++ b/Build/source/libs/xpdf/xpdf-src/xpdf/HTMLGen.cc @@ -34,9 +34,11 @@ #include "GList.h" #include "SplashBitmap.h" #include "PDFDoc.h" +#include "GfxFont.h" #include "TextOutputDev.h" #include "SplashOutputDev.h" #include "ErrorCodes.h" +#include "WebFont.h" #include "HTMLGen.h" #ifdef _WIN32 @@ -62,11 +64,14 @@ static FontStyleTagInfo fontStyleTags[] = { {"CondensedBold", 13, gTrue, gFalse}, {"CondensedLight", 14, gFalse, gFalse}, {"SemiBold", 8, gTrue, gFalse}, + {"BoldItalicMT", 12, gTrue, gTrue}, {"BoldItalic", 10, gTrue, gTrue}, {"Bold_Italic", 11, gTrue, gTrue}, {"BoldOblique", 11, gTrue, gTrue}, {"Bold_Oblique", 12, gTrue, gTrue}, + {"BoldMT", 6, gTrue, gFalse}, {"Bold", 4, gTrue, gFalse}, + {"ItalicMT", 8, gFalse, gTrue}, {"Italic", 6, gFalse, gTrue}, {"Oblique", 7, gFalse, gTrue}, {"Light", 5, gFalse, gFalse}, @@ -171,6 +176,26 @@ static const char *vertAlignNames[] = { //------------------------------------------------------------------------ +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) +}; + +//------------------------------------------------------------------------ + //------------------------------------------------------------------------ @@ -184,6 +209,7 @@ HTMLGen::HTMLGen(double backgroundResolutionA) { zoom = 1.0; drawInvisibleText = gTrue; allTextInvisible = gFalse; + extractFontFiles = gFalse; // set up the TextOutputDev textOutControl.mode = textOutReadingOrder; @@ -196,16 +222,27 @@ HTMLGen::HTMLGen(double backgroundResolutionA) { // set up the SplashOutputDev paperColor[0] = paperColor[1] = paperColor[2] = 0xff; splashOut = new SplashOutputDev(splashModeRGB8, 1, gFalse, paperColor); + + fontDefns = NULL; } HTMLGen::~HTMLGen() { delete textOut; delete splashOut; + if (fontDefns) { + deleteGList(fontDefns, HTMLGenFontDefn); + } } void HTMLGen::startDoc(PDFDoc *docA) { doc = docA; 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), @@ -240,7 +277,7 @@ static void pngWriteFunc(png_structp png, png_bytep data, png_size_t size) { } 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), void *htmlStream, int (*writePNG)(void *stream, const char *data, int size), @@ -257,6 +294,7 @@ int HTMLGen::convertPage( TextColumn *col; TextParagraph *par; TextLine *line; + HTMLGenFontDefn *fontDefn; GString *s; double base; int primaryDir, spanDir; @@ -269,7 +307,7 @@ int HTMLGen::convertPage( 0, gFalse, gTrue, gFalse); bitmap = splashOut->getBitmap(); if (!(png = png_create_write_struct(PNG_LIBPNG_VER_STRING, - NULL, NULL, NULL)) || + NULL, NULL, NULL)) || !(pngInfo = png_create_info_struct(png))) { return errFileIO; } @@ -314,11 +352,19 @@ int HTMLGen::convertPage( pr(writeHTML, htmlStream, ".txt { white-space:nowrap; }\n"); fonts = text->getFonts(); 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) { font = (TextFontInfo *)fonts->get(i); - s = getFontDefn(font, &fontScales[i]); - pf(writeHTML, htmlStream, "#f{0:d} {{ {1:t} }}\n", i, s); - delete s; + fontDefn = getFontDefn(font, htmlDir); + if (!fontDefn->used && fontDefn->fontFace) { + 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, "</head>\n"); @@ -592,7 +638,112 @@ void HTMLGen::appendUTF8(Unicode u, GString *s) { } } -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; char *fontName2; FontStyleTagInfo *fst; @@ -666,11 +817,7 @@ GString *HTMLGen::getFontDefn(TextFontInfo *font, double *scale) { } } - // generate the CSS markup - return GString::format("font-family:{0:s}; font-weight:{1:s}; font-style:{2:s};", - fixedWidth ? "monospace" - : serif ? "serif" - : "sans-serif", - bold ? "bold" : "normal", - italic ? "italic" : "normal"); + *family = fixedWidth ? "monospace" : serif ? "serif" : "sans-serif"; + *weight = bold ? "bold" : "normal"; + *style = italic ? "italic" : "normal"; } |