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

📄 dccg.cpp

📁 Wxpython Implemented on Windows CE, Source code
💻 CPP
📖 第 1 页 / 共 5 页
字号:
                    blit = wxNullBitmap ;
                }
            }
            else
            {
                blit = wxNullBitmap ;
            }
        }

        if ( blit.Ok() )
        {
            CGContextRef cg = ((wxMacCGContext*)(m_graphicContext))->GetNativeContext() ;
            CGImageRef image = (CGImageRef)( blit.CGImageCreate() ) ;
            HIRect r = CGRectMake( xxdest , yydest , wwdest , hhdest ) ;
            HIViewDrawCGImage( cg , &r , image ) ;
            CGImageRelease( image ) ;
        }
    }
    else
    {
#if 0
        CGContextRef cg = (wxMacCGContext*)(source->GetGraphicContext())->GetNativeContext() ;
        void *data = CGBitmapContextGetData( cg ) ;
#endif

        return false ; // wxFAIL_MSG( wxT("Blitting is only supported from bitmap contexts") ) ;
    }

    return true;
}

void wxDC::DoDrawRotatedText(const wxString& str, wxCoord x, wxCoord y,
                              double angle)
{
    wxCHECK_RET( Ok(), wxT("wxDC(cg)::DoDrawRotatedText - invalid DC") );
    wxCHECK_RET( m_macATSUIStyle != NULL, wxT("wxDC(cg)::DoDrawRotatedText - no valid font set") );

    if ( str.length() == 0 )
        return ;
    if ( m_logicalFunction != wxCOPY )
        return ;

    OSStatus status = noErr ;
    ATSUTextLayout atsuLayout ;
    UniCharCount chars = str.length() ;
    UniChar* ubuf = NULL ;

#if SIZEOF_WCHAR_T == 4
    wxMBConvUTF16 converter ;
#if wxUSE_UNICODE
    size_t unicharlen = converter.WC2MB( NULL , str.wc_str() , 0 ) ;
    ubuf = (UniChar*) malloc( unicharlen + 2 ) ;
    converter.WC2MB( (char*) ubuf , str.wc_str(), unicharlen + 2 ) ;
#else
    const wxWCharBuffer wchar = str.wc_str( wxConvLocal ) ;
    size_t unicharlen = converter.WC2MB( NULL , wchar.data() , 0 ) ;
    ubuf = (UniChar*) malloc( unicharlen + 2 ) ;
    converter.WC2MB( (char*) ubuf , wchar.data() , unicharlen + 2 ) ;
#endif
    chars = unicharlen / 2 ;
#else
#if wxUSE_UNICODE
    ubuf = (UniChar*) str.wc_str() ;
#else
    wxWCharBuffer wchar = str.wc_str( wxConvLocal ) ;
    chars = wxWcslen( wchar.data() ) ;
    ubuf = (UniChar*) wchar.data() ;
#endif
#endif

    int drawX = XLOG2DEVMAC(x) ;
    int drawY = YLOG2DEVMAC(y) ;

    status = ::ATSUCreateTextLayoutWithTextPtr( (UniCharArrayPtr) ubuf , 0 , chars , chars , 1 ,
        &chars , (ATSUStyle*) &m_macATSUIStyle , &atsuLayout ) ;

    wxASSERT_MSG( status == noErr , wxT("couldn't create the layout of the rotated text") );

    status = ::ATSUSetTransientFontMatching( atsuLayout , true ) ;
    wxASSERT_MSG( status == noErr , wxT("couldn't setup transient font matching") );

    int iAngle = int( angle );
    if ( abs(iAngle) > 0 )
    {
        Fixed atsuAngle = IntToFixed( iAngle ) ;
        ATSUAttributeTag atsuTags[] =
        {
            kATSULineRotationTag ,
        } ;
        ByteCount atsuSizes[sizeof(atsuTags) / sizeof(ATSUAttributeTag)] =
        {
            sizeof( Fixed ) ,
        } ;
        ATSUAttributeValuePtr    atsuValues[sizeof(atsuTags) / sizeof(ATSUAttributeTag)] =
        {
            &atsuAngle ,
        } ;
        status = ::ATSUSetLayoutControls(atsuLayout , sizeof(atsuTags) / sizeof(ATSUAttributeTag),
            atsuTags, atsuSizes, atsuValues ) ;
    }

    {
        CGContextRef cgContext = ((wxMacCGContext*)(m_graphicContext))->GetNativeContext() ;
        ATSUAttributeTag atsuTags[] =
        {
            kATSUCGContextTag ,
        } ;
        ByteCount atsuSizes[sizeof(atsuTags) / sizeof(ATSUAttributeTag)] =
        {
            sizeof( CGContextRef ) ,
        } ;
        ATSUAttributeValuePtr    atsuValues[sizeof(atsuTags) / sizeof(ATSUAttributeTag)] =
        {
            &cgContext ,
        } ;
        status = ::ATSUSetLayoutControls(atsuLayout , sizeof(atsuTags) / sizeof(ATSUAttributeTag),
            atsuTags, atsuSizes, atsuValues ) ;
    }

    ATSUTextMeasurement textBefore, textAfter ;
    ATSUTextMeasurement ascent, descent ;

    status = ::ATSUGetUnjustifiedBounds( atsuLayout, kATSUFromTextBeginning, kATSUToTextEnd,
        &textBefore , &textAfter, &ascent , &descent );

    wxASSERT_MSG( status == noErr , wxT("couldn't measure the rotated text") );

    Rect rect ;

    if ( m_backgroundMode == wxSOLID )
    {
        wxGraphicPath* path = m_graphicContext->CreatePath() ;
        path->MoveToPoint( drawX , drawY ) ;
        path->AddLineToPoint(
            (int) (drawX + sin(angle / RAD2DEG) * FixedToInt(ascent + descent)) ,
            (int) (drawY + cos(angle / RAD2DEG) * FixedToInt(ascent + descent)) ) ;
        path->AddLineToPoint(
            (int) (drawX + sin(angle / RAD2DEG) * FixedToInt(ascent + descent ) + cos(angle / RAD2DEG) * FixedToInt(textAfter)) ,
            (int) (drawY + cos(angle / RAD2DEG) * FixedToInt(ascent + descent) - sin(angle / RAD2DEG) * FixedToInt(textAfter)) ) ;
        path->AddLineToPoint(
            (int) (drawX + cos(angle / RAD2DEG) * FixedToInt(textAfter)) ,
            (int) (drawY - sin(angle / RAD2DEG) * FixedToInt(textAfter)) ) ;

        m_graphicContext->FillPath( path , m_textBackgroundColour ) ;
        delete path ;
    }

    drawX += (int)(sin(angle / RAD2DEG) * FixedToInt(ascent));
    drawY += (int)(cos(angle / RAD2DEG) * FixedToInt(ascent));

    status = ::ATSUMeasureTextImage( atsuLayout, kATSUFromTextBeginning, kATSUToTextEnd,
        IntToFixed(drawX) , IntToFixed(drawY) , &rect );
    wxASSERT_MSG( status == noErr , wxT("couldn't measure the rotated text") );

    CGContextSaveGState(((wxMacCGContext*)(m_graphicContext))->GetNativeContext());
    CGContextTranslateCTM(((wxMacCGContext*)(m_graphicContext))->GetNativeContext(), drawX, drawY);
    CGContextScaleCTM(((wxMacCGContext*)(m_graphicContext))->GetNativeContext(), 1, -1);
    status = ::ATSUDrawText( atsuLayout, kATSUFromTextBeginning, kATSUToTextEnd,
        IntToFixed(0) , IntToFixed(0) );

    wxASSERT_MSG( status == noErr , wxT("couldn't draw the rotated text") );

    CGContextRestoreGState( ((wxMacCGContext*)(m_graphicContext))->GetNativeContext() ) ;

    CalcBoundingBox(XDEV2LOG(rect.left), YDEV2LOG(rect.top) );
    CalcBoundingBox(XDEV2LOG(rect.right), YDEV2LOG(rect.bottom) );

    ::ATSUDisposeTextLayout(atsuLayout);

#if SIZEOF_WCHAR_T == 4
    free( ubuf ) ;
#endif
}

void wxDC::DoDrawText(const wxString& strtext, wxCoord x, wxCoord y)
{
    wxCHECK_RET( Ok(), wxT("wxDC(cg)::DoDrawText - invalid DC") );

    DoDrawRotatedText( strtext , x , y , 0.0 ) ;
}

bool wxDC::CanGetTextExtent() const
{
    wxCHECK_MSG( Ok(), false, wxT("wxDC(cg)::CanGetTextExtent - invalid DC") );

    return true ;
}

void wxDC::DoGetTextExtent( const wxString &str, wxCoord *width, wxCoord *height,
                            wxCoord *descent, wxCoord *externalLeading ,
                            wxFont *theFont ) const
{
    wxCHECK_RET( Ok(), wxT("wxDC(cg)::DoGetTextExtent - invalid DC") );

    wxFont formerFont = m_font ;
    if ( theFont )
    {
        // work around the const-ness
        *((wxFont*)(&m_font)) = *theFont ;
        MacInstallFont() ;
    }

    if ( str.empty() )
        return ;

    wxCHECK_RET( m_macATSUIStyle != NULL, wxT("wxDC(cg)::DoGetTextExtent - no valid font set") ) ;

    OSStatus status = noErr ;
    ATSUTextLayout atsuLayout ;
    UniCharCount chars = str.length() ;
    UniChar* ubuf = NULL ;

#if SIZEOF_WCHAR_T == 4
    wxMBConvUTF16 converter ;
#if wxUSE_UNICODE
    size_t unicharlen = converter.WC2MB( NULL , str.wc_str() , 0 ) ;
    ubuf = (UniChar*) malloc( unicharlen + 2 ) ;
    converter.WC2MB( (char*) ubuf , str.wc_str(), unicharlen + 2 ) ;
#else
    const wxWCharBuffer wchar = str.wc_str( wxConvLocal ) ;
    size_t unicharlen = converter.WC2MB( NULL , wchar.data() , 0 ) ;
    ubuf = (UniChar*) malloc( unicharlen + 2 ) ;
    converter.WC2MB( (char*) ubuf , wchar.data() , unicharlen + 2 ) ;
#endif
    chars = unicharlen / 2 ;
#else
#if wxUSE_UNICODE
    ubuf = (UniChar*) str.wc_str() ;
#else
    wxWCharBuffer wchar = str.wc_str( wxConvLocal ) ;
    chars = wxWcslen( wchar.data() ) ;
    ubuf = (UniChar*) wchar.data() ;
#endif
#endif

    status = ::ATSUCreateTextLayoutWithTextPtr( (UniCharArrayPtr) ubuf , 0 , chars , chars , 1 ,
        &chars , (ATSUStyle*) &m_macATSUIStyle , &atsuLayout ) ;

    wxASSERT_MSG( status == noErr , wxT("couldn't create the layout of the text") );

    ATSUTextMeasurement textBefore, textAfter ;
    ATSUTextMeasurement textAscent, textDescent ;

    status = ::ATSUGetUnjustifiedBounds( atsuLayout, kATSUFromTextBeginning, kATSUToTextEnd,
        &textBefore , &textAfter, &textAscent , &textDescent );

    if ( height )
        *height = YDEV2LOGREL( FixedToInt(textAscent + textDescent) ) ;
    if ( descent )
        *descent =YDEV2LOGREL( FixedToInt(textDescent) );
    if ( externalLeading )
        *externalLeading = 0 ;
    if ( width )
        *width = XDEV2LOGREL( FixedToInt(textAfter - textBefore) ) ;

    ::ATSUDisposeTextLayout(atsuLayout);

#if SIZEOF_WCHAR_T == 4
    free( ubuf ) ;
#endif

    if ( theFont )
    {
        // work around the constness
        *((wxFont*)(&m_font)) = formerFont ;
        MacInstallFont() ;
    }
}

bool wxDC::DoGetPartialTextExtents(const wxString& text, wxArrayInt& widths) const
{
    wxCHECK_MSG( Ok(), false, wxT("wxDC(cg)::DoGetPartialTextExtents - invalid DC") );

    widths.Empty();
    widths.Add(0, text.length());

    if (text.empty())
        return false;

    ATSUTextLayout atsuLayout ;
    UniCharCount chars = text.length() ;
    UniChar* ubuf = NULL ;

#if SIZEOF_WCHAR_T == 4
    wxMBConvUTF16 converter ;
#if wxUSE_UNICODE
    size_t unicharlen = converter.WC2MB( NULL , text.wc_str() , 0 ) ;
    ubuf = (UniChar*) malloc( unicharlen + 2 ) ;
    converter.WC2MB( (char*) ubuf , text.wc_str(), unicharlen + 2 ) ;
#else
    const wxWCharBuffer wchar = text.wc_str( wxConvLocal ) ;
    size_t unicharlen = converter.WC2MB( NULL , wchar.data() , 0 ) ;
    ubuf = (UniChar*) malloc( unicharlen + 2 ) ;
    converter.WC2MB( (char*) ubuf , wchar.data() , unicharlen + 2 ) ;
#endif
    chars = unicharlen / 2 ;
#else
#if wxUSE_UNICODE
    ubuf = (UniChar*) text.wc_str() ;
#else
    wxWCharBuffer wchar = text.wc_str( wxConvLocal ) ;
    chars = wxWcslen( wchar.data() ) ;
    ubuf = (UniChar*) wchar.data() ;
#endif
#endif

    OSStatus status;
    status = ::ATSUCreateTextLayoutWithTextPtr( (UniCharArrayPtr) ubuf , 0 , chars , chars , 1 ,
        &chars , (ATSUStyle*) &m_macATSUIStyle , &atsuLayout ) ;

    for ( int pos = 0; pos < (int)chars; pos ++ )
    {
        unsigned long actualNumberOfBounds = 0;
        ATSTrapezoid glyphBounds;

        // We get a single bound, since the text should only require one. If it requires more, there is an issue
        OSStatus result;
        result = ATSUGetGlyphBounds( atsuLayout, 0, 0, kATSUFromTextBeginning, pos + 1,
            kATSUseDeviceOrigins, 1, &glyphBounds, &actualNumberOfBounds );
        if (result != noErr || actualNumberOfBounds != 1 )
            return false;

        widths[pos] = XDEV2LOGREL(FixedToInt( glyphBounds.upperRight.x - glyphBounds.upperLeft.x ));
        //unsigned char uch = s[i];
    }

    ::ATSUDisposeTextLayout(atsuLayout);
    return true;
}

wxCoord wxDC::GetCharWidth(void) const
{
    wxCoord width ;
    DoGetTextExtent( wxT("g") , &width , NULL , NULL , NULL , NULL ) ;

    return width ;
}

wxCoord wxDC::GetCharHeight(void) const
{
    wxCoord height ;
    DoGetTextExtent( wxT("g") , NULL , &height , NULL , NULL , NULL ) ;

    return height ;
}

void wxDC::Clear(void)
{
    wxCHECK_RET( Ok(), wxT("wxDC(cg)::Clear - invalid DC") );

    if (m_backgroundBrush.Ok() && m_backgroundBrush.GetStyle() != wxTRANSPARENT)
    {
        HIRect rect = CGRectMake( -10000 , -10000 , 20000 , 20000 ) ;
        CGContextRef cg = ((wxMacCGContext*)(m_graphicContext))->GetNativeContext() ;
        switch ( m_backgroundBrush.MacGetBrushKind() )
        {
            case kwxMacBrushTheme :
                {
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4
                    if ( HIThemeSetFill != 0 )
                    {
                        HIThemeSetFill( m_backgroundBrush.MacGetTheme(), NULL, cg, kHIThemeOrientationNormal );
                        CGContextFillRect(cg, rect);

                    }
                    else
#endif
                    {
                        RGBColor color;
                        GetThemeBrushAsColor( m_backgroundBrush.MacGetTheme(), 32, true, &color );
                        CGContextSetRGBFillColor( cg, (float) color.red / 65536,
                            (float) color.green / 65536, (float) color.blue / 65536, 1 );
                            CGContextFillRect( cg, rect );
                    }

                    // reset to normal value
                    RGBColor col = MAC_WXCOLORREF( GetBrush().GetColour().GetPixel() ) ;
                    CGContextSetRGBFillColor( cg, col.red / 65536.0, col.green / 65536.0, col.blue / 65536.0, 1.0 );
                }
                break ;

            case kwxMacBrushThemeBackground :
                {
                    wxFAIL_MSG( wxT("There shouldn't be theme backgrounds under Quartz") ) ;

#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_3
                    if ( UMAGetSystemVersion() >= 0x1030 )
                    {
                        HIThemeBackgroundDrawInfo drawInfo ;
                        drawInfo.version = 0 ;
                        drawInfo.state = kThemeStateActive ;
                        drawInfo.kind = m_backgroundBrush.MacGetThemeBackground( NULL ) ;
                        if ( drawInfo.kind == kThemeBackgroundMetal )
                        {
                            HIThemeDrawBackground( &rect, &drawInfo, cg, kHIThemeOrientationNormal ) ;
                            HIThemeApplyBackground( &rect, &drawInfo, cg, kHIThemeOrientationNormal ) ;
                        }
                    }
#endif
                }
                break ;

            case kwxMacBrushColour :
                {
                    // FIXME: doesn't correctly render stippled brushes !!
                    // FIXME: should this be replaced by ::SetBrush() ??

                    RGBColor col = MAC_WXCOLORREF( m_backgroundBrush.GetColour().GetPixel()) ;
                    CGContextSetRGBFillColor( cg , col.red / 65536.0 , col.green / 65536.0 , col.blue / 65536.0 , 1.0 ) ;
                    CGContextFillRect(cg, rect);

                    // reset to normal value
                    col = MAC_WXCOLORREF( GetBrush().GetColour().GetPixel() ) ;
                    CGContextSetRGBFillColor( cg , col.red / 65536.0 , col.green / 65536.0 , col.blue / 65536.0 , 1.0 ) ;
                }
                break ;

            default :
                wxFAIL_MSG( wxT("unknown brush kind") ) ;

⌨️ 快捷键说明

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