1
0
Fork 0
mirror of https://github.com/geometer/FBReaderJ.git synced 2025-10-03 01:39:18 +02:00

ePub embedded fonts support (in progress)

This commit is contained in:
Nikolay Pultsin 2014-03-17 23:20:59 +02:00
parent 2f5e28d325
commit 8e925ef8d7
6 changed files with 85 additions and 13 deletions

View file

@ -20,13 +20,15 @@
#include <cctype>
#include <cstring>
#include <ZLStringUtil.h>
#include <ZLFile.h>
#include <ZLInputStream.h>
#include <ZLStringUtil.h>
#include <ZLLogger.h>
#include "StyleSheetParser.h"
#include "../util/MiscUtil.h"
StyleSheetParser::StyleSheetParser() {
StyleSheetParser::StyleSheetParser(const std::string &pathPrefix) : myPathPrefix(pathPrefix) {
reset();
}
@ -179,6 +181,9 @@ void StyleSheetParser::processWordWithoutComments(const std::string &word) {
}
}
StyleSheetSingleStyleParser::StyleSheetSingleStyleParser(const std::string &pathPrefix) : StyleSheetParser(pathPrefix) {
}
shared_ptr<ZLTextStyleEntry> StyleSheetSingleStyleParser::parseString(const char *text) {
myReadState = WAITING_FOR_ATTRIBUTE;
parse(text, std::strlen(text), true);
@ -187,6 +192,9 @@ shared_ptr<ZLTextStyleEntry> StyleSheetSingleStyleParser::parseString(const char
return control;
}
StyleSheetMultiStyleParser::StyleSheetMultiStyleParser(const std::string &pathPrefix) : StyleSheetParser(pathPrefix) {
}
void StyleSheetMultiStyleParser::storeData(const std::string &selector, const StyleSheetTable::AttributeMap &map) {
std::string s = selector;
ZLStringUtil::stripWhiteSpaces(s);
@ -215,8 +223,46 @@ void StyleSheetMultiStyleParser::storeData(const std::string &selector, const St
}
}
void StyleSheetMultiStyleParser::processAtRule(const std::string &name, const StyleSheetTable::AttributeMap&) {
static std::string firstValue(const StyleSheetTable::AttributeMap &map, const std::string &key) {
const StyleSheetTable::AttributeMap::const_iterator it = map.find(key);
if (it == map.end() || it->second.empty()) {
return std::string();
}
return it->second[0];
}
void StyleSheetMultiStyleParser::processAtRule(const std::string &name, const StyleSheetTable::AttributeMap &attributes) {
ZLLogger::Instance().registerClass("FONT");
if (name == "@font-face") {
const std::string family = firstValue(attributes, "font-family");
if (family.empty()) {
ZLLogger::Instance().println("FONT", "Font family not specified in @font-face entry");
return;
}
const StyleSheetTable::AttributeMap::const_iterator it = attributes.find("src");
std::string url;
if (it != attributes.end()) {
for (std::vector<std::string>::const_iterator jt = it->second.begin(); jt != it->second.end(); ++jt) {
if (ZLStringUtil::stringStartsWith(*jt, "url(") &&
ZLStringUtil::stringEndsWith(*jt, ")")) {
url = jt->substr(4, jt->size() - 5);
if (url.size() > 2 && url[0] == url[url.size() - 1]) {
if (url[0] == '\'' || url[0] == '"') {
url = url.substr(1, url.size() - 2);
}
}
break;
}
}
}
if (url.empty()) {
ZLLogger::Instance().println("FONT", "Source not specified for " + family);
return;
}
const ZLFile fontFile(myPathPrefix + MiscUtil::decodeHtmlURL(url));
const bool bold = firstValue(attributes, "font-weight") == "bold";
const bool italic = firstValue(attributes, "font-style") == "italic";
ZLLogger::Instance().println("FONT", family + " => " + fontFile.path());
}
}
@ -235,13 +281,16 @@ void StyleSheetMultiStyleParser::parseStream(ZLInputStream &stream) {
}
}
StyleSheetTableParser::StyleSheetTableParser(StyleSheetTable &table) : myTable(table) {
StyleSheetTableParser::StyleSheetTableParser(const std::string &pathPrefix, StyleSheetTable &table) : StyleSheetMultiStyleParser(pathPrefix), myTable(table) {
}
void StyleSheetTableParser::store(const std::string &tag, const std::string &aClass, const StyleSheetTable::AttributeMap &map) {
myTable.addMap(tag, aClass, map);
}
StyleSheetParserWithCache::StyleSheetParserWithCache(const std::string &pathPrefix) : StyleSheetMultiStyleParser(pathPrefix) {
}
void StyleSheetParserWithCache::store(const std::string &tag, const std::string &aClass, const StyleSheetTable::AttributeMap &map) {
myEntries.push_back(new Entry(tag, aClass, map));
}

View file

@ -29,7 +29,7 @@ class ZLInputStream;
class StyleSheetParser {
protected:
StyleSheetParser();
StyleSheetParser(const std::string &pathPrefix);
public:
virtual ~StyleSheetParser();
@ -45,6 +45,9 @@ private:
void processWordWithoutComments(const std::string &word);
void processControl(const char control);
protected:
const std::string myPathPrefix;
private:
std::string myWord;
std::string myAttributeName;
@ -65,11 +68,15 @@ friend class StyleSheetSingleStyleParser;
class StyleSheetSingleStyleParser : public StyleSheetParser {
public:
StyleSheetSingleStyleParser(const std::string &pathPrefix);
shared_ptr<ZLTextStyleEntry> parseString(const char *text);
};
class StyleSheetMultiStyleParser : public StyleSheetParser {
protected:
StyleSheetMultiStyleParser(const std::string &pathPrefix);
public:
void parseStream(ZLInputStream &stream);
@ -84,7 +91,7 @@ private:
class StyleSheetTableParser : public StyleSheetMultiStyleParser {
public:
StyleSheetTableParser(StyleSheetTable &table);
StyleSheetTableParser(const std::string &pathPrexix, StyleSheetTable &table);
private:
void store(const std::string &tag, const std::string &aClass, const StyleSheetTable::AttributeMap &map);
@ -105,6 +112,7 @@ private:
};
public:
StyleSheetParserWithCache(const std::string &pathPrefix);
void applyToTable(StyleSheetTable &table) const;
private:

View file

@ -274,7 +274,7 @@ HtmlStyleTagAction::HtmlStyleTagAction(HtmlBookReader &reader) : HtmlTagAction(r
}
void HtmlStyleTagAction::run(const HtmlReader::HtmlTag &tag) {
myReader.myStyleSheetParser = tag.Start ? new StyleSheetTableParser(myReader.myStyleSheetTable) : 0;
myReader.myStyleSheetParser = tag.Start ? new StyleSheetTableParser(myReader.myBaseDirPath, myReader.myStyleSheetTable) : 0;
/*
if (!tag.Start) {
myReader.myStyleSheetTable.dump();

View file

@ -229,7 +229,7 @@ void XHTMLTagStyleAction::doAtStart(XHTMLReader &reader, const char **xmlattribu
if (reader.myReadState == XHTML_READ_NOTHING) {
reader.myReadState = XHTML_READ_STYLE;
reader.myTableParser = new StyleSheetTableParser(reader.myStyleSheetTable);
reader.myTableParser = new StyleSheetTableParser(reader.myPathPrefix, reader.myStyleSheetTable);
ZLLogger::Instance().println("CSS", "parsing style tag content");
}
}
@ -259,14 +259,15 @@ void XHTMLTagLinkAction::doAtStart(XHTMLReader &reader, const char **xmlattribut
return;
}
const std::string cssFilePath = reader.myPathPrefix + MiscUtil::decodeHtmlURL(href);
std::string cssFilePath = reader.myPathPrefix + MiscUtil::decodeHtmlURL(href);
//ZLLogger::Instance().registerClass("CSS");
ZLLogger::Instance().println("CSS", "style file: " + cssFilePath);
const ZLFile cssFile(cssFilePath);
shared_ptr<StyleSheetParserWithCache> parser = reader.myFileParsers[cssFile.path()];
cssFilePath = cssFile.path();
shared_ptr<StyleSheetParserWithCache> parser = reader.myFileParsers[cssFilePath];
if (parser.isNull()) {
parser = new StyleSheetParserWithCache();
reader.myFileParsers[cssFile.path()] = parser;
parser = new StyleSheetParserWithCache(MiscUtil::htmlDirectoryPrefix(cssFilePath));
reader.myFileParsers[cssFilePath] = parser;
ZLLogger::Instance().println("CSS", "creating stream");
shared_ptr<ZLInputStream> cssStream = ZLFile(cssFilePath).inputStream(reader.myEncryptionMap);
if (!cssStream.isNull()) {
@ -639,7 +640,7 @@ bool XHTMLReader::readFile(const ZLFile &file, const std::string &referenceName)
myStylesToRemove = 0;
myDoPageBreakAfterStack.clear();
myStyleParser = new StyleSheetSingleStyleParser();
myStyleParser = new StyleSheetSingleStyleParser(myPathPrefix);
myTableParser.reset();
return readDocument(file.inputStream(myEncryptionMap));

View file

@ -103,6 +103,19 @@ std::vector<std::string> ZLStringUtil::split(const std::string &str, const std::
return result;
}
std::string ZLStringUtil::join(const std::vector<std::string> &data, const std::string &delimiter) {
std::string joined;
bool addDelimiter = false;
for (std::vector<std::string>::const_iterator it = data.begin(); it != data.end(); ++it) {
if (addDelimiter) {
joined += delimiter;
}
joined += *it;
addDelimiter = true;
}
return joined;
}
std::string ZLStringUtil::printf(const std::string &format, const std::string &arg0) {
int index = format.find("%s");
if (index == -1) {

View file

@ -37,6 +37,7 @@ public:
static void stripWhiteSpaces(std::string &str);
static std::vector<std::string> split(const std::string &str, const std::string &delimiter);
static std::string join(const std::vector<std::string> &data, const std::string &delimiter);
static std::string printf(const std::string &format, const std::string &arg0);