Skip to content

Commit

Permalink
Support multiline strings in wxPostScriptDC::DrawText() and DrawRotat…
Browse files Browse the repository at this point in the history
…edText()

'show' operator in PostScript doesn't support printing newlines, so we need to split the string into lines manually and print each line separately.

Closes wxWidgets#17798.
  • Loading branch information
a-wi committed Feb 11, 2017
1 parent 506b51c commit 8e47b3c
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 13 deletions.
2 changes: 1 addition & 1 deletion include/wx/generic/dcpsg.h
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ class WXDLLIMPEXP_CORE wxPostScriptDCImpl : public wxDCImpl
void DoGetSizeMM(int *width, int *height) const wxOVERRIDE;

// Common part of DoDrawText() and DoDrawRotatedText()
void DrawAnyText(const wxWX2MBbuf& textbuf, wxCoord testDescent);
void DrawAnyText(const wxWX2MBbuf& textbuf, wxCoord testDescent, double lineHeight);

FILE* m_pstream; // PostScript output stream
unsigned char m_currentRed;
Expand Down
50 changes: 38 additions & 12 deletions src/generic/dcpsg.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,19 @@ static const char wxPostScriptHeaderReencodeISO2[] =
"/yacute/thorn/ydieresis\n"
"] def\n\n";

// Split multiline string and store each line in the array.
static const char *wxPostScriptHeaderStrSplit =
"/strsplit {\n" // str delim
" [ 3 1 roll\n" // [ str delim
" {\n" // [ str-items str delim
" search {\n" // [ str-items post match pre
" 3 1 roll\n" // [ str-items pre post match => [ str-items new-item remaining-str delim
" }{\n" // [ str-items str
" exit\n" // [ str-items str => exit from loop
" }ifelse\n"
" }loop\n" // [ str-items
" ]\n" // [ str-items ]
"} def\n";
//-------------------------------------------------------------------------------
// wxPostScriptDC
//-------------------------------------------------------------------------------
Expand Down Expand Up @@ -1310,7 +1323,7 @@ void wxPostScriptDCImpl::SetBrush( const wxBrush& brush )
}

// Common part of DoDrawText() and DoDrawRotatedText()
void wxPostScriptDCImpl::DrawAnyText(const wxWX2MBbuf& textbuf, wxCoord textDescent)
void wxPostScriptDCImpl::DrawAnyText(const wxWX2MBbuf& textbuf, wxCoord textDescent, double lineHeight)
{
wxCHECK_RET( textbuf, wxS("Invalid text buffer") );

Expand Down Expand Up @@ -1373,8 +1386,15 @@ void wxPostScriptDCImpl::DrawAnyText(const wxWX2MBbuf& textbuf, wxCoord textDesc
PsPrint( (char) c );
}
}
PsPrint( ")\n" );
PsPrint( ")" );

// Split multiline text and store individual lines in the array.
PsPrint( " (\\n) strsplit\n" );

// Print each line individually by fetching lines from the array
PsPrint( "{\n" );
// Preserve current point.
PsPrint( " currentpoint 3 -1 roll\n" ); // x y (str)
if (m_font.GetUnderlined())
{
// We need relative underline position
Expand All @@ -1383,19 +1403,24 @@ void wxPostScriptDCImpl::DrawAnyText(const wxWX2MBbuf& textbuf, wxCoord textDesc
// uy = by + text_descent - m_underlinePosition =>
// dy = -(text_descent - m_underlinePosition)
// It's negated due to the orientation of Y-axis.
buffer.Printf( "gsave\n"
"0.0 %f rmoveto\n"
"%f setlinewidth\n"
"dup stringwidth rlineto\n"
"stroke\n"
"grestore\n",
buffer.Printf( " gsave\n"
" 0.0 %f rmoveto\n"
" %f setlinewidth\n"
" dup stringwidth rlineto\n"
" stroke\n"
" grestore\n",
-YLOG2DEVREL(textDescent - m_underlinePosition),
m_underlineThickness );
buffer.Replace( ",", "." );
PsPrint( buffer );
}

PsPrint("show\n");
PsPrint( " show\n" ); // x y
// Advance to the beginning of th next line.
buffer.Printf( " %f add moveto\n", -YLOG2DEVREL(lineHeight) );
buffer.Replace( ",", "." );
PsPrint( buffer );
// Execute above statements for all elements of the array
PsPrint( "} forall\n" );
}

void wxPostScriptDCImpl::DoDrawText( const wxString& text, wxCoord x, wxCoord y )
Expand All @@ -1422,7 +1447,7 @@ void wxPostScriptDCImpl::DoDrawText( const wxString& text, wxCoord x, wxCoord y
buffer.Replace( ",", "." );
PsPrint( buffer );

DrawAnyText(textbuf, text_descent);
DrawAnyText(textbuf, text_descent, size);

CalcBoundingBox( x, y );
CalcBoundingBox( x + size * text.length() * 2/3 , y );
Expand Down Expand Up @@ -1461,7 +1486,7 @@ void wxPostScriptDCImpl::DoDrawRotatedText( const wxString& text, wxCoord x, wxC
buffer.Replace( ",", "." );
PsPrint( buffer );

DrawAnyText(textbuf, text_descent);
DrawAnyText(textbuf, text_descent, size);

buffer.Printf( "%f rotate\n", -angle );
buffer.Replace( ",", "." );
Expand Down Expand Up @@ -1737,6 +1762,7 @@ bool wxPostScriptDCImpl::StartDoc( const wxString& WXUNUSED(message) )
PsPrint( wxPostScriptHeaderReencodeISO2 );
if (wxPostScriptHeaderSpline)
PsPrint( wxPostScriptHeaderSpline );
PsPrint( wxPostScriptHeaderStrSplit );
PsPrint( "%%EndProlog\n" );

SetBrush( *wxBLACK_BRUSH );
Expand Down

0 comments on commit 8e47b3c

Please sign in to comment.