示例#1
0
void wxGraphicsContext::SetPen( const wxPen& pen )
{
    if ( !pen.Ok() || pen.GetStyle() == wxTRANSPARENT )
        SetPen( wxNullGraphicsPen );
    else
        SetPen( CreatePen( pen ) );
}
示例#2
0
wxPen &GetGreyPen(wxPen &pen)
{
	static wxPen p;
	wxColour c;
	p = pen;
	c = MakeColourGrey(pen.GetColour());
	p.SetColour(c);
	return p;
}
示例#3
0
/*****************************************************
**
**   PdfPainter   ---   setPen
**
******************************************************/
void PdfPainter:: setPen( const wxPen &p )
{
	//const double defaultWidth = 1;

	double width = p.GetWidth() * PDF_PEN_PENWIDTH_FACTOR;

	wxPdfLineStyle style;
	switch ( p.GetStyle() )
	{
		case wxDOT:
		{
			wxPdfArrayDouble dash1;
			dash1.Add( .5 );
			style = wxPdfLineStyle( width, wxPDF_LINECAP_NONE, wxPDF_LINEJOIN_MITER, dash1, 10.);
		}
		break;
		case wxLONG_DASH:
		{
			wxPdfArrayDouble dash2;
			dash2.Add( 3 );
			style  = wxPdfLineStyle( width, wxPDF_LINECAP_BUTT, wxPDF_LINEJOIN_MITER, dash2, 0.);
			break;
		}
		break;
		case wxSHORT_DASH:
		{
			wxPdfArrayDouble dash3;
			dash3.Add( 1.5 );
			style  = wxPdfLineStyle( width, wxPDF_LINECAP_BUTT, wxPDF_LINEJOIN_MITER, dash3, 0.);
		}
		case wxDOT_DASH:
		{
			wxPdfArrayDouble dash4;
			dash4.Add( 1.5 );
			dash4.Add( 3 );
			style  = wxPdfLineStyle( width, wxPDF_LINECAP_BUTT, wxPDF_LINEJOIN_MITER, dash4, 0.);
		}
		break;
		default:
		// Noting to do
		break;
	}

	style.SetWidth( width );
	if ( p.GetColour().IsOk() )
	{
		style.SetColour( p.GetColour() );
		pdf->SetDrawColour( p.GetColour());
	}
	pdf->SetLineStyle( style );
}
示例#4
0
文件: genergdi.cpp 项目: Jarlene/mrpt
bool wxGenericPen::IsSameAs(const wxPen &pen) const
{
    wxCHECK_MSG(Ok() && pen.Ok(), false, wxT("Invalid generic pen"));
    wxGenericPen gp(pen);
    gp.GetGenericColour().SetAlpha(M_GPENDATA->m_colour.GetAlpha());
    return IsSameAs(gp);
}
示例#5
0
	wxPen GetStyle() const
	{
		if (!style.IsOk())
			/// @todo Make this colour configurable
			style = wxPen(wxColour(255,0,255), 1);
		return style;
	}
示例#6
0
void wxQtDCImpl::SetPen(const wxPen& pen)
{
    m_pen = pen;

    m_qtPainter->setPen(pen.GetHandle());

    ApplyRasterColourOp();
}
示例#7
0
/*****************************************************
**
**   DcPainter   ---   setPen
**
******************************************************/
void DcPainter::setPen( const wxPen &p )
{
	//printf( "DcPainter::setPen OK %d color OK %d\n", p.IsOk(), p.GetColour().IsOk());
	if ( ! p.IsOk() )
	{
		wxLogError( wxT( "pen not okay, using default pen" ));
		setDefaultPen();
	}
	else dc->SetPen( p );
}
void SjOscRocket::Show(wxDC& dc, long light)
{
	if(m_sleep)
	{
		return;
	}

	if( m_t<m_length )
	{
		int i, j, x, y, maxL;
		double s;

		#define VIEW 20
		maxL = VIEW;
		if( maxL > m_length-m_t )
		{
			maxL = m_length-m_t;
			long intensity = (255/VIEW)*(m_length-m_t);
			if( light > intensity ) intensity = light;
			m_pen.SetColour(intensity, intensity, intensity);
		}

		dc.SetPen(m_pen);

		wxPoint points[VIEW];
		for(i=0; i<m_patch; i++)
		{
			for( j = 0; j < maxL; j++ )
			{
				s=(double)(m_t+j)/100;
				x=(int)(m_vx[i]*s);
				y=(int)(m_vy[i]*s-ROCKET_GRAVITY*s*s);

				points[j].x = m_ox+x;
				points[j].y = m_oy-y;
			}

			dc.DrawLines(maxL, points);
		}

		m_t++;
	}
	else
	{
		m_sleep = TRUE;
	}
}
示例#9
0
文件: genergdi.cpp 项目: Jarlene/mrpt
void wxGenericPen::Set( const wxPen &pen )
{
    wxCHECK_RET(Ok() && pen.Ok(), wxT("Invalid generic pen"));
    SetColour(pen.GetColour());
    M_GPENDATA->m_width = pen.GetWidth();
    M_GPENDATA->m_style = pen.GetStyle();
    M_GPENDATA->m_cap   = pen.GetCap();
    M_GPENDATA->m_join  = pen.GetJoin();

    wxDash* dash;
    int n_dashes = pen.GetDashes(&dash);
    SetDashes(n_dashes, dash);

    // or SetDashes(pen.GetDashCount(), pen.GetDash()); not in msw 2.4
}
示例#10
0
void SjOscRocket::Init(int energy, int patch, int length, long seed, int mx, int my)
{
	int i;

	m_mx        = mx;
	m_my        = my;

	m_energy    = energy;
	m_patch     = patch;
	m_length    = length;
	m_random    = seed;

	m_pen.SetColour(255, 255, 255);

	m_ox=(int)SjTools::Rand(m_mx/2)+m_mx/4;
	m_oy=(int)SjTools::Rand(m_my/2)+m_my/4;

	for(i=0; i<m_patch; i++)
	{
		m_vx[i]=(int)SjTools::Rand(m_energy)-m_energy/2;
		m_vy[i]=(int)SjTools::Rand(m_energy*7/8)-m_energy/8;
	}
}
示例#11
0
// Draws a line between (x1,y1) - (x2,y2) with a start thickness of t1
void DrawThickLine( double x1, double y1, double x2, double y2, wxPen pen, bool b_hiqual )
{
    double angle = atan2( y2 - y1, x2 - x1 );
    double t1 = pen.GetWidth();
    double t2sina1 = t1 / 2 * sin( angle );
    double t2cosa1 = t1 / 2 * cos( angle );

    glPushAttrib( GL_COLOR_BUFFER_BIT | GL_HINT_BIT | GL_POLYGON_BIT );      //Save state
    ocpnDC::SetGLAttrs( b_hiqual );

    //    n.b.  The dwxDash interpretation for GL only allows for 2 elements in the dash table.
    //    The first is assumed drawn, second is assumed space
    wxDash *dashes;
    int n_dashes = pen.GetDashes( &dashes );
    if( n_dashes ) {
        double lpix = sqrt( ( x1 - x2 ) * ( x1 - x2 ) + ( y1 - y2 ) * ( y1 - y2 ) );
        double lrun = 0.;
        double xa = x1;
        double ya = y1;
        double ldraw = t1 * dashes[0];
        double lspace = t1 * dashes[1];

        while( lrun < lpix ) {
            //    Dash
            double xb = xa + ldraw * cos( angle );
            double yb = ya + ldraw * sin( angle );

            if( ( lrun + ldraw ) >= lpix )         // last segment is partial draw
                    {
                xb = x2;
                yb = y2;
            }

            glBegin( GL_TRIANGLES );
            glVertex2f( xa + t2sina1, ya - t2cosa1 );
            glVertex2f( xb + t2sina1, yb - t2cosa1 );
            glVertex2f( xb - t2sina1, yb + t2cosa1 );

            glVertex2f( xb - t2sina1, yb + t2cosa1 );
            glVertex2f( xa - t2sina1, ya + t2cosa1 );
            glVertex2f( xa + t2sina1, ya - t2cosa1 );
            glEnd();

            xa = xb;
            ya = yb;
            lrun += ldraw;

            //    Space
            xb = xa + lspace * cos( angle );
            yb = ya + lspace * sin( angle );

            xa = xb;
            ya = yb;
            lrun += lspace;
        }
    } else {
        glBegin( GL_TRIANGLES );
        glVertex2f( x1 + t2sina1, y1 - t2cosa1 );
        glVertex2f( x2 + t2sina1, y2 - t2cosa1 );
        glVertex2f( x2 - t2sina1, y2 + t2cosa1 );
        glVertex2f( x2 - t2sina1, y2 + t2cosa1 );
        glVertex2f( x1 - t2sina1, y1 + t2cosa1 );
        glVertex2f( x1 + t2sina1, y1 - t2cosa1 );
        glEnd();
    }
    glPopAttrib();
}
示例#12
0
void ThemeBase::SetPenColour(   wxPen & Pen, int iIndex )
{
   wxASSERT( iIndex >= 0 );
   Pen.SetColour( Colour( iIndex ));
}
示例#13
0
bool SjOscStar::Draw(wxDC& dc, const wxSize& clientSize, double rot, wxPen& pen, wxBrush& brush)
{
	double  xfloat, yfloat;
	int     x, y, hh, vv;
	int     d, intensity;

	m_z -= 2;
	if( m_z < -63 )
	{
		m_z = STAR_DEPTH;
		m_doDraw = !m_exitRequest;
	}

	hh = (m_x*64)/(64+m_z);
	vv = (m_y*64)/(64+m_z);

	// check position
	x = hh + 500;
	y = vv + 500;
	if( x < -300 || x > 1300 || y < -300 || y > 1300 )
	{
		m_z = STAR_DEPTH;
		m_doDraw = !m_exitRequest;

		hh = (m_x*64)/(64+m_z);
		vv = (m_y*64)/(64+m_z);
	}

	// calculate position
	xfloat = (hh*cos(rot))-(vv*sin(rot));
	yfloat = (hh*sin(rot))+(vv*cos(rot));

	x = (int)xfloat + 500;
	y = (int)yfloat + 500;

	// use star?
	if( !m_doDraw )
	{
		if( m_exitRequest || x < 450 || x > 550 || y < 450 || y > 550 )
		{
			return FALSE;
		}
		else
		{
			m_doDraw = TRUE;
		}
	}

	// map star position to client size, keep aspect ratio
	d = clientSize.x;
	if( clientSize.y > d )
	{
		d = clientSize.y;
	}

	if( d == 0 )
	{
		d = 10;
	}

	x = (x * d) / 1000 - (d-clientSize.x)/2;
	y = (y * d) / 1000 - (d-clientSize.y)/2;

	// calculate size
	d = (STAR_DEPTH-m_z) / (38400/d);
	if( d == 0 ) d = 1;

	// calculate light intensity
	intensity = STAR_DEPTH-m_z;
	intensity = 55 + ((intensity * 200) / STAR_DEPTH);
	//if( intensity < light ) intensity = light + 10;
	if( intensity < 0   )   intensity = 0;
	if( intensity > 255 )   intensity = 255;

	// draw star
	if( d==1 )
	{
		pen.SetColour(intensity, intensity, intensity);
		dc.SetPen(pen);
		dc.DrawPoint(x, y);
	}
	else
	{
		dc.SetPen(*wxTRANSPARENT_PEN);

		brush.SetColour(intensity, intensity, intensity);
		dc.SetBrush(brush);

		dc.DrawRectangle(x, y, d, d);
	}

	return TRUE;
}
示例#14
0
	virtual void SetPen(const wxPen& pen) override {
		wxPen newpen = pen;
		newpen.SetColour(PivotColour(pen.GetColour()));
		wxMirrorDC::SetPen(newpen);
	}
示例#15
0
void SjOscHands::Draw(wxDC& dc, const wxSize& clientSize,
                      long volume, long light, bool newTitle)
{
	long i, offset;

	// (re-)calculate log. hand data
	if( m_logHandMode == HAND_MODE_NOP )
	{
		m_pause--;

		if( m_pause <= 0 // about once in 90 seconds or every 4 titles
		        || (newTitle && !m_firstTitle && SjTools::Rand(4) == 0) )
		{
			for( i = 0; i < MAX_HANDS; i++ )
			{
				m_logHandsPos[i].x = i*(1024/MAX_HANDS)+SjTools::Rand((1024/MAX_HANDS)-HAND_W/2);
				m_logHandsPos[i].y = ((768-HAND_H) + 10) - SjTools::Rand(20);
				m_logHandRnd[i]    = 5-SjTools::Rand(10);
				if( m_logHandRnd[i] == 0 ) m_logHandRnd[i] = 1;
			}
			m_logHandMode = HAND_MODE_FADEIN;
			m_logHandModeData = HAND_H+volume;
			m_pause = (10000+SjTools::Rand(90000))/SLEEP_MS;
			offset = m_logHandModeData;
			m_firstTitle = FALSE;
		}
		else
		{
			if( newTitle ) m_firstTitle = FALSE;
			return;
		}
	}
	else if( m_logHandMode == HAND_MODE_FADEIN )
	{
		m_logHandModeData--;
		offset = m_logHandModeData;

		if( m_logHandModeData == 0 )
		{
			m_logHandMode = HAND_MODE_DO;
			m_logHandModeData = (10000 + SjTools::Rand(50000)) / SLEEP_MS; // 10-60 seconds
		}
	}
	else if( m_logHandMode == HAND_MODE_DO )
	{
		m_logHandModeData--;
		offset = 0;

		if( m_logHandModeData == 0
		        || (newTitle && SjTools::Rand(4)==0) )
		{
			m_logHandMode = HAND_MODE_FADEOUT;
			m_logHandModeData = (HAND_H+80);
		}
	}
	else if( m_logHandMode == HAND_MODE_FADEOUT )
	{
		m_logHandModeData--;
		offset = (HAND_H+80) - m_logHandModeData;

		if( m_logHandModeData == 0 )
		{
			m_logHandMode = HAND_MODE_NOP;
			return;
		}
	}

	// calculate a hand for the given screen resolution
	wxPoint scrHandPoints[19];
	for( i = 0; i < HAND_POINTS; i++ )
	{
		scrHandPoints[i].x = (s_logHandPoints[i*2  ] * clientSize.x) / 1024;
		scrHandPoints[i].y = (s_logHandPoints[i*2+1] * clientSize.x) / 1024/*not:768*/;
	}

	// draw the hands
	long intensity = 42+light;
	if( intensity < 70 ) intensity = 70;
	if( intensity > 255 ) intensity = 255;
	m_pen.SetColour(intensity, intensity, intensity);

	dc.SetPen(m_pen);

	for( i = 0; i < MAX_HANDS; i++ )
	{
		dc.DrawLines(HAND_POINTS, scrHandPoints,
		             (m_logHandsPos[i].x * clientSize.x) / 1024,
		             offset + (((m_logHandsPos[i].y * clientSize.y) / 768) - volume/m_logHandRnd[i]));
	}
}
示例#16
0
文件: ocpndc.cpp 项目: libai245/wht1
// Draws a line between (x1,y1) - (x2,y2) with a start thickness of t1
void DrawGLThickLine( float x1, float y1, float x2, float y2, wxPen pen, bool b_hiqual )
{
#ifdef ocpnUSE_GL
    
    float angle = atan2f( y2 - y1, x2 - x1 );
    float t1 = pen.GetWidth();
    float t2sina1 = t1 / 2 * sinf( angle );
    float t2cosa1 = t1 / 2 * cosf( angle );

    glBegin( GL_TRIANGLES );

    //    n.b.  The dwxDash interpretation for GL only allows for 2 elements in the dash table.
    //    The first is assumed drawn, second is assumed space
    wxDash *dashes;
    int n_dashes = pen.GetDashes( &dashes );
    if( n_dashes ) {
        float lpix = sqrtf( powf( (float) (x1 - x2), 2) + powf( (float) (y1 - y2), 2) );
        float lrun = 0.;
        float xa = x1;
        float ya = y1;
        float ldraw = t1 * dashes[0];
        float lspace = t1 * dashes[1];

        while( lrun < lpix ) {
            //    Dash
            float xb = xa + ldraw * cosf( angle );
            float yb = ya + ldraw * sinf( angle );

            if( ( lrun + ldraw ) >= lpix )         // last segment is partial draw
            {
                xb = x2;
                yb = y2;
            }

            glVertex2f( xa + t2sina1, ya - t2cosa1 );
            glVertex2f( xb + t2sina1, yb - t2cosa1 );
            glVertex2f( xb - t2sina1, yb + t2cosa1 );

            glVertex2f( xb - t2sina1, yb + t2cosa1 );
            glVertex2f( xa - t2sina1, ya + t2cosa1 );
            glVertex2f( xa + t2sina1, ya - t2cosa1 );

            xa = xb;
            ya = yb;
            lrun += ldraw;

            //    Space
            xb = xa + lspace * cos( angle );
            yb = ya + lspace * sin( angle );

            xa = xb;
            ya = yb;
            lrun += lspace;
        }
    } else {
        glVertex2f( x1 + t2sina1, y1 - t2cosa1 );
        glVertex2f( x2 + t2sina1, y2 - t2cosa1 );
        glVertex2f( x2 - t2sina1, y2 + t2cosa1 );

        glVertex2f( x2 - t2sina1, y2 + t2cosa1 );
        glVertex2f( x1 - t2sina1, y1 + t2cosa1 );
        glVertex2f( x1 + t2sina1, y1 - t2cosa1 );

        /* wx draws a nice rounded end in dc mode, so replicate
           this for opengl mode, should this be done for the dashed mode case? */
        if(pen.GetCap() == wxCAP_ROUND) {
            DrawEndCap( x1, y1, t1, angle);
            DrawEndCap( x2, y2, t1, angle + M_PI);
        }

    }

    glEnd();
#endif    
}
示例#17
0
void SjOscRotor::Draw(wxDC& dc, const wxSize& clientSize, bool otherRunning, bool newTitle, long volume, long light)
{
	if( m_mode == ROTOR_MODE_NOP )
	{
		m_pause--;

		if( (m_pause <= 0 && !otherRunning) ) // about once in two minutes
		{
			m_mode          = ROTOR_MODE_FADEIN;
			m_logCenterX    = SjTools::Rand(100);
			m_logCenterY    = SjTools::Rand(100);
			m_logColour     = 0;
			m_delta         = 0;
			m_logDo         = (10000 + SjTools::Rand(50000)) / SLEEP_MS; // 10-60 seconds
			m_pause         = SjTools::Rand(ROTOR_SLEEP_MS/SLEEP_MS);
			m_followVolume  = SjTools::Rand(2)==0;
		}

		return;
	}
	else if( m_mode == ROTOR_MODE_FADEIN )
	{
		m_logColour++;

		long intensity = m_logColour;
		if( light > intensity ) intensity = light;
		m_pen.SetColour(intensity, intensity, intensity);

		if( m_logColour == 255 )
		{
			m_pen.SetColour(255, 255, 255);
			m_mode = ROTOR_MODE_DO;
		}
	}
	else if( m_mode == ROTOR_MODE_DO )
	{
		m_logDo--;
		if( m_logDo <= 0 || newTitle || otherRunning )
		{
			m_logDo = 0;
			m_mode = ROTOR_MODE_FADEOUT;
			if( newTitle || otherRunning )
			{
				m_mode = ROTOR_MODE_FADEOUTFAST;
				if( SjTools::Rand(2) == 0 && !otherRunning )
				{
					m_pause = 0;
				}
			}
		}
	}
	else if( m_mode == ROTOR_MODE_FADEOUT || m_mode == ROTOR_MODE_FADEOUTFAST )
	{
		m_logColour -= m_mode == ROTOR_MODE_FADEOUT? 1 : 3;
		if( m_logColour < 0 ) m_logColour = 0;

		long intensity = m_logColour;
		if( light > intensity ) intensity = light;

		m_pen.SetColour(intensity, intensity, intensity);
		if( m_logColour == 0 )
		{
			m_mode = ROTOR_MODE_NOP;
		}
	}

	if( m_followVolume )
	{
		double add = 0.001*volume;
		if( add < 0.005 ) add = 0.005;
		m_delta += add;
	}
	else
	{
		m_delta += 0.01;
	}

	if( m_delta >= PI )
	{
		m_delta -= PI;
	}

	int centerx = (clientSize.x*m_logCenterX) / 100,
	    centery = (clientSize.y*m_logCenterY) / 150/*not:100 - center is not in the lower part*/;
	int radius = (clientSize.x+clientSize.y)*2;

	dc.SetPen(m_pen);

	dc.DrawLine(centerx+sin(m_delta         )*radius, centery+cos(m_delta         )*radius,
	            centerx+sin(m_delta+PI      )*radius, centery+cos(m_delta+PI      )*radius);
	dc.DrawLine(centerx+sin(m_delta+PI/2    )*radius, centery+cos(m_delta+PI/2    )*radius,
	            centerx+sin(m_delta+PI/2+PI )*radius, centery+cos(m_delta+PI/2+PI )*radius);
}
示例#18
0
文件: ocpndc.cpp 项目: libai245/wht1
// Draws thick lines from triangles
void DrawGLThickLines( int n, wxPoint points[],wxCoord xoffset,
                       wxCoord yoffset, wxPen pen, bool b_hiqual )
{
#ifdef ocpnUSE_GL
    if(n < 2)
        return;

    /* for dashed case, for now just draw thick lines */
    wxDash *dashes;
    if( pen.GetDashes( &dashes ) )
    {
        wxPoint p0 = points[0];
        for( int i = 1; i < n; i++ ) {
            DrawGLThickLine( p0.x + xoffset, p0.y + yoffset, points[i].x + xoffset,
                             points[i].y + yoffset, pen, b_hiqual );
            p0 = points[i];
        }
        return;
    }

    /* cull zero segments */
    wxPoint *cpoints = new wxPoint[n];
    cpoints[0] = points[0];
    int c = 1;
    for( int i = 1; i < n; i++ ) {
        if(points[i].x != points[i-1].x || points[i].y != points[i-1].y)
            cpoints[c++] = points[i];
    }

    /* nicer than than rendering each segment separately, this is because thick
       line segments drawn as rectangles which have different angles have
       rectangles which overlap and also leave a gap.
       This code properly calculates vertexes for adjoining segments */
    float t1 = pen.GetWidth();

    float x0 = cpoints[0].x, y0 = cpoints[0].y, x1 = cpoints[1].x, y1 = cpoints[1].y;
    float a0 = atan2f( y1 - y0, x1 - x0 );

    // It is also possible to use triangle strip, (and triangle fan for endcap)
    // to reduce vertex count.. is it worth it?
    glBegin( GL_TRIANGLES );

    float t2sina0 = t1 / 2 * sinf( a0 );
    float t2cosa0 = t1 / 2 * cosf( a0 );

    for( int i = 1; i < c; i++ ) {
        float x2, y2;
        float a1;

        if(i < c - 1) {
            x2 = cpoints[i + 1].x, y2 = cpoints[i + 1].y;
            a1 = atan2f( y2 - y1, x2 - x1 );
        } else {
            x2 = x1, y2 = y1;
            a1 = a0;
        }

        float aa = (a0 + a1) / 2;
        float diff = fabsf(a0 - a1);
        if(diff > M_PI)
            diff -= 2 * (float)M_PI;
        float rad = t1 / 2 / wxMax(cosf(diff / 2), .4);

        float t2sina1 = rad * sinf( aa );
        float t2cosa1 = rad * cosf( aa );

        glVertex2f( x1 + t2sina1, y1 - t2cosa1 );
        glVertex2f( x1 - t2sina1, y1 + t2cosa1 );
        glVertex2f( x0 + t2sina0, y0 - t2cosa0 );

        glVertex2f( x0 - t2sina0, y0 + t2cosa0 );
        glVertex2f( x0 + t2sina0, y0 - t2cosa0 );

        float dot = t2sina0 * t2sina1 + t2cosa0 * t2cosa1;
        if(dot > 0)
            glVertex2f( x1 - t2sina1, y1 + t2cosa1 );
        else
            glVertex2f( x1 + t2sina1, y1 - t2cosa1 );

        x0 = x1, x1 = x2;
        y0 = y1, y1 = y2;
        a0 = a1;
        t2sina0 = t2sina1, t2cosa0 = t2cosa1;
    }
 
    if(pen.GetCap() == wxCAP_ROUND) {
        DrawEndCap( x0, y0, t1, a0);
        DrawEndCap( x0, y0, t1, a0 + M_PI);
     }

    glEnd();

    glPopAttrib();

    delete [] cpoints;

 #endif    
 }
示例#19
0
wxString xsPenPropIO::ToString(wxPen value)
{
    return wxString::Format(wxT("%s %d %d"), xsColourPropIO::ToString(value.GetColour()).c_str(), value.GetWidth(), value.GetStyle());
}
示例#20
0
文件: dc.cpp 项目: hgwells/tive
void wxDC::SetPen(const wxPen& pen)
{
    m_pen = pen.Ok() ? pen : DEFAULT_PEN;

    SelectColour(m_pen.GetColour());
}