⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dccg.cpp

📁 Wxpython Implemented on Windows CE, Source code
💻 CPP
📖 第 1 页 / 共 5 页
字号:
        m_imageBounds = CGRectMake( 0.0, 0.0, 8.0 , 8.0 ) ;
        m_patternRef = CGPatternCreate(
            this , m_imageBounds, transform ,
            m_imageBounds.size.width, m_imageBounds.size.height,
            kCGPatternTilingNoDistortion, false , &wxMacCGPattern::ms_Callbacks ) ;
    }

    void StrokeLineSegments( CGContextRef ctxRef , const CGPoint pts[] , size_t count )
    {
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4
        if ( UMAGetSystemVersion() >= 0x1040 )
        {
            CGContextStrokeLineSegments( ctxRef , pts , count ) ;
        }
        else
#endif
        {
            CGContextBeginPath( ctxRef );
            for (size_t i = 0; i < count; i += 2)
            {
                CGContextMoveToPoint(ctxRef, pts[i].x, pts[i].y);
                CGContextAddLineToPoint(ctxRef, pts[i+1].x, pts[i+1].y);
            }
            CGContextStrokePath(ctxRef);
        }
    }

    virtual void Render( CGContextRef ctxRef )
    {
        switch ( m_hatch )
        {
            case wxBDIAGONAL_HATCH :
                {
                    CGPoint pts[] =
                    {
                    { 8.0 , 0.0 } , { 0.0 , 8.0 }
                    };
                    StrokeLineSegments( ctxRef , pts , 2 ) ;
                }
                break ;

            case wxCROSSDIAG_HATCH :
                {
                    CGPoint pts[] =
                    {
                        { 0.0 , 0.0 } , { 8.0 , 8.0 } ,
                        { 8.0 , 0.0 } , { 0.0 , 8.0 }
                    };
                    StrokeLineSegments( ctxRef , pts , 4 ) ;
                }
                break ;

            case wxFDIAGONAL_HATCH :
                {
                    CGPoint pts[] =
                    {
                    { 0.0 , 0.0 } , { 8.0 , 8.0 }
                    };
                    StrokeLineSegments( ctxRef , pts , 2 ) ;
                }
                break ;

            case wxCROSS_HATCH :
                {
                    CGPoint pts[] =
                    {
                    { 0.0 , 4.0 } , { 8.0 , 4.0 } ,
                    { 4.0 , 0.0 } , { 4.0 , 8.0 } ,
                    };
                    StrokeLineSegments( ctxRef , pts , 4 ) ;
                }
                break ;

            case wxHORIZONTAL_HATCH :
                {
                    CGPoint pts[] =
                    {
                    { 0.0 , 4.0 } , { 8.0 , 4.0 } ,
                    };
                    StrokeLineSegments( ctxRef , pts , 2 ) ;
                }
                break ;

            case wxVERTICAL_HATCH :
                {
                    CGPoint pts[] =
                    {
                    { 4.0 , 0.0 } , { 4.0 , 8.0 } ,
                    };
                    StrokeLineSegments( ctxRef , pts , 2 ) ;
                }
                break ;

            default:
                break;
        }
    }

protected :
    ~HatchPattern() {}

    CGRect      m_imageBounds ;
    int         m_hatch ;
};

#pragma mark -

void wxMacCGContext::SetPen( const wxPen &pen )
{
    m_pen = pen ;
    if ( m_cgContext == NULL )
        return ;

    bool fill = m_brush.GetStyle() != wxTRANSPARENT ;
    bool stroke = pen.GetStyle() != wxTRANSPARENT ;

#if 0
    // we can benchmark performance; should go into a setting eventually
    CGContextSetShouldAntialias( m_cgContext , false ) ;
#endif

    if ( fill | stroke )
    {
        // set up brushes
        m_mode = kCGPathFill ; // just a default

        if ( stroke )
        {
            RGBColor col = MAC_WXCOLORREF( pen.GetColour().GetPixel() ) ;
            CGContextSetRGBStrokeColor( m_cgContext , col.red / 65536.0 , col.green / 65536.0 , col.blue / 65536.0 , 1.0 ) ;

            // TODO: * m_dc->m_scaleX
            float penWidth = pen.GetWidth();
            if (penWidth <= 0.0)
                penWidth = 0.1;
            CGContextSetLineWidth( m_cgContext , penWidth ) ;

            CGLineCap cap ;
            switch ( pen.GetCap() )
            {
                case wxCAP_ROUND :
                    cap = kCGLineCapRound ;
                    break ;

                case wxCAP_PROJECTING :
                    cap = kCGLineCapSquare ;
                    break ;

                case wxCAP_BUTT :
                    cap = kCGLineCapButt ;
                    break ;

                default :
                    cap = kCGLineCapButt ;
                    break ;
            }

            CGLineJoin join ;
            switch ( pen.GetJoin() )
            {
                case wxJOIN_BEVEL :
                    join = kCGLineJoinBevel ;
                    break ;

                case wxJOIN_MITER :
                    join = kCGLineJoinMiter ;
                    break ;

                case wxJOIN_ROUND :
                    join = kCGLineJoinRound ;
                    break ;

                default :
                    join = kCGLineJoinMiter ;
                    break;
            }

            m_mode = kCGPathStroke ;
            int count = 0 ;

            const float *lengths = NULL ;
            float *userLengths = NULL ;

            const float dashUnit = penWidth < 1.0 ? 1.0 : penWidth;

            const float dotted[] = { dashUnit , dashUnit + 2.0 };
            const float short_dashed[] = { 9.0 , 6.0 };
            const float dashed[] = { 19.0 , 9.0 };
            const float dotted_dashed[] = { 9.0 , 6.0 , 3.0 , 3.0 };

            switch ( pen.GetStyle() )
            {
                case wxSOLID :
                    break ;

                case wxDOT :
                    lengths = dotted ;
                    count = WXSIZEOF(dotted);
                    break ;

                case wxLONG_DASH :
                    lengths = dashed ;
                    count = WXSIZEOF(dashed) ;
                    break ;

                case wxSHORT_DASH :
                    lengths = short_dashed ;
                    count = WXSIZEOF(short_dashed) ;
                    break ;

                case wxDOT_DASH :
                    lengths = dotted_dashed ;
                    count = WXSIZEOF(dotted_dashed);
                    break ;

                case wxUSER_DASH :
                    wxDash *dashes ;
                    count = pen.GetDashes( &dashes ) ;
                    if ((dashes != NULL) && (count > 0))
                    {
                        userLengths = new float[count] ;
                        for ( int i = 0 ; i < count ; ++i )
                        {
                            userLengths[i] = dashes[i] * dashUnit ;

                            if ( i % 2 == 1 && userLengths[i] < dashUnit + 2.0 )
                                userLengths[i] = dashUnit + 2.0 ;
                            else if ( i % 2 == 0 && userLengths[i] < dashUnit )
                                userLengths[i] = dashUnit ;
                        }
                    }
                    lengths = userLengths ;
                    break ;

                case wxSTIPPLE :
                    {
                        float  alphaArray[1] = { 1.0 } ;
                        wxBitmap* bmp = pen.GetStipple() ;
                        if ( bmp && bmp->Ok() )
                        {
                            wxMacCFRefHolder<CGColorSpaceRef> patternSpace( CGColorSpaceCreatePattern( NULL ) ) ;
                            CGContextSetStrokeColorSpace( m_cgContext , patternSpace ) ;
                            wxMacCFRefHolder<CGPatternRef> pattern( *( new ImagePattern( bmp , CGContextGetCTM( m_cgContext ) ) ) );
                            CGContextSetStrokePattern( m_cgContext, pattern , alphaArray ) ;
                        }
                    }
                    break ;

                default :
                    {
                        wxMacCFRefHolder<CGColorSpaceRef> patternSpace( CGColorSpaceCreatePattern( wxMacGetGenericRGBColorSpace() ) ) ;
                        CGContextSetStrokeColorSpace( m_cgContext , patternSpace ) ;
                        wxMacCFRefHolder<CGPatternRef> pattern( *( new HatchPattern( pen.GetStyle() , CGContextGetCTM( m_cgContext ) ) ) );

                        RGBColor col = MAC_WXCOLORREF( pen.GetColour().GetPixel() ) ;
                        float  colorArray[4] = { col.red / 65536.0 , col.green / 65536.0 , col.blue / 65536.0 , 1.0 } ;

                        CGContextSetStrokePattern( m_cgContext, pattern , colorArray ) ;
                    }
                    break ;
            }

            if ((lengths != NULL) && (count > 0))
            {
                CGContextSetLineDash( m_cgContext , 0 , lengths , count ) ;
                // force the line cap, otherwise we get artifacts (overlaps) and just solid lines
                cap = kCGLineCapButt ;
            }
            else
            {
               CGContextSetLineDash( m_cgContext , 0 , NULL , 0 ) ;
            }

            CGContextSetLineCap( m_cgContext , cap ) ;
            CGContextSetLineJoin( m_cgContext , join ) ;

            delete[] userLengths ;
        }

        if ( fill && stroke )
            m_mode = kCGPathFillStroke ;
    }
}

void wxMacCGContext::SetBrush( const wxBrush &brush )
{
    m_brush = brush ;
    if ( m_cgContext == NULL )
        return ;

    bool fill = brush.GetStyle() != wxTRANSPARENT ;
    bool stroke = m_pen.GetStyle() != wxTRANSPARENT ;

#if 0
    // we can benchmark performance, should go into a setting later
    CGContextSetShouldAntialias( m_cgContext , false ) ;
#endif

    if ( fill | stroke )
    {
        // setup brushes
        m_mode = kCGPathFill ; // just a default

        if ( fill )
        {
            if ( brush.GetStyle() == wxSOLID )
            {
                RGBColor col = MAC_WXCOLORREF( brush.GetColour().GetPixel() ) ;
                CGContextSetRGBFillColor( m_cgContext , col.red / 65536.0 , col.green / 65536.0 , col.blue / 65536.0 , 1.0 ) ;
            }
            else if ( brush.IsHatch() )
            {
                wxMacCFRefHolder<CGColorSpaceRef> patternSpace( CGColorSpaceCreatePattern( wxMacGetGenericRGBColorSpace() ) ) ;
                CGContextSetFillColorSpace( m_cgContext , patternSpace ) ;
                wxMacCFRefHolder<CGPatternRef> pattern( *( new HatchPattern( brush.GetStyle() , CGContextGetCTM( m_cgContext ) ) ) );

                RGBColor col = MAC_WXCOLORREF( brush.GetColour().GetPixel() ) ;
                float  colorArray[4] = { col.red / 65536.0 , col.green / 65536.0 , col.blue / 65536.0 , 1.0 } ;

                CGContextSetFillPattern( m_cgContext, pattern , colorArray ) ;
            }
            else
            {
                // now brush is a bitmap
                float  alphaArray[1] = { 1.0 } ;
                wxBitmap* bmp = brush.GetStipple() ;
                if ( bmp && bmp->Ok() )
                {
                    wxMacCFRefHolder<CGColorSpaceRef> patternSpace( CGColorSpaceCreatePattern( NULL ) ) ;
                    CGContextSetFillColorSpace( m_cgContext , patternSpace ) ;
                    wxMacCFRefHolder<CGPatternRef> pattern( *( new ImagePattern( bmp , CGContextGetCTM( m_cgContext ) ) ) );
                    CGContextSetFillPattern( m_cgContext, pattern , alphaArray ) ;
                }
            }

            m_mode = kCGPathFill ;
        }

        if ( fill && stroke )
            m_mode = kCGPathFillStroke ;
        else if ( stroke )
            m_mode = kCGPathStroke ;
    }
}

void AddEllipticArcToPath(CGContextRef c, CGPoint center, float a, float b, float fromDegree , float toDegree )
{
    CGContextSaveGState(c);
    CGContextTranslateCTM(c, center.x, center.y);
    CGContextScaleCTM(c, a, b);
    CGContextMoveToPoint(c, 1, 0);
    CGContextAddArc(c, 0, 0, 1, DegToRad(fromDegree), DegToRad(toDegree), 0);
    CGContextClosePath(c);
    CGContextRestoreGState(c);
}

void AddRoundedRectToPath(CGContextRef c, CGRect rect, float ovalWidth,
      float ovalHeight)
{
    float fw, fh;
    if (ovalWidth == 0 || ovalHeight == 0)
    {
        CGContextAddRect(c, rect);
        return;
    }

    CGContextSaveGState(c);
    CGContextTranslateCTM(c, CGRectGetMinX(rect), CGRectGetMinY(rect));
    CGContextScaleCTM(c, ovalWidth, ovalHeight);

    fw = CGRectGetWidth(rect) / ovalWidth;
    fh = CGRectGetHeight(rect) / ovalHeight;

    CGContextMoveToPoint(c, fw, fh / 2);
    CGContextAddArcToPoint(c, fw, fh, fw / 2, fh, 1);
    CGContextAddArcToPoint(c, 0, fh, 0, fh / 2, 1);
    CGContextAddArcToPoint(c, 0, 0, fw / 2, 0, 1);
    CGContextAddArcToPoint(c, fw, 0, fw, fh / 2, 1);
    CGContextClosePath(c);
    CGContextRestoreGState(c);
}

#pragma mark -

wxDC::wxDC()
{
    m_ok = false ;
    m_colour = true;
    m_mm_to_pix_x = mm2pt;
    m_mm_to_pix_y = mm2pt;

    m_externalDeviceOriginX = 0;
    m_externalDeviceOriginY = 0;
    m_logicalScaleX = 1.0;
    m_logicalScaleY = 1.0;
    m_userScaleX = 1.0;
    m_userScaleY = 1.0;
    m_scaleX = 1.0;
    m_scaleY = 1.0;
    m_needComputeScaleX =
    m_needComputeScaleY = false;

    m_macPort = 0 ;
    m_macLocalOrigin.x =
    m_macLocalOrigin.y = 0 ;

    m_pen = *wxBLACK_PEN;
    m_font = *wxNORMAL_FONT;
    m_brush = *wxWHITE_BRUSH;

    m_macATSUIStyle = NULL ;
    m_graphicContext = NULL ;
}

wxDC::~wxDC()
{
    if ( m_macATSUIStyle )
    {
        ::ATSUDisposeStyle((ATSUStyle)m_macATSUIStyle);
        m_macATSUIStyle = NULL ;
    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -