Optimize selecting font in generated PostScript code

Emit code to select PostScript font only if it is needed (not at every call to SetFont(), but only if font has been really changed prior to a text drawing operation).
This commit is contained in:
Artur Wieczorek
2017-03-04 18:54:44 +01:00
parent 8950ac9a3f
commit feee67e6a1
3 changed files with 56 additions and 34 deletions

View File

@@ -139,6 +139,8 @@ protected:
// Common part of DoDrawText() and DoDrawRotatedText() // Common part of DoDrawText() and DoDrawRotatedText()
void DrawAnyText(const wxWX2MBbuf& textbuf, wxCoord testDescent, double lineHeight); void DrawAnyText(const wxWX2MBbuf& textbuf, wxCoord testDescent, double lineHeight);
// Actually set PostScript font
void SetPSFont();
FILE* m_pstream; // PostScript output stream FILE* m_pstream; // PostScript output stream
unsigned char m_currentRed; unsigned char m_currentRed;
@@ -151,6 +153,7 @@ protected:
wxPrintData m_printData; wxPrintData m_printData;
double m_pageHeight; double m_pageHeight;
wxArrayString m_definedPSFonts; wxArrayString m_definedPSFonts;
bool m_isFontChanged;
private: private:
wxDECLARE_DYNAMIC_CLASS(wxPostScriptDCImpl); wxDECLARE_DYNAMIC_CLASS(wxPostScriptDCImpl);

View File

@@ -12,6 +12,13 @@
can write PostScript files on any platform. See wxDC for descriptions of can write PostScript files on any platform. See wxDC for descriptions of
the member functions. the member functions.
@section start_doc Starting a document
Document should be started with call to StartDoc() prior to calling any
function to execute a drawing operation.
However, some functions, like SetFont(), may be legitimately called even
before StartDoc().
@library{wxbase} @library{wxbase}
@category{dc} @category{dc}
*/ */

View File

@@ -323,6 +323,7 @@ void wxPostScriptDCImpl::Init()
m_underlinePosition = 0.0; m_underlinePosition = 0.0;
m_underlineThickness = 0.0; m_underlineThickness = 0.0;
m_isFontChanged = false;
} }
wxPostScriptDCImpl::~wxPostScriptDCImpl () wxPostScriptDCImpl::~wxPostScriptDCImpl ()
@@ -1038,13 +1039,27 @@ void wxPostScriptDCImpl::SetFont( const wxFont& font )
if (!font.IsOk()) return; if (!font.IsOk()) return;
// Note that we may legitimately call SetFont even before BeginDoc.
if ( font == m_font ) // No change
return;
m_font = font; m_font = font;
m_isFontChanged = true;
}
// Actually set PostScript font.
void wxPostScriptDCImpl::SetPSFont()
{
wxASSERT_MSG( m_font.IsOk(), wxS("Font is not yet set") );
if ( !m_isFontChanged )
return;
wxFontStyle Style = m_font.GetStyle(); wxFontStyle Style = m_font.GetStyle();
wxFontWeight Weight = m_font.GetWeight(); wxFontWeight Weight = m_font.GetWeight();
const char *name; wxString name;
switch (m_font.GetFamily()) switch ( m_font.GetFamily() )
{ {
case wxTELETYPE: case wxTELETYPE:
case wxMODERN: case wxMODERN:
@@ -1052,16 +1067,16 @@ void wxPostScriptDCImpl::SetFont( const wxFont& font )
if (Style == wxFONTSTYLE_ITALIC) if (Style == wxFONTSTYLE_ITALIC)
{ {
if (Weight == wxFONTWEIGHT_BOLD) if (Weight == wxFONTWEIGHT_BOLD)
name = "/Courier-BoldOblique"; name = wxS("/Courier-BoldOblique");
else else
name = "/Courier-Oblique"; name = wxS("/Courier-Oblique");
} }
else else
{ {
if (Weight == wxFONTWEIGHT_BOLD) if (Weight == wxFONTWEIGHT_BOLD)
name = "/Courier-Bold"; name = wxS("/Courier-Bold");
else else
name = "/Courier"; name = wxS("/Courier");
} }
break; break;
} }
@@ -1070,22 +1085,22 @@ void wxPostScriptDCImpl::SetFont( const wxFont& font )
if (Style == wxFONTSTYLE_ITALIC) if (Style == wxFONTSTYLE_ITALIC)
{ {
if (Weight == wxFONTWEIGHT_BOLD) if (Weight == wxFONTWEIGHT_BOLD)
name = "/Times-BoldItalic"; name = wxS("/Times-BoldItalic");
else else
name = "/Times-Italic"; name = wxS("/Times-Italic");
} }
else else
{ {
if (Weight == wxFONTWEIGHT_BOLD) if (Weight == wxFONTWEIGHT_BOLD)
name = "/Times-Bold"; name = wxS("/Times-Bold");
else else
name = "/Times-Roman"; name = wxS("/Times-Roman");
} }
break; break;
} }
case wxSCRIPT: case wxSCRIPT:
{ {
name = "/ZapfChancery-MediumItalic"; name = wxS("/ZapfChancery-MediumItalic");
break; break;
} }
case wxSWISS: case wxSWISS:
@@ -1094,42 +1109,37 @@ void wxPostScriptDCImpl::SetFont( const wxFont& font )
if (Style == wxFONTSTYLE_ITALIC) if (Style == wxFONTSTYLE_ITALIC)
{ {
if (Weight == wxFONTWEIGHT_BOLD) if (Weight == wxFONTWEIGHT_BOLD)
name = "/Helvetica-BoldOblique"; name = wxS("/Helvetica-BoldOblique");
else else
name = "/Helvetica-Oblique"; name = wxS("/Helvetica-Oblique");
} }
else else
{ {
if (Weight == wxFONTWEIGHT_BOLD) if (Weight == wxFONTWEIGHT_BOLD)
name = "/Helvetica-Bold"; name = wxS("/Helvetica-Bold");
else else
name = "/Helvetica"; name = wxS("/Helvetica");
} }
break; break;
} }
} }
// We may legitimately call SetFont before BeginDoc wxString buffer;
if (!m_pstream)
return;
// Generate PS code to register the font only once. // Generate PS code to register the font only once.
if ( m_definedPSFonts.Index(name) == wxNOT_FOUND ) if ( m_definedPSFonts.Index(name) == wxNOT_FOUND )
{ {
PsPrint( name ); buffer.Printf( "%s reencodeISO def\n", name.c_str() );
PsPrint( " reencodeISO def\n" ); PsPrint( buffer );
m_definedPSFonts.Add(name); m_definedPSFonts.Add(name);
} }
PsPrint( name );
PsPrint( " findfont\n" );
// Select font
float size = float(m_font.GetPointSize()); float size = (float)m_font.GetPointSize() * GetFontPointSizeAdjustment(DPI);
size = size * GetFontPointSizeAdjustment(DPI); buffer.Printf( "%s findfont %f scalefont setfont\n", name.c_str(), size * m_scaleX );
wxString buffer;
buffer.Printf( "%f scalefont setfont\n", size * m_scaleX );
buffer.Replace( ",", "." ); buffer.Replace( ",", "." );
PsPrint( buffer ); PsPrint( buffer );
m_isFontChanged = false;
} }
void wxPostScriptDCImpl::SetPen( const wxPen& pen ) void wxPostScriptDCImpl::SetPen( const wxPen& pen )
@@ -1425,7 +1435,7 @@ void wxPostScriptDCImpl::DoDrawText( const wxString& text, wxCoord x, wxCoord y
if ( !textbuf ) if ( !textbuf )
return; return;
SetFont( m_font ); SetPSFont();
wxCoord text_descent; wxCoord text_descent;
GetOwner()->GetTextExtent(text, NULL, NULL, &text_descent); GetOwner()->GetTextExtent(text, NULL, NULL, &text_descent);
@@ -1463,7 +1473,7 @@ void wxPostScriptDCImpl::DoDrawRotatedText( const wxString& text, wxCoord x, wxC
if ( !textbuf ) if ( !textbuf )
return; return;
SetFont( m_font ); SetPSFont();
// Calculate bottom-left coordinates of the rotated text // Calculate bottom-left coordinates of the rotated text
wxCoord text_descent; wxCoord text_descent;
@@ -1626,11 +1636,13 @@ void wxPostScriptDCImpl::ComputeScaleAndOrigin()
wxDCImpl::ComputeScaleAndOrigin(); wxDCImpl::ComputeScaleAndOrigin();
// If scale has changed call SetPen to recalculate the line width // If scale has changed call SetPen to recalculate the line width
// and SetFont to recalculate font size // and request for recalculating the font size at nearest opportunity.
if ( wxRealPoint(m_scaleX, m_scaleY) != origScale && m_pen.IsOk() ) if ( wxRealPoint(m_scaleX, m_scaleY) != origScale )
{ {
SetPen( m_pen ); if ( m_pen.IsOk() )
SetFont( m_font ); SetPen( m_pen );
m_isFontChanged = true;
} }
} }