Fix infinite loop in wxHtmlEasyPrinting page break code.

The code didn't handle cells higher than the page height correctly and entered
an infinite loop when trying to adjust page breaks in their presence, e.g.
when trying to print a very tall image.

Closes #13935.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@70528 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin 2012-02-07 13:02:32 +00:00
parent d7235613f4
commit 846f4568e5
6 changed files with 50 additions and 18 deletions

View File

@ -469,6 +469,8 @@ All:
All (GUI):
- Added strike-through support to wxFont (Igor Korot).
- Fix infinite loop in wxHtmlEasyPrinting when trying to page break images
taller than the page height in wxHtmlEasyPrinting (Laurent Poujoulat).
- Added wxFilePickerCtrl::SetInitialDirectory().
- Added wxDataViewItemAttr::SetBackgroundColour() and implemented it in generic
wxDataViewCtrl (Andrew Xu).

View File

@ -280,10 +280,13 @@ public:
// Returned value : true if pagebreak was modified, false otherwise
// Usage : while (container->AdjustPagebreak(&p)) {}
virtual bool AdjustPagebreak(int *pagebreak,
const wxArrayInt& known_pagebreaks) const;
const wxArrayInt& known_pagebreaks,
int pageHeight) const;
// Sets cell's behaviour on pagebreaks (see AdjustPagebreak). Default
// is true - the cell can be split on two pages
// If there is no way to fit a cell in the current page size, the cell
// is always split, ignoring this setting.
void SetCanLiveOnPagebreak(bool can) { m_CanLiveOnPagebreak = can; }
// Can the line be broken before this cell?
@ -439,8 +442,10 @@ public:
wxHtmlRenderingInfo& info);
virtual void DrawInvisible(wxDC& dc, int x, int y,
wxHtmlRenderingInfo& info);
/* virtual bool AdjustPagebreak(int *pagebreak, int *known_pagebreaks = NULL, int number_of_pages = 0) const;*/
virtual bool AdjustPagebreak(int *pagebreak, const wxArrayInt& known_pagebreaks) const;
virtual bool AdjustPagebreak(int *pagebreak,
const wxArrayInt& known_pagebreaks,
int pageHeight) const;
// insert cell at the end of m_Cells list
void InsertCell(wxHtmlCell *cell);

View File

@ -95,19 +95,33 @@ public:
/**
This method is used to adjust pagebreak position.
The parameter is variable that contains y-coordinate of page break
The first parameter is a variable that contains the y-coordinate of the page break
(= horizontal line that should not be crossed by words, images etc.).
If this cell cannot be divided into two pieces (each one on another page)
then it moves the pagebreak few pixels up.
then it either moves the pagebreak a few pixels up, if possible, or, if
the cell cannot fit on the page at all, then the cell is forced to
split unconditionally.
Returns @true if pagebreak was modified, @false otherwise.
@param pagebreak
position in pixel of the pagebreak.
@param known_pagebreaks
the list of the previous pagebreaks
@param pageHeight
the height in pixel of the page drawable area
Usage:
@code
while (container->AdjustPagebreak(&p)) {}
while (container->AdjustPagebreak(&p, kp, ph)) {}
@endcode
*/
virtual bool AdjustPagebreak(int* pagebreak,
const wxArrayInt& known_pagebreaks) const;
const wxArrayInt& known_pagebreaks,
int pageHeight) const;
/**
Renders the cell.

View File

@ -220,11 +220,16 @@ wxCursor wxHtmlCell::GetMouseCursor(wxHtmlWindowInterface *window) const
}
bool wxHtmlCell::AdjustPagebreak(int *pagebreak,
const wxArrayInt& WXUNUSED(known_pagebreaks)) const
bool
wxHtmlCell::AdjustPagebreak(int *pagebreak,
const wxArrayInt& WXUNUSED(known_pagebreaks),
int pageHeight) const
{
if ((!m_CanLiveOnPagebreak) &&
m_PosY < *pagebreak && m_PosY + m_Height > *pagebreak)
// Notice that we always break the cells bigger than the page height here
// as otherwise we wouldn't be able to break them at all.
if ( m_Height <= pageHeight &&
(!m_CanLiveOnPagebreak &&
m_PosY < *pagebreak && m_PosY + m_Height > *pagebreak) )
{
*pagebreak = m_PosY;
return true;
@ -774,11 +779,13 @@ int wxHtmlContainerCell::GetIndentUnits(int ind) const
}
bool wxHtmlContainerCell::AdjustPagebreak(int *pagebreak,
const wxArrayInt& known_pagebreaks) const
bool
wxHtmlContainerCell::AdjustPagebreak(int *pagebreak,
const wxArrayInt& known_pagebreaks,
int pageHeight) const
{
if (!m_CanLiveOnPagebreak)
return wxHtmlCell::AdjustPagebreak(pagebreak, known_pagebreaks);
return wxHtmlCell::AdjustPagebreak(pagebreak, known_pagebreaks, pageHeight);
wxHtmlCell *c = GetFirstChild();
bool rt = false;
@ -786,7 +793,7 @@ bool wxHtmlContainerCell::AdjustPagebreak(int *pagebreak,
while (c)
{
if (c->AdjustPagebreak(&pbrk, known_pagebreaks))
if (c->AdjustPagebreak(&pbrk, known_pagebreaks, pageHeight))
rt = true;
c = c->GetNext();
}

View File

@ -151,7 +151,7 @@ int wxHtmlDCRenderer::Render(int x, int y,
int pbreak, hght;
pbreak = (int)(from + m_Height);
while (m_Cells->AdjustPagebreak(&pbreak, known_pagebreaks)) {}
while (m_Cells->AdjustPagebreak(&pbreak, known_pagebreaks, m_Height)) {}
hght = pbreak - from;
if(to < hght)
hght = to;

View File

@ -71,7 +71,8 @@ public:
wxHtmlPageBreakCell() {}
bool AdjustPagebreak(int* pagebreak,
const wxArrayInt& known_pagebreaks) const;
const wxArrayInt& known_pagebreaks,
int pageHeight) const;
void Draw(wxDC& WXUNUSED(dc),
int WXUNUSED(x), int WXUNUSED(y),
@ -82,7 +83,10 @@ private:
wxDECLARE_NO_COPY_CLASS(wxHtmlPageBreakCell);
};
bool wxHtmlPageBreakCell::AdjustPagebreak(int* pagebreak, const wxArrayInt& known_pagebreaks) const
bool
wxHtmlPageBreakCell::AdjustPagebreak(int* pagebreak,
const wxArrayInt& known_pagebreaks,
int WXUNUSED(pageHeight)) const
{
// When we are counting pages, 'known_pagebreaks' is non-NULL.
// That's the only time we change 'pagebreak'. Otherwise, pages