39 #include <wx/string.h>
43 #if wxUSE_GRAPHICS_CONTEXT
57 wxPLDevGC::~wxPLDevGC()
65 ( (wxMemoryDC *) m_dc )->SelectObject( wxNullBitmap );
77 void wxPLDevGC::DrawLine(
short x1a,
short y1a,
short x2a,
short y2a )
81 wxDouble x1 = x1a / scalex;
82 wxDouble y1 = height - y1a / scaley;
83 wxDouble x2 = x2a / scalex;
84 wxDouble y2 = height - y2a / scaley;
86 wxGraphicsPath path = m_context->CreatePath();
87 path.MoveToPoint( x1, y1 );
88 path.AddLineToPoint( x2, y2 );
89 m_context->StrokePath( path );
91 AddtoClipRegion( (
int) x1, (
int) y1, (
int) x2, (
int) y2 );
95 void wxPLDevGC::DrawPolyline(
short *xa,
short *ya,
PLINT npts )
99 wxGraphicsPath path = m_context->CreatePath();
100 path.MoveToPoint( xa[0] / scalex, height - ya[0] / scaley );
101 for (
PLINT i = 1; i < npts; i++ )
102 path.AddLineToPoint( xa[i] / scalex, height - ya[i] / scaley );
103 m_context->StrokePath( path );
106 path.GetBox( &x, &y, &w, &h );
107 AddtoClipRegion( (
int) x, (
int) y, (
int) ( x + w ), (
int) ( y + h ) );
115 wxDouble x1a, y1a, x2a, y2a;
124 y1a = height - y1 / scaley;
132 y2a = height - y2 / scaley;
134 m_context->SetPen( *( wxThePenList->FindOrCreatePen( wxColour( bgr, bgg, bgb ), 1, wxSOLID ) ) );
135 m_context->SetBrush( wxBrush( wxColour( bgr, bgg, bgb ) ) );
136 m_context->DrawRectangle( x1a, y1a, x2a - x1a, y2a - y1a );
138 m_context->SetPen( *( wxThePenList->FindOrCreatePen( wxColour( mColorRedStroke, mColorGreenStroke,
139 mColorBlueStroke, mStrokeOpacity ),
141 m_context->SetBrush( wxBrush( wxColour( mColorRedFill, mColorGreenFill, mColorBlueFill, mStrokeOpacity ) ) );
143 AddtoClipRegion( (
int) x1a, (
int) y1a, (
int) x2a, (
int) y2a );
147 void wxPLDevGC::FillPolygon(
PLStream *pls )
152 short* x = pls->
dev_x;
153 short* y = pls->
dev_y;
157 if ( x[0] == x[1] && x[2] == x[3] && y[0] == y[3] && y[1] == y[2] )
159 else if ( x[0] == x[3] && x[1] == x[2] && y[0] == y[1] && y[2] == y[3] )
164 if ( x[0] == x[4] && y[0] == y[4] )
166 if ( x[0] == x[1] && x[2] == x[3] && y[0] == y[3] && y[1] == y[2] )
168 else if ( x[0] == x[3] && x[1] == x[2] && y[0] == y[1] && y[2] == y[3] )
175 double x1, y1, x2, y2, x0, y0, w, h;
179 y1 = height - y[0] / scaley;
180 y2 = height - y[2] / scaley;
202 m_context->DrawRectangle( x0, y0, w, h );
203 AddtoClipRegion( (
int) x0, (
int) y0, (
int) w, (
int) h );
207 wxGraphicsPath path = m_context->CreatePath();
208 path.MoveToPoint( x[0] / scalex, height - y[0] / scaley );
209 for (
int i = 1; i < pls->
dev_npts; i++ )
210 path.AddLineToPoint( x[i] / scalex, height - y[i] / scaley );
214 m_context->DrawPath( path, wxODDEVEN_RULE );
216 m_context->DrawPath( path, wxWINDING_RULE );
219 path.GetBox( &x, &y, &w, &h );
221 AddtoClipRegion( (
int) x, (
int) y, (
int) ( x + w ), (
int) ( y + h ) );
226 void wxPLDevGC::BlitRectangle( wxDC* dc,
int vX,
int vY,
int vW,
int vH )
231 dc->Blit( vX, vY, vW, vH, m_dc, vX, vY );
235 void wxPLDevGC::CreateCanvas()
242 m_dc =
new wxMemoryDC();
244 ( (wxMemoryDC *) m_dc )->SelectObject( wxNullBitmap );
247 m_bitmap =
new wxBitmap( bm_width, bm_height, 32 );
248 ( (wxMemoryDC *) m_dc )->SelectObject( *m_bitmap );
254 m_context = wxGraphicsContext::Create( *( (wxMemoryDC *) m_dc ) );
259 void wxPLDevGC::SetWidth(
PLStream *pls )
263 m_context->SetPen( *( wxThePenList->FindOrCreatePen( wxColour( mColorRedStroke, mColorGreenStroke,
264 mColorBlueStroke, mStrokeOpacity ),
265 pls->
width > 0 ? pls->
width : 1, wxSOLID ) ) );
269 void wxPLDevGC::SetColor0(
PLStream *pls )
279 mStrokeOpacity = (
unsigned char) ( pls->
curcolor.
a * 255 );
281 m_context->SetPen( *( wxThePenList->FindOrCreatePen( wxColour( mColorRedStroke, mColorGreenStroke,
282 mColorBlueStroke, mStrokeOpacity ),
283 pls->
width > 0 ? pls->
width : 1, wxSOLID ) ) );
284 m_context->SetBrush( wxBrush( wxColour( mColorRedFill, mColorGreenFill, mColorBlueFill, mStrokeOpacity ) ) );
288 void wxPLDevGC::SetColor1(
PLStream *pls )
298 mStrokeOpacity = (
unsigned char) ( pls->
curcolor.
a * 255 );
300 m_context->SetPen( *( wxThePenList->FindOrCreatePen( wxColour( mColorRedStroke, mColorGreenStroke,
301 mColorBlueStroke, mStrokeOpacity ),
302 pls->
width > 0 ? pls->
width : 1, wxSOLID ) ) );
303 m_context->SetBrush( wxBrush( wxColour( mColorRedFill, mColorGreenFill, mColorBlueFill, mStrokeOpacity ) ) );
313 void wxPLDevGC::SetExternalBuffer(
void* dc )
318 m_context = wxGraphicsContext::Create( *( (wxMemoryDC *) m_dc ) );
324 #ifdef PL_HAVE_FREETYPE
326 void wxPLDevGC::PutPixel(
short x,
short y,
PLINT color )
330 const wxPen oldpen = m_dc->GetPen();
331 m_context->SetPen( *( wxThePenList->FindOrCreatePen( wxColour( GetRValue( color ), GetGValue( color ), GetBValue( color ) ),
334 AddtoClipRegion( x, y, x, y );
335 m_context->SetPen( oldpen );
338 void wxPLDevGC::PutPixel(
short x,
short y )
343 AddtoClipRegion( x, y, x, y );
346 PLINT wxPLDevGC::GetPixel(
short x,
short y )
358 return RGB( bgr, bgg, bgb );
361 m_dc->GetPixel( x, y, &col );
362 return RGB( col.Red(), col.Green(), col.Blue() );
366 #endif // PL_HAVE_FREETYPE
369 void wxPLDevGC::PSDrawTextToDC(
char* utf8_string,
bool drawText )
375 wxString str( wxConvUTF8.cMB2WC( utf8_string ), *wxConvCurrent );
378 m_context->GetTextExtent( str, &w, &h, &d, &l );
382 m_context->DrawText( str, 0, -yOffset / scaley );
383 m_context->Translate( w, 0 );
386 textWidth +=
static_cast<int>( w );
390 if ( yOffset > 0.0001 )
393 double currentOffset = yOffset;
394 double currentHeight = h;
395 while ( currentOffset > 0.0001 )
397 currentOffset -= scaley * fontSize * fontScale / 2.;
398 currentHeight *= 1.25;
400 textHeight = textHeight > ( currentHeight )
402 : static_cast<int>( ( currentHeight ) );
404 superscriptHeight = superscriptHeight > ( currentHeight + yOffset / scaley )
406 : static_cast<int>( ( currentHeight + yOffset / scaley ) );
408 else if ( yOffset < -0.0001 )
411 double currentOffset = yOffset;
412 double currentHeight = h;
413 double currentDepth = d;
414 while ( currentOffset < -0.0001 )
416 currentOffset += scaley * fontSize * fontScale * 1.25 / 2.;
417 currentHeight *= 1.25;
418 currentDepth *= 1.25;
420 textHeight = textHeight > currentHeight ? textHeight :
static_cast<int>( ( currentHeight ) );
425 subscriptDepth = subscriptDepth > ( ( -yOffset / scaley + h + d ) - ( currentDepth + textHeight ) )
427 : static_cast<int>( ( -yOffset / scaley + h + d ) - ( currentDepth + textHeight ) );
428 subscriptDepth = subscriptDepth > 0 ? subscriptDepth : 0;
431 textHeight = textHeight > h ? textHeight :
static_cast<int>( h );
433 memset( utf8_string,
'\0', max_string_length );
437 void wxPLDevGC::PSSetFont(
PLUNICODE fci )
441 unsigned char fontFamily, fontStyle, fontWeight;
448 m_font = wxFont::New( static_cast<int>( fontSize * fontScale ),
451 m_font->SetUnderlined( underlined );
452 m_context->SetFont( *m_font, wxColour( textRed, textGreen, textBlue ) );
463 printf(
"Non unicode string passed to a cairo driver, ignoring\n" );
470 printf(
"Sorry, the wxWidgets drivers only handles strings of length < %d\n", max_string_length );
478 PLINT rcx[4], rcy[4];
481 #ifdef __WXOSX_COCOA__
482 wxPoint topLeft( width, height ), bottomRight( -1, -1 );
483 for (
int i = 0; i < 4; i++ )
485 topLeft.x = topLeft.x > ( rcx[i] / scalex ) ? ( rcx[i] / scalex ) : topLeft.x;
486 topLeft.y = topLeft.y > ( height - rcy[i] / scaley ) ? ( height - rcy[i] / scaley ) : topLeft.y;
487 bottomRight.x = bottomRight.x < ( rcx[i] / scalex ) ? ( rcx[i] / scalex ) : bottomRight.x;
488 bottomRight.y = bottomRight.y < ( height - rcy[i] / scaley ) ? ( height - rcy[i] / scaley ) : bottomRight.y;
491 m_context->Clip( wxRegion( topLeft.x, topLeft.y, bottomRight.x - topLeft.x, bottomRight.y - topLeft.y ) );
495 for (
int i = 0; i < 4; i++ )
497 cpoints[i].x = rcx[i] / scalex;
498 cpoints[i].y = height - rcy[i] / scaley;
500 m_context->Clip( wxRegion( 4, cpoints ) );
511 cos_rot = cos( rotation );
512 sin_rot = sin( rotation );
513 cos_shear = cos( shear );
514 sin_shear = sin( shear );
519 bool lineFeed =
false;
520 bool carriageReturn =
false;
521 wxCoord paraHeight = 0;
530 && *( lineStart + lineLen ) != (
PLUNICODE)
'\n' )
536 lineFeed = carriageReturn;
538 && *( lineStart + lineLen ) == (
PLUNICODE) (
'\n' );
540 paraHeight += textHeight + subscriptDepth;
543 double startingFontScale = fontScale;
544 double startingYOffset = yOffset;
548 PSDrawText( lineStart, lineLen,
false );
550 if ( lineFeed && superscriptHeight > textHeight )
551 paraHeight += superscriptHeight - textHeight;
554 fontScale = startingFontScale;
555 yOffset = startingYOffset;
558 m_context->PushState();
559 m_context->Translate( args->
x / scalex, height - args->
y / scaley );
560 wxGraphicsMatrix matrix = m_context->CreateMatrix(
561 cos_rot * stride, -sin_rot * stride,
562 cos_rot * sin_shear + sin_rot * cos_shear,
563 -sin_rot * sin_shear + cos_rot * cos_shear,
565 m_context->ConcatTransform( matrix );
566 m_context->Translate( -args->
just * textWidth, -0.5 * textHeight + paraHeight * lineSpacing );
567 PSDrawText( lineStart, lineLen,
true );
568 m_context->PopState();
570 lineStart += lineLen;
571 if ( carriageReturn )
577 AddtoClipRegion( 0, 0, width, height );
579 m_context->ResetClip();