Respect "page-break-before" and "page-break-after" inline styles
This commit is contained in:
parent
fc3171abad
commit
74d70a9d3a
5 changed files with 59 additions and 26 deletions
|
@ -32,10 +32,17 @@ void StyleSheetTableParser::storeData(const std::string &tagName, const std::str
|
||||||
myTable.addMap(tagName, className, map);
|
myTable.addMap(tagName, className, map);
|
||||||
}
|
}
|
||||||
|
|
||||||
shared_ptr<ZLTextStyleEntry> StyleSheetSingleStyleParser::parseString(const char *text) {
|
shared_ptr<ZLTextStyleEntry> StyleSheetSingleStyleParser::parseString(const char *text, ZLBoolean3 *pageBreakBefore, ZLBoolean3 *pageBreakAfter) {
|
||||||
myReadState = ATTRIBUTE_NAME;
|
myReadState = ATTRIBUTE_NAME;
|
||||||
parse(text, strlen(text), true);
|
parse(text, strlen(text), true);
|
||||||
shared_ptr<ZLTextStyleEntry> control = StyleSheetTable::createControl(myMap);
|
shared_ptr<ZLTextStyleEntry> control = StyleSheetTable::createControl(myMap);
|
||||||
|
bool value;
|
||||||
|
if (pageBreakBefore && StyleSheetTable::getPageBreakBefore(myMap, value)) {
|
||||||
|
*pageBreakBefore = value ? B3_TRUE : B3_FALSE;
|
||||||
|
}
|
||||||
|
if (pageBreakAfter && StyleSheetTable::getPageBreakAfter(myMap, value)) {
|
||||||
|
*pageBreakAfter = value ? B3_TRUE : B3_FALSE;
|
||||||
|
}
|
||||||
reset();
|
reset();
|
||||||
return control;
|
return control;
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
#define __STYLESHEETPARSER_H__
|
#define __STYLESHEETPARSER_H__
|
||||||
|
|
||||||
#include "StyleSheetTable.h"
|
#include "StyleSheetTable.h"
|
||||||
|
#include "ZLBoolean3.h"
|
||||||
|
|
||||||
class ZLInputStream;
|
class ZLInputStream;
|
||||||
|
|
||||||
|
@ -76,7 +77,7 @@ private:
|
||||||
class StyleSheetSingleStyleParser : public StyleSheetParser {
|
class StyleSheetSingleStyleParser : public StyleSheetParser {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
shared_ptr<ZLTextStyleEntry> parseString(const char *text);
|
shared_ptr<ZLTextStyleEntry> parseString(const char *text, ZLBoolean3* pageBreakBefore, ZLBoolean3* pageBreakAfter);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* __STYLESHEETPARSER_H__ */
|
#endif /* __STYLESHEETPARSER_H__ */
|
||||||
|
|
|
@ -31,25 +31,12 @@ void StyleSheetTable::addMap(const std::string &tag, const std::string &aClass,
|
||||||
if ((!tag.empty() || !aClass.empty()) && !map.empty()) {
|
if ((!tag.empty() || !aClass.empty()) && !map.empty()) {
|
||||||
Key key(tag, aClass);
|
Key key(tag, aClass);
|
||||||
myControlMap[key] = createControl(map);
|
myControlMap[key] = createControl(map);
|
||||||
const std::vector<std::string> &pbb = values(map, "page-break-before");
|
bool value;
|
||||||
if (!pbb.empty()) {
|
if (getPageBreakBefore(map, value)) {
|
||||||
if ((pbb[0] == "always") ||
|
myPageBreakBeforeMap[key] = value;
|
||||||
(pbb[0] == "left") ||
|
|
||||||
(pbb[0] == "right")) {
|
|
||||||
myPageBreakBeforeMap[key] = true;
|
|
||||||
} else if (pbb[0] == "avoid") {
|
|
||||||
myPageBreakBeforeMap[key] = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
const std::vector<std::string> &pba = values(map, "page-break-after");
|
if (getPageBreakAfter(map, value)) {
|
||||||
if (!pba.empty()) {
|
myPageBreakAfterMap[key] = value;
|
||||||
if ((pba[0] == "always") ||
|
|
||||||
(pba[0] == "left") ||
|
|
||||||
(pba[0] == "right")) {
|
|
||||||
myPageBreakAfterMap[key] = true;
|
|
||||||
} else if (pba[0] == "avoid") {
|
|
||||||
myPageBreakAfterMap[key] = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -255,3 +242,35 @@ shared_ptr<ZLTextStyleEntry> StyleSheetTable::createControl(const AttributeMap &
|
||||||
|
|
||||||
return entry;
|
return entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool StyleSheetTable::getPageBreakBefore(const AttributeMap &map, bool &value) {
|
||||||
|
const std::vector<std::string> &pbb = values(map, "page-break-before");
|
||||||
|
if (!pbb.empty()) {
|
||||||
|
if ((pbb[0] == "always") ||
|
||||||
|
(pbb[0] == "left") ||
|
||||||
|
(pbb[0] == "right")) {
|
||||||
|
value = true;
|
||||||
|
return true;
|
||||||
|
} else if (pbb[0] == "avoid") {
|
||||||
|
value = false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool StyleSheetTable::getPageBreakAfter(const AttributeMap &map, bool &value) {
|
||||||
|
const std::vector<std::string> &pba = values(map, "page-break-after");
|
||||||
|
if (!pba.empty()) {
|
||||||
|
if ((pba[0] == "always") ||
|
||||||
|
(pba[0] == "left") ||
|
||||||
|
(pba[0] == "right")) {
|
||||||
|
value = true;
|
||||||
|
return true;
|
||||||
|
} else if (pba[0] == "avoid") {
|
||||||
|
value = false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
|
@ -33,6 +33,8 @@ class StyleSheetTable {
|
||||||
public:
|
public:
|
||||||
typedef std::map<std::string,std::vector<std::string> > AttributeMap;
|
typedef std::map<std::string,std::vector<std::string> > AttributeMap;
|
||||||
static shared_ptr<ZLTextStyleEntry> createControl(const AttributeMap &map);
|
static shared_ptr<ZLTextStyleEntry> createControl(const AttributeMap &map);
|
||||||
|
static bool getPageBreakBefore(const AttributeMap &map, bool &value);
|
||||||
|
static bool getPageBreakAfter(const AttributeMap &map, bool &value);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void addMap(const std::string &tag, const std::string &aClass, const AttributeMap &map);
|
void addMap(const std::string &tag, const std::string &aClass, const AttributeMap &map);
|
||||||
|
|
|
@ -526,10 +526,17 @@ void XHTMLReader::startElementHandler(const char *tag, const char **attributes)
|
||||||
const char *aClass = attributeValue(attributes, "class");
|
const char *aClass = attributeValue(attributes, "class");
|
||||||
const std::string sClass = (aClass != 0) ? aClass : "";
|
const std::string sClass = (aClass != 0) ? aClass : "";
|
||||||
|
|
||||||
if (myStyleSheetTable.doBreakBefore(sTag, sClass)) {
|
shared_ptr<ZLTextStyleEntry> inlineStyle;
|
||||||
|
const char *style = attributeValue(attributes, "style");
|
||||||
|
ZLBoolean3 pageBreakBefore(B3_UNDEFINED), pageBreakAfter(B3_UNDEFINED);
|
||||||
|
if (style != 0) {
|
||||||
|
inlineStyle = myStyleParser.parseString(style, &pageBreakBefore, &pageBreakAfter);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pageBreakBefore == B3_TRUE || (pageBreakBefore == B3_UNDEFINED && myStyleSheetTable.doBreakBefore(sTag, sClass))) {
|
||||||
myModelReader.insertEndOfSectionParagraph();
|
myModelReader.insertEndOfSectionParagraph();
|
||||||
}
|
}
|
||||||
myDoPageBreakAfterStack.push_back(myStyleSheetTable.doBreakAfter(sTag, sClass));
|
myDoPageBreakAfterStack.push_back(pageBreakAfter == B3_TRUE || (pageBreakAfter == B3_UNDEFINED && myStyleSheetTable.doBreakAfter(sTag, sClass)));
|
||||||
|
|
||||||
XHTMLTagAction *action = ourTagActions[sTag];
|
XHTMLTagAction *action = ourTagActions[sTag];
|
||||||
if (action != 0) {
|
if (action != 0) {
|
||||||
|
@ -540,10 +547,7 @@ void XHTMLReader::startElementHandler(const char *tag, const char **attributes)
|
||||||
entry = addStyleEntry(entry, myStyleSheetTable.control(sTag, ""));
|
entry = addStyleEntry(entry, myStyleSheetTable.control(sTag, ""));
|
||||||
entry = addStyleEntry(entry, myStyleSheetTable.control("", sClass));
|
entry = addStyleEntry(entry, myStyleSheetTable.control("", sClass));
|
||||||
entry = addStyleEntry(entry, myStyleSheetTable.control(sTag, sClass));
|
entry = addStyleEntry(entry, myStyleSheetTable.control(sTag, sClass));
|
||||||
const char *style = attributeValue(attributes, "style");
|
entry = addStyleEntry(entry, inlineStyle);
|
||||||
if (style != 0) {
|
|
||||||
entry = addStyleEntry(entry, myStyleParser.parseString(style));
|
|
||||||
}
|
|
||||||
if (!entry.isNull()) {
|
if (!entry.isNull()) {
|
||||||
myModelReader.addControl(*entry);
|
myModelReader.addControl(*entry);
|
||||||
myStyleEntryStack.push_back(entry);
|
myStyleEntryStack.push_back(entry);
|
||||||
|
|
Loading…
Reference in a new issue