diff --git a/docs/changes.txt b/docs/changes.txt index 4b9ec418eb..a156283e77 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -106,6 +106,7 @@ All (GUI): - Add wxHtmlEasyPrinting::SetPromptMode() (pavel-t). - Fix possible infinite loop in wxHtmlWindow layout (trivia21). - Add "hint" property support to XRC for wxComboBox and wxSearchCtrl. +- Add support for style="page-break-inside:avoid" to
in wxHTML. wxGTK: diff --git a/samples/html/printing/test.htm b/samples/html/printing/test.htm index 3bb5be3a20..c0518a8d00 100644 --- a/samples/html/printing/test.htm +++ b/samples/html/printing/test.htm @@ -55,6 +55,8 @@ is split into base and GUI libraries.

+ +

Release 2.1.11 (final)

+

+

Release 2.1.12

+

+

Release 2.1.13

+

@@ -102,6 +109,7 @@ combined base/GUI library for GUI applications only.

+

Release 2.2.x (final)

+

+

Release 2.3.x (final)

+

diff --git a/src/html/m_layout.cpp b/src/html/m_layout.cpp index 95b0afbab2..5556c34396 100644 --- a/src/html/m_layout.cpp +++ b/src/html/m_layout.cpp @@ -187,6 +187,35 @@ TAG_HANDLER_BEGIN(DIV, "DIV") m_WParser->OpenContainer(); return false; } + else if(style.IsSameAs(wxT("PAGE-BREAK-INSIDE:AVOID"), false)) + { + // As usual, reuse the current container if it's empty. + wxHtmlContainerCell *c = m_WParser->GetContainer(); + if (c->GetFirstChild() != NULL) + { + // If not, open a new one. + m_WParser->CloseContainer(); + c = m_WParser->OpenContainer(); + } + + // Force this container to live entirely on the same page. + c->SetCanLiveOnPagebreak(false); + + // Use a nested container so that nested tags that close and + // reopen a container again close this one, but still remain + // inside the outer "unbreakable" container. + m_WParser->OpenContainer(); + + ParseInner(tag); + + // Close both the inner and the outer containers and reopen the + // new current one. + m_WParser->CloseContainer(); + m_WParser->CloseContainer(); + m_WParser->OpenContainer(); + + return true; + } else { // Treat other STYLE parameters here when they're supported. diff --git a/tests/html/htmprint.cpp b/tests/html/htmprint.cpp index 34560d9cb8..64ce4b144e 100644 --- a/tests/html/htmprint.cpp +++ b/tests/html/htmprint.cpp @@ -59,6 +59,17 @@ TEST_CASE("wxHtmlPrintout::Pagination", "[html][print]") // the DPI-dependent factor, but it doesn't seem to be worth doing it). pr.SetMargins(0, 0, 0, 0, 0); + // Use font size in pixels to make it DPI-independent: if we just used a + // normal (say 12pt) font, it would have different height in pixels on 96 + // and 200 DPI systems, meaning that the text at the end of this test would + // take different number of (fixed to 1000px height) pages. + // + // We could also make the page height proportional to the DPI, but this + // would be more complicated as we also wouldn't be able to use hardcoded + // height attribute values in the HTML snippets below then. + const wxFont fontFixedPixelSize(wxFontInfo(wxSize(10, 16))); + pr.SetStandardFonts(fontFixedPixelSize.GetPointSize(), "Helvetica"); + wxBitmap bmp(1000, 1000); wxMemoryDC dc(bmp); pr.SetUp(dc); @@ -107,6 +118,75 @@ TEST_CASE("wxHtmlPrintout::Pagination", "[html][print]") "

" ); CHECK( CountPages(pr) == 2 ); + + // Also test that forbidding page breaks inside a paragraph works: it + // should move it entirely to the next page, resulting in one extra page + // compared to the version without "page-break-inside: avoid". + static const char* const text = +"Early in the morning on the fourteenth of the spring month of Nisan the
" +"Procurator of Judea, Pontius Pilate, in a white cloak lined with blood red,
" +"emerged with his shuffling cavalryman's walk into the arcade connecting the two
" +"wings of the palace of Herod the Great.
" +"
" +"More than anything else in the world the Procurator hated the smell of attar of
" +"roses. The omens for the day were bad, as this scent had been haunting him
" +"since dawn.
" +"
" +"It seemed to the Procurator that the very cypresses and palms in the garden
" +"were exuding the smell of roses, that this damned stench of roses was even
" +"mingling with the smell of leather tackle and sweat from his mounted bodyguard.
" +"
" +"A haze of smoke was drifting toward the arcade across the upper courtyard of
" +"the garden, coming from the wing at the rear of the palace, the quarters of the
" +"first cohort of the XII Legion; known as the \"Lightning,\" it had been
" +"stationed in Jerusalem since the Procurator's arrival. The same oily perfume
" +"of roses was mixed with the acrid smoke that showed that the centuries' cooks
" +"had started to prepare breakfast
" +"
" +"\"Oh, gods, what are you punishing me for?.. No, there's no doubt, I have it
" +"again, this terrible incurable pain... hemicrania, when half the head aches...
" +"There's no cure for it, nothing helps... I must try not to move my head...\"
" +"
" +"A chair had already been placed on the mosaic floor by the fountain; without a
" +"glance around, the Procurator sat in it and stretched out his hand to one side.
" +"His secretary deferentially laid a piece of parchment in his hand. Unable to
" +"restrain a grimace of agony, the Procurator gave a fleeting sideways look at
" +"its contents, returned the parchment to his secretary and said painfully, \"The
" +"accused comes from Galilee, does he? Was the case sent to the tetrarch?\"
" +"
" +"\"Yes, Procurator,\" replied the secretary. \"He declined to confirm the
" +"finding of the court and passed the Sanhedrin's sentence of death to you for
" +"confirmation.\"
" +"
" +"The Procurator's cheek twitched, and he said quietly, \"Bring in the accused.\"
" + ; + + pr.SetHtmlText + ( + wxString::Format + ( + "" + "
%s
" + "
" + "", + text + ) + ); + CHECK( CountPages(pr) == 2 ); + + pr.SetHtmlText + ( + wxString::Format + ( + "" + "
%s
" + "
" + "", + text + ) + ); + INFO("Using base font size " << fontFixedPixelSize.GetPointSize()); + CHECK( CountPages(pr) == 3 ); } #endif //wxUSE_HTML