mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
E-book viewer: Fix a regression in 5.15 that caused the viewer to not respect page-break properties
This commit is contained in:
parent
36511cb505
commit
0b94f39d9a
@ -313,7 +313,7 @@ class Token {
|
|||||||
text.reserve(16);
|
text.reserve(16);
|
||||||
}
|
}
|
||||||
|
|
||||||
Token(const TokenType type, const char32_t ch, size_t out_pos) :
|
Token(const TokenType type, const char32_t ch, size_t out_pos = 0) :
|
||||||
type(type), text(), unit_at(0), out_pos(out_pos) {
|
type(type), text(), unit_at(0), out_pos(out_pos) {
|
||||||
text.reserve(16);
|
text.reserve(16);
|
||||||
if (ch) text.push_back(ch);
|
if (ch) text.push_back(ch);
|
||||||
@ -391,6 +391,17 @@ class Token {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool is_property_terminator() const {
|
||||||
|
switch(type) {
|
||||||
|
case TokenType::whitespace:
|
||||||
|
return text.size() > 0 && text.find_first_of('\n') != std::string::npos;
|
||||||
|
case TokenType::delimiter:
|
||||||
|
return text.size() == 1 && (text[0] == ';' || text[0] == '}');
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
PyObject* get_text_as_python() const {
|
PyObject* get_text_as_python() const {
|
||||||
PyObject *ans = PyUnicode_FromKindAndData(PyUnicode_4BYTE_KIND, text.data(), text.size());
|
PyObject *ans = PyUnicode_FromKindAndData(PyUnicode_4BYTE_KIND, text.data(), text.size());
|
||||||
if (ans == NULL) throw python_error("Failed to convert token value to python unicode object");
|
if (ans == NULL) throw python_error("Failed to convert token value to python unicode object");
|
||||||
@ -414,6 +425,10 @@ class Token {
|
|||||||
text.replace(pos, len, (size_t)0u, 0);
|
text.replace(pos, len, (size_t)0u, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void prepend(const char32_t *src) {
|
||||||
|
text.insert(0, src);
|
||||||
|
}
|
||||||
|
|
||||||
void set_text(const PyObject* src) {
|
void set_text(const PyObject* src) {
|
||||||
if (PyUnicode_READY(src) != 0) throw python_error("Failed to set token value from unicode object as readying the unicode obect failed");
|
if (PyUnicode_READY(src) != 0) throw python_error("Failed to set token value from unicode object as readying the unicode obect failed");
|
||||||
int kind = PyUnicode_KIND(src); void *data = PyUnicode_DATA(src);
|
int kind = PyUnicode_KIND(src); void *data = PyUnicode_DATA(src);
|
||||||
@ -602,9 +617,21 @@ class TokenQueue {
|
|||||||
case PropertyType::font_size:
|
case PropertyType::font_size:
|
||||||
process_values = std::bind(&TokenQueue::process_font_sizes, this, std::placeholders::_1);
|
process_values = std::bind(&TokenQueue::process_font_sizes, this, std::placeholders::_1);
|
||||||
break;
|
break;
|
||||||
case PropertyType::page_break:
|
case PropertyType::page_break: {
|
||||||
it->erase_text_substring(0, 5);
|
it->erase_text_substring(0, 5);
|
||||||
|
size_t pos = std::distance(queue.begin(), it);
|
||||||
|
std::vector<Token> copies;
|
||||||
|
copies.reserve(queue.size());
|
||||||
|
while (it < queue.end() && !it->is_property_terminator()) { copies.push_back(*(it++)); }
|
||||||
|
if (copies.size()) {
|
||||||
|
queue.insert(queue.begin() + pos, std::make_move_iterator(copies.begin()), std::make_move_iterator(copies.end()));
|
||||||
|
size_t idx = pos + copies.size();
|
||||||
|
queue[idx].prepend(U"-webkit-column-");
|
||||||
|
queue.emplace(queue.begin() + idx, TokenType::whitespace, ' ');
|
||||||
|
queue.emplace(queue.begin() + idx, TokenType::delimiter, ';');
|
||||||
|
}
|
||||||
changed = true; keep_going = false;
|
changed = true; keep_going = false;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case PropertyType::non_standard_writing_mode:
|
case PropertyType::non_standard_writing_mode:
|
||||||
it->set_text(U"writing-mode");
|
it->set_text(U"writing-mode");
|
||||||
|
@ -31,6 +31,13 @@ class TestTransform(SimpleTest):
|
|||||||
def s(src, expected, url_callback=upper_case):
|
def s(src, expected, url_callback=upper_case):
|
||||||
return d(src, expected, url_callback=url_callback, is_declaration=False)
|
return d(src, expected, url_callback=url_callback, is_declaration=False)
|
||||||
|
|
||||||
|
s('.c { page-break-after: 1 always }', '.c { break-after: 1 always ; -webkit-column-break-after: 1 always }')
|
||||||
|
s('.c { page-break-after: always\ncolor:red }', '.c { break-after: always; -webkit-column-break-after: always\ncolor:red }')
|
||||||
|
s('.c { page-break-after: always\n}', '.c { break-after: always; -webkit-column-break-after: always\n}')
|
||||||
|
s('.c { page-break-after: always;color:red }', '.c { break-after: always; -webkit-column-break-after: always;color:red }')
|
||||||
|
s('.c { page-break-after: /**/always }', '.c { break-after: always ; -webkit-column-break-after: always }')
|
||||||
|
s('.c { page-break-after: always !important }', '.c { break-after: always !important ; -webkit-column-break-after: always !important }')
|
||||||
|
s('.c { page-break-after: always;}', '.c { break-after: always; -webkit-column-break-after: always;}')
|
||||||
s('.c{x:url(y)}', '.c{x:url("Y")}')
|
s('.c{x:url(y)}', '.c{x:url("Y")}')
|
||||||
s('@im/* c */port "x.y";', '@import "X.Y";')
|
s('@im/* c */port "x.y";', '@import "X.Y";')
|
||||||
s('@import url("narrow.css") supports(display: flex) handheld and (max-width: 400px);',
|
s('@import url("narrow.css") supports(display: flex) handheld and (max-width: 400px);',
|
||||||
@ -59,6 +66,7 @@ class TestTransform(SimpleTest):
|
|||||||
|
|
||||||
d('-epub-writing-mode: a; -web/* */kit-writing-mode: b; writing-mode: c', 'writing-mode: a; writing-mode: b; writing-mode: c')
|
d('-epub-writing-mode: a; -web/* */kit-writing-mode: b; writing-mode: c', 'writing-mode: a; writing-mode: b; writing-mode: c')
|
||||||
d('xxx:yyy', 'xxx:yyy')
|
d('xxx:yyy', 'xxx:yyy')
|
||||||
|
d('page-break-before: always', 'break-before: always; -webkit-column-break-before: always')
|
||||||
|
|
||||||
sheet = '''
|
sheet = '''
|
||||||
@import "b/loc.test";
|
@import "b/loc.test";
|
||||||
@ -78,9 +86,10 @@ class TestTransform(SimpleTest):
|
|||||||
@zoo {
|
@zoo {
|
||||||
not(.woo) and why {
|
not(.woo) and why {
|
||||||
font: 16px "something something" 16;
|
font: 16px "something something" 16;
|
||||||
|
page-break-before: avoid
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.why { font: 16px}
|
.why { font: 16px}
|
||||||
'''
|
'''
|
||||||
s(sheet, sheet.replace('16px', '1rem').replace('b/loc.test', 'B/LOC.TEST'))
|
s(sheet, sheet.replace('16px', '1rem').replace('b/loc.test', 'B/LOC.TEST').replace('page-', 'break-before: avoid; -webkit-column-'))
|
||||||
|
Loading…
x
Reference in New Issue
Block a user