new wxHTML printing code ; parser now supports scaling

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@4906 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Václav Slavík 1999-12-11 21:50:44 +00:00
parent 56ac3e75d4
commit edbd0635f2
12 changed files with 102 additions and 93 deletions

View File

@ -205,7 +205,7 @@ empty place!}
\func{void}{SetWidthFloat}{\param{int }{w}, \param{int }{units}}
\func{void}{SetWidthFloat}{\param{const wxHtmlTag\& }{tag}}
\func{void}{SetWidthFloat}{\param{const wxHtmlTag\& }{tag}, \param{double }{pixel_scale = 1.0}}
Sets floating width adjustment.
@ -213,6 +213,8 @@ The normal behaviour of container is that its width is the same as the width of
parent container (and thus you can have only one sub-container per line).
You can change this by setting FWA.
{\it pixel_scale} is number of real pixels that equals to 1 HTML pixel.
\wxheading{Parameters}
\docparam{w}{Width of the container. If the value is negative it means

View File

@ -23,10 +23,14 @@ Constructor.
\membersection{wxHtmlDCRenderer::SetDC}\label{wxhtmldcrenderersetdc}
\func{void}{SetDC}{\param{wxDC* }{dc}, \param{int }{maxwidth}}
\func{void}{SetDC}{\param{wxDC* }{dc}, \param{double }{pixel_scale = 1.0}}
Assign DC instance to the renderer.
{\it pixel_scale} can be used when rendering to high-resolution DCs (e.g. printer) to adjust size of pixel metrics.
(Many dimensions in HTML are given in pixels - e.g. image sizes. 300x300 image would be only one
inch wide on typical printer. With pixel_scale = 3.0 it would be 3 inches.)
\wxheading{Parameters}
\docparam{maxwidth}{width of the area (on this DC) that is equivalent to screen's width,
@ -45,9 +49,6 @@ See also \helpref{SetSize}{wxhtmldcrenderersetsize}.
Set size of output rectangle, in pixels. Note that you {\bf can't} change
width of the rectangle between calls to \helpref{Render}{wxhtmldcrendererrender}!
(You can freely change height.)
If you set width equal to maxwidth then HTML is rendered as if it were displayed in fullscreen.
If you set width = 1/2 maxwidth the it is rendered as if it covered half the screen
and so on.
\membersection{wxHtmlDCRenderer::SetHtmlText}\label{wxhtmldcrenderersethtmltext}

View File

@ -200,9 +200,12 @@ Alignment of newly opened container is set to this value.
\membersection{wxHtmlWinParser::SetDC}\label{wxhtmlwinparsersetdc}
\func{virtual void}{SetDC}{\param{wxDC }{*dc}}
\func{virtual void}{SetDC}{\param{wxDC }{*dc}, \param{double }{pixel_scale = 1.0}
Sets the DC. This must be called before \helpref{Parse}{wxhtmlparserparse}!
Sets the DC. This must be called before \helpref{Parse}{wxhtmlparserparse}! {\it pixel_scale}
can be used when rendering to high-resolution DCs (e.g. printer) to adjust size of pixel metrics.
(Many dimensions in HTML are given in pixels - e.g. image sizes. 300x300 image would be only one
inch wide on typical printer. With pixel_scale = 3.0 it would be 3 inches.)
\membersection{wxHtmlWinParser::SetFontBold}\label{wxhtmlwinparsersetfontbold}

View File

@ -210,7 +210,7 @@ class WXDLLEXPORT wxHtmlContainerCell : public wxHtmlCell
void SetAlign(const wxHtmlTag& tag);
// sets alignment info based on given tag's params
void SetWidthFloat(int w, int units) {m_WidthFloat = w; m_WidthFloatUnits = units;}
void SetWidthFloat(const wxHtmlTag& tag);
void SetWidthFloat(const wxHtmlTag& tag, double pixel_scale = 1.0);
// sets floating width adjustment
// (examples : 32 percent of parent container,
// -15 pixels percent (this means 100 % - 15 pixels)

View File

@ -38,17 +38,11 @@ class WXDLLEXPORT wxHtmlDCRenderer : public wxObject
~wxHtmlDCRenderer();
// Following 3 methods *must* be called before any call to Render:
void SetDC(wxDC *dc, int maxwidth);
void SetDC(wxDC *dc, double pixel_scale = 1.0);
// asign DC to this render
// maxwidth is width of area (on this DC) that is equivalent to screen's width, in pixels
// (you should set it to page width minus margins)
// Also see SetSize
void SetSize(int width, int height);
// sets size of output rectangle, in pixels. Note that you *can't* change
// width of the rectangle between calls to Render! (You can freely change height.)
// If you set width = maxwidth then HTML is rendered as if it were displayed in fullscreen.
// If you set width = 1/2 maxwidth the it is rendered as if it covered half the screen
// and so on..
void SetHtmlText(const wxString& html, const wxString& basepath = wxEmptyString, bool isdir = TRUE);
// sets the text to be displayed
//
@ -79,7 +73,6 @@ class WXDLLEXPORT wxHtmlDCRenderer : public wxObject
wxFileSystem *m_FS;
wxHtmlContainerCell *m_Cells;
int m_MaxWidth, m_Width, m_Height;
double m_Scale;
};

View File

@ -44,10 +44,11 @@ class WXDLLEXPORT wxHtmlWinParser : public wxHtmlParser
virtual void DoneParser();
virtual wxObject* GetProduct();
virtual void SetDC(wxDC *dc) {m_DC = dc;}
virtual void SetDC(wxDC *dc, double pixel_scale = 1.0) {m_DC = dc; m_PixelScale = pixel_scale;}
// Set's the DC used for parsing. If SetDC() is not called,
// parsing won't proceed
wxDC *GetDC() {return m_DC;}
double GetPixelScale() {return m_PixelScale;}
int GetCharHeight() const {return m_CharHeight;}
int GetCharWidth() const {return m_CharWidth;}
// NOTE : these functions do _not_ return _actual_
@ -113,6 +114,7 @@ class WXDLLEXPORT wxHtmlWinParser : public wxHtmlParser
// temporary variable used by AddText
wxWindow *m_Window;
// window we're parsing for
double m_PixelScale;
wxDC *m_DC;
// Device Context we're parsing for
static wxList m_Modules;

View File

@ -390,7 +390,7 @@ void wxHtmlContainerCell::SetAlign(const wxHtmlTag& tag)
void wxHtmlContainerCell::SetWidthFloat(const wxHtmlTag& tag)
void wxHtmlContainerCell::SetWidthFloat(const wxHtmlTag& tag, double pixel_scale)
{
if (tag.HasParam("WIDTH")) {
int wdi;
@ -402,7 +402,7 @@ void wxHtmlContainerCell::SetWidthFloat(const wxHtmlTag& tag)
}
else {
wxSscanf(wd.c_str(), wxT("%i"), &wdi);
SetWidthFloat(wdi, wxHTML_UNITS_PIXELS);
SetWidthFloat((int)(pixel_scale * (double)wdi), wxHTML_UNITS_PIXELS);
}
}
}

View File

@ -1,4 +1,3 @@
/////////////////////////////////////////////////////////////////////////////
// Name: htmprint.cpp
// Purpose: html printing classes
@ -49,7 +48,6 @@ wxHtmlDCRenderer::wxHtmlDCRenderer() : wxObject()
m_Parser = new wxHtmlWinParser(NULL);
m_FS = new wxFileSystem();
m_Parser -> SetFS(m_FS);
m_Scale = 1.0;
}
@ -63,29 +61,18 @@ wxHtmlDCRenderer::~wxHtmlDCRenderer()
void wxHtmlDCRenderer::SetDC(wxDC *dc, int maxwidth)
void wxHtmlDCRenderer::SetDC(wxDC *dc, double pixel_scale)
{
int dx, dy;
wxDisplaySize(&dx, &dy);
m_MaxWidth = maxwidth;
#if 0
m_Scale = (float)dx * 2 / 3 / (float)maxwidth;
// let the width of A4 is approximately 2/3 the screen width
#endif
m_Scale = (float)800 / (float)maxwidth;
// for now, assume screen width = 800 => good results
m_DC = dc;
m_Parser -> SetDC(dc);
m_Parser -> SetDC(m_DC, pixel_scale);
}
void wxHtmlDCRenderer::SetSize(int width, int height)
{
m_Width = (int)(width * m_Scale);
m_Height = (int)(height * m_Scale);
m_Width = width;
m_Height = height;
}
@ -97,7 +84,6 @@ void wxHtmlDCRenderer::SetHtmlText(const wxString& html, const wxString& basepat
if (m_Cells != NULL) delete m_Cells;
m_FS -> ChangePathTo(basepath, isdir);
m_DC -> SetUserScale(1.0, 1.0);
m_Cells = (wxHtmlContainerCell*) m_Parser -> Parse(html);
m_Cells -> SetIndent(0, wxHTML_INDENT_ALL, wxHTML_UNITS_PIXELS);
m_Cells -> Layout(m_Width);
@ -111,26 +97,21 @@ int wxHtmlDCRenderer::Render(int x, int y, int from, int dont_render)
if (m_Cells == NULL || m_DC == NULL) return 0;
pbreak = (int)(from * m_Scale + m_Height);
pbreak = (int)(from + m_Height);
while (m_Cells -> AdjustPagebreak(&pbreak)) {}
hght = pbreak - (int)(from * m_Scale);
hght = pbreak - from;
if (!dont_render) {
int w, h;
m_DC -> GetSize(&w, &h);
float overallScale = (float)(w/(float)m_MaxWidth) / m_Scale;
m_DC -> SetUserScale(overallScale, overallScale);
m_DC -> SetBrush(*wxWHITE_BRUSH);
m_DC -> SetClippingRegion(x * m_Scale, y * m_Scale, m_Width, hght);
m_DC -> SetClippingRegion(x, y, m_Width, hght);
m_Cells -> Draw(*m_DC,
x * m_Scale, (y - from) * m_Scale,
y * m_Scale, pbreak + (y /*- from*/) * m_Scale);
x, (y - from),
y, pbreak + (y /*- from*/));
m_DC -> DestroyClippingRegion();
}
if (pbreak < m_Cells -> GetHeight()) return (int)(pbreak / m_Scale);
if (pbreak < m_Cells -> GetHeight()) return pbreak;
else return GetTotalHeight();
}
@ -138,7 +119,7 @@ int wxHtmlDCRenderer::Render(int x, int y, int from, int dont_render)
int wxHtmlDCRenderer::GetTotalHeight()
{
if (m_Cells) return (int)(m_Cells -> GetHeight() / m_Scale);
if (m_Cells) return m_Cells -> GetHeight();
else return 0;
}
@ -187,7 +168,7 @@ wxHtmlPrintout::~wxHtmlPrintout()
bool wxHtmlPrintout::OnBeginDocument(int startPage, int endPage)
{
int pageWidth, pageHeight, mm_w, mm_h;
int pageWidth, pageHeight, mm_w, mm_h, scr_w, scr_h, dc_w, dc_h;
float ppmm_h, ppmm_v;
if (!wxPrintout::OnBeginDocument(startPage, endPage)) return FALSE;
@ -197,9 +178,19 @@ bool wxHtmlPrintout::OnBeginDocument(int startPage, int endPage)
ppmm_h = (float)pageWidth / mm_w;
ppmm_v = (float)pageHeight / mm_h;
int ppiPrinterX, ppiPrinterY;
GetPPIPrinter(&ppiPrinterX, &ppiPrinterY);
int ppiScreenX, ppiScreenY;
GetPPIScreen(&ppiScreenX, &ppiScreenY);
wxDisplaySize(&scr_w, &scr_h);
GetDC() -> GetSize(&dc_w, &dc_h);
GetDC() -> SetUserScale((double)dc_w / (double)pageWidth, (double)dc_w / (double)pageWidth);
/* prepare headers/footers renderer: */
m_RendererHdr -> SetDC(GetDC(), pageWidth);
m_RendererHdr -> SetDC(GetDC(), (double)ppiPrinterY / (double)ppiScreenY);
m_RendererHdr -> SetSize(ppmm_h * (mm_w - m_MarginLeft - m_MarginTop),
ppmm_v * (mm_h - m_MarginTop - m_MarginBottom));
if (m_Headers[0] != wxEmptyString) {
@ -220,7 +211,7 @@ bool wxHtmlPrintout::OnBeginDocument(int startPage, int endPage)
}
/* prepare main renderer: */
m_Renderer -> SetDC(GetDC(), pageWidth);
m_Renderer -> SetDC(GetDC(), (double)ppiPrinterY / (double)ppiScreenY);
m_Renderer -> SetSize(ppmm_h * (mm_w - m_MarginLeft - m_MarginTop),
ppmm_v * (mm_h - m_MarginTop - m_MarginBottom) -
m_FooterHeight - m_HeaderHeight -
@ -339,15 +330,24 @@ void wxHtmlPrintout::RenderPage(wxDC *dc, int page)
{
wxBusyCursor wait;
int pageWidth, pageHeight, mm_w, mm_h;
int pageWidth, pageHeight, mm_w, mm_h, scr_w, scr_h, dc_w, dc_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;
wxDisplaySize(&scr_w, &scr_h);
dc -> GetSize(&dc_w, &dc_h);
m_Renderer -> SetDC(dc, pageWidth);
int ppiPrinterX, ppiPrinterY;
GetPPIPrinter(&ppiPrinterX, &ppiPrinterY);
int ppiScreenX, ppiScreenY;
GetPPIScreen(&ppiScreenX, &ppiScreenY);
dc -> SetUserScale((double)dc_w / (double)pageWidth, (double)dc_w / (double)pageWidth);
m_Renderer -> SetDC(dc, (double)ppiPrinterY / (double)ppiScreenY);
dc -> SetBackgroundMode(wxTRANSPARENT);
@ -355,7 +355,7 @@ void wxHtmlPrintout::RenderPage(wxDC *dc, int page)
ppmm_v * (m_MarginTop + (m_HeaderHeight == 0 ? 0 : m_MarginSpace)) + m_HeaderHeight,
m_PageBreaks[page-1]);
m_RendererHdr -> SetDC(dc, pageWidth);
m_RendererHdr -> SetDC(dc, (double)ppiPrinterY / (double)ppiScreenY);
if (m_Headers[page % 2] != wxEmptyString) {
m_RendererHdr -> SetHtmlText(TranslateHeader(m_Headers[page % 2], page));
m_RendererHdr -> Render(ppmm_h * m_MarginLeft, ppmm_v * m_MarginTop);

View File

@ -81,7 +81,7 @@ TAG_HANDLER_BEGIN(HR, "HR")
c -> SetWidthFloat(tag);
sz = 1;
if (tag.HasParam(wxT("SIZE")) && tag.ScanParam(wxT("SIZE"), wxT("%i"), &sz) == 1) {}
c -> InsertCell(new wxHtmlLineCell(sz));
c -> InsertCell(new wxHtmlLineCell((int)((double)sz * m_WParser -> GetPixelScale())));
m_WParser -> CloseContainer();
m_WParser -> OpenContainer();

View File

@ -59,7 +59,7 @@ class wxHtmlImageMapAreaCell : public wxHtmlCell
celltype type;
int radius;
public:
wxHtmlImageMapAreaCell( celltype t, wxString &coords );
wxHtmlImageMapAreaCell( celltype t, wxString &coords, double pixel_scale = 1.0);
virtual wxString GetLink( int x = 0, int y = 0 ) const;
};
@ -67,17 +67,17 @@ class wxHtmlImageMapAreaCell : public wxHtmlCell
wxHtmlImageMapAreaCell::wxHtmlImageMapAreaCell( wxHtmlImageMapAreaCell::celltype t, wxString &incoords )
wxHtmlImageMapAreaCell::wxHtmlImageMapAreaCell( wxHtmlImageMapAreaCell::celltype t, wxString &incoords, double pixel_scale )
{
int i;
wxString x = incoords, y;
type = t;
while ((i = x.Find( ',' )) != -1) {
coords.Add( wxAtoi( x.Left( i ).c_str() ) );
coords.Add( (int)(pixel_scale * (double)wxAtoi( x.Left( i ).c_str())) );
x = x.Mid( i + 1 );
}
coords.Add( wxAtoi( x.c_str() ) );
coords.Add( (int)(pixel_scale * (double)wxAtoi( x.c_str())) );
}
wxString wxHtmlImageMapAreaCell::GetLink( int x, int y ) const
@ -372,7 +372,10 @@ TAG_HANDLER_BEGIN(IMG, "IMG,MAP,AREA")
}
wxHtmlImageCell *cel = NULL;
if (str) {
cel = new wxHtmlImageCell(str, w, h, al, mn);
cel = new wxHtmlImageCell(str,
(int)(m_WParser -> GetPixelScale() * (double)w),
(int)(m_WParser -> GetPixelScale() * (double)h),
al, mn);
cel -> SetLink(m_WParser -> GetLink());
m_WParser -> GetContainer() -> InsertCell(cel);
delete str;
@ -394,18 +397,18 @@ TAG_HANDLER_BEGIN(IMG, "IMG,MAP,AREA")
if (tag.GetName() == "AREA") {
if (tag.HasParam("SHAPE")) {
wxString tmp = tag.GetParam("SHAPE");
wxString coords;
wxString coords = wxEmptyString;
tmp.MakeUpper();
wxHtmlImageMapAreaCell *cel = NULL;
if (tag.HasParam("COORDS")) {
coords = tag.GetParam("COORDS");
}
if (tmp == "POLY") {
cel = new wxHtmlImageMapAreaCell( wxHtmlImageMapAreaCell::POLY, coords );
cel = new wxHtmlImageMapAreaCell( wxHtmlImageMapAreaCell::POLY, coords, m_WParser -> GetPixelScale() );
} else if (tmp == "CIRCLE") {
cel = new wxHtmlImageMapAreaCell( wxHtmlImageMapAreaCell::CIRCLE, coords );
cel = new wxHtmlImageMapAreaCell( wxHtmlImageMapAreaCell::CIRCLE, coords, m_WParser -> GetPixelScale() );
} else if (tmp == "RECT") {
cel = new wxHtmlImageMapAreaCell( wxHtmlImageMapAreaCell::RECT, coords );
cel = new wxHtmlImageMapAreaCell( wxHtmlImageMapAreaCell::RECT, coords, m_WParser -> GetPixelScale() );
}
if (cel != NULL && tag.HasParam("HREF")) {
wxString tmp = tag.GetParam("HREF");

View File

@ -93,9 +93,11 @@ class wxHtmlTableCell : public wxHtmlContainerCell
int m_tBkg, m_rBkg;
wxString m_tValign, m_rValign;
double m_PixelScale;
public:
wxHtmlTableCell(wxHtmlContainerCell *parent, const wxHtmlTag& tag);
wxHtmlTableCell(wxHtmlContainerCell *parent, const wxHtmlTag& tag, double pixel_scale = 1.0);
~wxHtmlTableCell();
virtual void Layout(int w);
@ -111,9 +113,10 @@ class wxHtmlTableCell : public wxHtmlContainerCell
wxHtmlTableCell::wxHtmlTableCell(wxHtmlContainerCell *parent, const wxHtmlTag& tag)
wxHtmlTableCell::wxHtmlTableCell(wxHtmlContainerCell *parent, const wxHtmlTag& tag, double pixel_scale)
: wxHtmlContainerCell(parent)
{
m_PixelScale = pixel_scale;
m_HasBorders = (tag.HasParam("BORDER") && tag.GetParam("BORDER") != "0");
m_ColsInfo = NULL;
m_NumCols = m_NumRows = 0;
@ -126,6 +129,8 @@ wxHtmlTableCell::wxHtmlTableCell(wxHtmlContainerCell *parent, const wxHtmlTag& t
if (tag.HasParam(wxT("VALIGN"))) m_tValign = tag.GetParam(wxT("VALIGN")); else m_tValign = wxEmptyString;
if (tag.HasParam(wxT("CELLSPACING")) && tag.ScanParam(wxT("CELLSPACING"), wxT("%i"), &m_Spacing) == 1) {} else m_Spacing = 2;
if (tag.HasParam(wxT("CELLPADDING")) && tag.ScanParam(wxT("CELLPADDING"), wxT("%i"), &m_Padding) == 1) {} else m_Padding = 3;
m_Spacing = (int)(m_PixelScale * (double)m_Spacing);
m_Padding = (int)(m_PixelScale * (double)m_Padding);
if (m_HasBorders)
SetBorder(TABLE_BORDER_CLR_1, TABLE_BORDER_CLR_2);
@ -229,6 +234,7 @@ void wxHtmlTableCell::AddCell(wxHtmlContainerCell *cell, const wxHtmlTag& tag)
}
else {
wxSscanf(wd.c_str(), wxT("%i"), &m_ColsInfo[c].width);
m_ColsInfo[c].width = (int)(m_PixelScale * (double)m_ColsInfo[c].width);
m_ColsInfo[c].units = wxHTML_UNITS_PIXELS;
}
}
@ -432,8 +438,8 @@ TAG_HANDLER_BEGIN(TABLE, "TABLE,TR,TD,TH")
oldcont = c = m_WParser -> OpenContainer();
c -> SetWidthFloat(tag);
m_Table = new wxHtmlTableCell(c, tag);
c -> SetWidthFloat(tag, m_WParser -> GetPixelScale());
m_Table = new wxHtmlTableCell(c, tag, m_WParser -> GetPixelScale());
m_OldAlign = m_WParser -> GetAlign();
m_tAlign = wxEmptyString;
if (tag.HasParam("ALIGN")) m_tAlign = tag.GetParam("ALIGN");

View File

@ -244,7 +244,6 @@ wxHtmlContainerCell* wxHtmlWinParser::CloseContainer()
}
wxFont* wxHtmlWinParser::CreateCurrentFont()
{
int fb = GetFontBold(),
@ -256,7 +255,7 @@ wxFont* wxHtmlWinParser::CreateCurrentFont()
if (m_FontsTable[fb][fi][fu][ff][fs] == NULL) {
m_FontsTable[fb][fi][fu][ff][fs] =
new wxFont(
m_FontsSizes[fs],
m_FontsSizes[fs] * m_PixelScale,
ff ? wxMODERN : wxSWISS,
fi ? (ff ? m_ItalicModeFixed : m_ItalicModeNormal) : wxNORMAL,
fb ? wxBOLD : wxNORMAL,