Split and simplify wxHtmlDCRenderer::Render()
This function was difficult to understand as it did two quite different things depending on the value of its "dont_render" argument and using it also made CountPages() logic more complicated than necessary. Simplify the code by splitting Render() into FindNextPageBreak(), which is used by CountPages(), and Render() itself, which doesn't need to deal with pagination at all as it's either already provided the page start and end positions or can just assume that everything fits on a single page (the latter is the case for the headers and footers renderer). This is a notionally backwards-incompatible change, but no code using wxHtmlDCRenderer could be found in the wild and the new API is so much simpler that it seems to be worth switching to it.
This commit is contained in:
@@ -66,6 +66,9 @@ Changes in behaviour which may result in build errors
|
|||||||
- wx/treebook.h doesn't include wx/treectrl.h (and, via it, wx/textctrl.h) any
|
- wx/treebook.h doesn't include wx/treectrl.h (and, via it, wx/textctrl.h) any
|
||||||
more, include these headers explicitly from your code if necessary.
|
more, include these headers explicitly from your code if necessary.
|
||||||
|
|
||||||
|
- wxHtmlDCRenderer::Render() arguments have changed, simply omit the ones not
|
||||||
|
existing in the function signature any more to update the code using it.
|
||||||
|
|
||||||
|
|
||||||
3.1.2: (released 2018-??-??)
|
3.1.2: (released 2018-??-??)
|
||||||
----------------------------
|
----------------------------
|
||||||
|
@@ -62,30 +62,19 @@ public:
|
|||||||
const wxString& normal_face = wxEmptyString,
|
const wxString& normal_face = wxEmptyString,
|
||||||
const wxString& fixed_face = wxEmptyString);
|
const wxString& fixed_face = wxEmptyString);
|
||||||
|
|
||||||
|
// Finds the next page break after the specified (vertical) position.
|
||||||
|
// Returns wxNOT_FOUND if passed in position is the last page break.
|
||||||
|
int FindNextPageBreak(const wxArrayInt& known_pagebreaks, int pos);
|
||||||
|
|
||||||
// [x,y] is position of upper-left corner of printing rectangle (see SetSize)
|
// [x,y] is position of upper-left corner of printing rectangle (see SetSize)
|
||||||
// from is y-coordinate of the very first visible cell
|
// from is y-coordinate of the very first visible cell
|
||||||
// to is y-coordinate of the next following page break, if any
|
// to is y-coordinate of the next following page break, if any
|
||||||
// Returned value is y coordinate of first cell than didn't fit onto page.
|
void Render(int x, int y, int from = 0, int to = INT_MAX);
|
||||||
// Use this value as 'from' in next call to Render in order to print multiple pages
|
|
||||||
// document
|
|
||||||
// If dont_render is TRUE then nothing is rendered into DC and it only counts
|
|
||||||
// pixels and return y coord of the next page
|
|
||||||
//
|
|
||||||
// known_pagebreaks and number_of_pages are used only when counting pages;
|
|
||||||
// otherwise, their default values should be used. Their purpose is to
|
|
||||||
// support pagebreaks using a subset of CSS2's <DIV>. The <DIV> handler
|
|
||||||
// needs to know what pagebreaks have already been set so that it doesn't
|
|
||||||
// set the same pagebreak twice.
|
|
||||||
//
|
|
||||||
// CAUTION! Render() changes DC's user scale and does NOT restore it!
|
|
||||||
int Render(int x, int y, const wxArrayInt& known_pagebreaks, int from = 0,
|
|
||||||
int dont_render = false, int to = INT_MAX);
|
|
||||||
|
|
||||||
// returns total width of the html document
|
// returns total width of the html document
|
||||||
int GetTotalWidth() const;
|
int GetTotalWidth() const;
|
||||||
|
|
||||||
// returns total height of the html document
|
// returns total height of the html document
|
||||||
// (compare Render's return value with this)
|
|
||||||
int GetTotalHeight() const;
|
int GetTotalHeight() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@@ -38,10 +38,9 @@ public:
|
|||||||
/**
|
/**
|
||||||
Returns the height of the HTML text in pixels.
|
Returns the height of the HTML text in pixels.
|
||||||
|
|
||||||
This is important if area height (see wxHtmlDCRenderer::SetSize) is
|
If the height of the area used with this renderer (see
|
||||||
smaller that total height and thus the page cannot fit into it. In that
|
wxHtmlDCRenderer::SetSize) is smaller that total height, the renderer
|
||||||
case you're supposed to call Render() as long as its return value is
|
will produce more than one page of output.
|
||||||
smaller than GetTotalHeight()'s.
|
|
||||||
|
|
||||||
@see GetTotalWidth()
|
@see GetTotalWidth()
|
||||||
*/
|
*/
|
||||||
@@ -52,19 +51,11 @@ public:
|
|||||||
|
|
||||||
@param x,y
|
@param x,y
|
||||||
position of upper-left corner of printing rectangle (see SetSize()).
|
position of upper-left corner of printing rectangle (see SetSize()).
|
||||||
@param known_pagebreaks
|
|
||||||
@todo docme
|
|
||||||
@param from
|
@param from
|
||||||
y-coordinate of the very first visible cell.
|
y-coordinate of the very first visible cell.
|
||||||
@param dont_render
|
|
||||||
if @true then this method only returns y coordinate of the next page
|
|
||||||
and does not output anything.
|
|
||||||
@param to
|
@param to
|
||||||
y-coordinate of the last visible cell.
|
y-coordinate of the last visible cell or @c INT_MAX to use the full
|
||||||
|
page height.
|
||||||
Returned value is y coordinate of first cell than didn't fit onto page.
|
|
||||||
Use this value as from in next call to Render() in order to print
|
|
||||||
multipages document.
|
|
||||||
|
|
||||||
@note
|
@note
|
||||||
The following three methods @b must always be called before any call to
|
The following three methods @b must always be called before any call to
|
||||||
@@ -72,11 +63,8 @@ public:
|
|||||||
- SetDC()
|
- SetDC()
|
||||||
- SetSize()
|
- SetSize()
|
||||||
- SetHtmlText()
|
- SetHtmlText()
|
||||||
|
|
||||||
@note Render() changes the DC's user scale and does NOT restore it.
|
|
||||||
*/
|
*/
|
||||||
int Render(int x, int y, wxArrayInt& known_pagebreaks, int from = 0,
|
void Render(int x, int y, int from = 0, int to = INT_MAX);
|
||||||
int dont_render = false, int to = INT_MAX);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Assign DC instance to the renderer.
|
Assign DC instance to the renderer.
|
||||||
|
@@ -140,36 +140,37 @@ void wxHtmlDCRenderer::SetStandardFonts(int size,
|
|||||||
// else: SetHtmlText() not yet called, no need for relayout
|
// else: SetHtmlText() not yet called, no need for relayout
|
||||||
}
|
}
|
||||||
|
|
||||||
int wxHtmlDCRenderer::Render(int x, int y,
|
int wxHtmlDCRenderer::FindNextPageBreak(const wxArrayInt& known_pagebreaks,
|
||||||
const wxArrayInt& known_pagebreaks,
|
int pos)
|
||||||
int from, int dont_render, int to)
|
|
||||||
{
|
{
|
||||||
wxCHECK_MSG( m_Cells, 0, "SetHtmlText() must be called before Render()" );
|
// Stop looking for page breaks if the previous one was already at the end
|
||||||
wxCHECK_MSG( m_DC, 0, "SetDC() must be called before Render()" );
|
// of the last page.
|
||||||
|
//
|
||||||
|
// For an empty HTML document total height is 0, but we still must have at
|
||||||
|
// least a single page in it, so handle the case of pos == 0 specially.
|
||||||
|
if ( pos != 0 && pos >= GetTotalHeight() )
|
||||||
|
return wxNOT_FOUND;
|
||||||
|
|
||||||
int pbreak, hght;
|
pos += m_Height;
|
||||||
|
while (m_Cells->AdjustPagebreak(&pos, known_pagebreaks, m_Height)) {}
|
||||||
|
return pos;
|
||||||
|
}
|
||||||
|
|
||||||
pbreak = (int)(from + m_Height);
|
void wxHtmlDCRenderer::Render(int x, int y, int from, int to)
|
||||||
while (m_Cells->AdjustPagebreak(&pbreak, known_pagebreaks, m_Height)) {}
|
{
|
||||||
hght = pbreak - from;
|
wxCHECK_RET( m_DC, "SetDC() must be called before Render()" );
|
||||||
if(to < hght)
|
|
||||||
hght = to;
|
|
||||||
|
|
||||||
if (!dont_render)
|
const int hght = to == INT_MAX ? m_Height : to - from;
|
||||||
{
|
|
||||||
wxHtmlRenderingInfo rinfo;
|
|
||||||
wxDefaultHtmlRenderingStyle rstyle;
|
|
||||||
rinfo.SetStyle(&rstyle);
|
|
||||||
m_DC->SetBrush(*wxWHITE_BRUSH);
|
|
||||||
wxDCClipper clip(*m_DC, x, y, m_Width, hght);
|
|
||||||
m_Cells->Draw(*m_DC,
|
|
||||||
x, (y - from),
|
|
||||||
y, y + hght,
|
|
||||||
rinfo);
|
|
||||||
}
|
|
||||||
|
|
||||||
const int totalHeight = GetTotalHeight();
|
wxHtmlRenderingInfo rinfo;
|
||||||
return pbreak < totalHeight ? pbreak : totalHeight;
|
wxDefaultHtmlRenderingStyle rstyle;
|
||||||
|
rinfo.SetStyle(&rstyle);
|
||||||
|
m_DC->SetBrush(*wxWHITE_BRUSH);
|
||||||
|
wxDCClipper clip(*m_DC, x, y, m_Width, hght);
|
||||||
|
m_Cells->Draw(*m_DC,
|
||||||
|
x, (y - from),
|
||||||
|
y, y + hght,
|
||||||
|
rinfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
int wxHtmlDCRenderer::GetTotalWidth() const
|
int wxHtmlDCRenderer::GetTotalWidth() const
|
||||||
@@ -470,27 +471,16 @@ void wxHtmlPrintout::SetFooter(const wxString& footer, int pg)
|
|||||||
void wxHtmlPrintout::CountPages()
|
void wxHtmlPrintout::CountPages()
|
||||||
{
|
{
|
||||||
wxBusyCursor wait;
|
wxBusyCursor wait;
|
||||||
int pageWidth, pageHeight, mm_w, mm_h;
|
|
||||||
float ppmm_h, ppmm_v;
|
|
||||||
|
|
||||||
GetPageSizePixels(&pageWidth, &pageHeight);
|
|
||||||
GetPageSizeMM(&mm_w, &mm_h);
|
|
||||||
ppmm_h = (float)pageWidth / mm_w;
|
|
||||||
ppmm_v = (float)pageHeight / mm_h;
|
|
||||||
|
|
||||||
int pos = 0;
|
|
||||||
m_NumPages = 0;
|
m_NumPages = 0;
|
||||||
|
|
||||||
m_PageBreaks.Clear();
|
m_PageBreaks.Clear();
|
||||||
m_PageBreaks.Add( 0);
|
|
||||||
do
|
for ( int pos = 0; pos != wxNOT_FOUND; )
|
||||||
{
|
{
|
||||||
pos = m_Renderer.Render((int)( ppmm_h * m_MarginLeft),
|
|
||||||
(int) (ppmm_v * (m_MarginTop + (m_HeaderHeight == 0 ? 0 : m_MarginSpace)) + m_HeaderHeight),
|
|
||||||
m_PageBreaks,
|
|
||||||
pos, true, INT_MAX);
|
|
||||||
m_PageBreaks.Add( pos);
|
m_PageBreaks.Add( pos);
|
||||||
} while (pos < m_Renderer.GetTotalHeight());
|
pos = m_Renderer.FindNextPageBreak(m_PageBreaks, pos);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -525,8 +515,8 @@ void wxHtmlPrintout::RenderPage(wxDC *dc, int page)
|
|||||||
dc->SetBackgroundMode(wxTRANSPARENT);
|
dc->SetBackgroundMode(wxTRANSPARENT);
|
||||||
|
|
||||||
m_Renderer.Render((int) (ppmm_h * m_MarginLeft),
|
m_Renderer.Render((int) (ppmm_h * m_MarginLeft),
|
||||||
(int) (ppmm_v * (m_MarginTop + (m_HeaderHeight == 0 ? 0 : m_MarginSpace)) + m_HeaderHeight), m_PageBreaks,
|
(int) (ppmm_v * (m_MarginTop + (m_HeaderHeight == 0 ? 0 : m_MarginSpace)) + m_HeaderHeight),
|
||||||
m_PageBreaks[page-1], false, m_PageBreaks[page]-m_PageBreaks[page-1]);
|
m_PageBreaks[page-1], m_PageBreaks[page]);
|
||||||
|
|
||||||
|
|
||||||
m_RendererHdr.SetDC(dc,
|
m_RendererHdr.SetDC(dc,
|
||||||
@@ -535,12 +525,12 @@ void wxHtmlPrintout::RenderPage(wxDC *dc, int page)
|
|||||||
if (!m_Headers[page % 2].empty())
|
if (!m_Headers[page % 2].empty())
|
||||||
{
|
{
|
||||||
m_RendererHdr.SetHtmlText(TranslateHeader(m_Headers[page % 2], page));
|
m_RendererHdr.SetHtmlText(TranslateHeader(m_Headers[page % 2], page));
|
||||||
m_RendererHdr.Render((int) (ppmm_h * m_MarginLeft), (int) (ppmm_v * m_MarginTop), m_PageBreaks);
|
m_RendererHdr.Render((int) (ppmm_h * m_MarginLeft), (int) (ppmm_v * m_MarginTop));
|
||||||
}
|
}
|
||||||
if (!m_Footers[page % 2].empty())
|
if (!m_Footers[page % 2].empty())
|
||||||
{
|
{
|
||||||
m_RendererHdr.SetHtmlText(TranslateHeader(m_Footers[page % 2], page));
|
m_RendererHdr.SetHtmlText(TranslateHeader(m_Footers[page % 2], page));
|
||||||
m_RendererHdr.Render((int) (ppmm_h * m_MarginLeft), (int) (pageHeight - ppmm_v * m_MarginBottom - m_FooterHeight), m_PageBreaks);
|
m_RendererHdr.Render((int) (ppmm_h * m_MarginLeft), (int) (pageHeight - ppmm_v * m_MarginBottom - m_FooterHeight));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user