예제 #1
0
파일: dc.cpp 프로젝트: EEmmanuel7/wxWidgets
bool wxQtDCImpl::DoBlit(wxCoord xdest, wxCoord ydest,
                    wxCoord width, wxCoord height,
                    wxDC *source,
                    wxCoord xsrc, wxCoord ysrc,
                    wxRasterOperationMode rop,
                    bool useMask,
                    wxCoord WXUNUSED(xsrcMask),
                    wxCoord WXUNUSED(ysrcMask) )
{
    wxQtDCImpl *implSource = (wxQtDCImpl*)source->GetImpl();
    
    QImage *qtSource = implSource->m_qtImage;
    
    // Not a CHECK on purpose
    if ( !qtSource )
        return false;

    QImage qtSourceConverted = *qtSource;
    if ( !useMask )
        qtSourceConverted = qtSourceConverted.convertToFormat( QImage::Format_RGB32 );

    // Change logical function
    wxRasterOperationMode savedMode = GetLogicalFunction();
    SetLogicalFunction( rop );
    
    m_qtPainter->drawImage( QRect( xdest, ydest, width, height ),
                           qtSourceConverted,
                           QRect( xsrc, ysrc, width, height ) );

    SetLogicalFunction( savedMode );

    return true;
}
예제 #2
0
bool wxGTKCairoDCImpl::DoStretchBlit(int xdest, int ydest, int dstWidth, int dstHeight, wxDC* source, int xsrc, int ysrc, int srcWidth, int srcHeight, wxRasterOperationMode rop, bool useMask, int xsrcMask, int ysrcMask)
{
    wxCHECK_MSG(IsOk(), false, "invalid DC");
    wxCHECK_MSG(source && source->IsOk(), false, "invalid source DC");

    cairo_t* cr = NULL;
    if (m_graphicContext)
        cr = static_cast<cairo_t*>(m_graphicContext->GetNativeContext());
    cairo_t* cr_src = NULL;
    wxGraphicsContext* gc_src = source->GetGraphicsContext();
    if (gc_src)
        cr_src = static_cast<cairo_t*>(gc_src->GetNativeContext());

    if (cr == NULL || cr_src == NULL)
        return false;

    const int xsrc_dev = source->LogicalToDeviceX(xsrc);
    const int ysrc_dev = source->LogicalToDeviceY(ysrc);

    cairo_surface_t* surfaceSrc = cairo_get_target(cr_src);
    cairo_surface_flush(surfaceSrc);

    cairo_surface_t* surfaceTmp = NULL;
    // If destination (this) and source wxDC refer to the same Cairo context
    // it means that we operate on one surface and results of drawing
    // can be invalid if destination and source regions overlap.
    // In such situation we have to copy source surface to the temporary
    // surface and use this copy in the drawing operations.
    if ( cr == cr_src )
    {
        // Check if destination and source regions overlap.
        // If necessary, copy source surface to the temporary one.
        if (wxRect(xdest, ydest, dstWidth, dstHeight)
            .Intersects(wxRect(xsrc, ysrc, srcWidth, srcHeight)))
        {
            const int w = cairo_image_surface_get_width(surfaceSrc);
            const int h = cairo_image_surface_get_height(surfaceSrc);
#if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 12, 0)
            if ( cairo_version() >= CAIRO_VERSION_ENCODE(1, 12, 0) )
            {
                surfaceTmp = cairo_surface_create_similar_image(surfaceSrc,
                     cairo_image_surface_get_format(surfaceSrc),
                     w, h);
            }
            else
#endif // Cairo 1.12
            {
                surfaceTmp = cairo_surface_create_similar(surfaceSrc,
                     CAIRO_CONTENT_COLOR_ALPHA,
                     w, h);
            }
            cairo_t* crTmp = cairo_create(surfaceTmp);
            cairo_set_source_surface(crTmp, surfaceSrc, 0, 0);
            cairo_rectangle(crTmp, 0.0, 0.0, w, h);
            cairo_set_operator(crTmp, CAIRO_OPERATOR_SOURCE);
            cairo_fill(crTmp);
            cairo_destroy(crTmp);
            cairo_surface_flush(surfaceTmp);
            surfaceSrc = surfaceTmp;
        }
    }
    cairo_save(cr);
    cairo_translate(cr, xdest, ydest);
    cairo_rectangle(cr, 0, 0, dstWidth, dstHeight);
    double sx, sy;
    source->GetUserScale(&sx, &sy);
    cairo_scale(cr, dstWidth / (sx * srcWidth), dstHeight / (sy * srcHeight));
    cairo_set_source_surface(cr, surfaceSrc, -xsrc_dev, -ysrc_dev);
    const wxRasterOperationMode rop_save = m_logicalFunction;
    SetLogicalFunction(rop);
    cairo_pattern_set_filter(cairo_get_source(cr), CAIRO_FILTER_NEAREST);
    cairo_surface_t* maskSurf = NULL;
    if (useMask)
    {
        const wxBitmap& bitmap = source->GetImpl()->GetSelectedBitmap();
        if (bitmap.IsOk())
        {
            wxMask* mask = bitmap.GetMask();
            if (mask)
                maskSurf = *mask;
        }
    }
    if (maskSurf)
    {
        int xsrcMask_dev = xsrc_dev;
        int ysrcMask_dev = ysrc_dev;
        if (xsrcMask != -1)
            xsrcMask_dev = source->LogicalToDeviceX(xsrcMask);
        if (ysrcMask != -1)
            ysrcMask_dev = source->LogicalToDeviceY(ysrcMask);
        cairo_clip(cr);
        cairo_mask_surface(cr, maskSurf, -xsrcMask_dev, -ysrcMask_dev);
    }
    else
    {
        cairo_fill(cr);
    }
    cairo_restore(cr);
    if ( surfaceTmp )
    {
        cairo_surface_destroy(surfaceTmp);
    }
    m_logicalFunction = rop_save;
    return true;
}
예제 #3
0
파일: dc.cpp 프로젝트: 3v1n0/wxWidgets
bool wxGTKCairoDCImpl::DoStretchBlit(int xdest, int ydest, int dstWidth, int dstHeight, wxDC* source, int xsrc, int ysrc, int srcWidth, int srcHeight, wxRasterOperationMode rop, bool useMask, int xsrcMask, int ysrcMask)
{
    wxCHECK_MSG(IsOk(), false, "invalid DC");
    wxCHECK_MSG(source && source->IsOk(), false, "invalid source DC");

    cairo_t* cr = NULL;
    if (m_graphicContext)
        cr = static_cast<cairo_t*>(m_graphicContext->GetNativeContext());
    cairo_t* cr_src = NULL;
    wxGraphicsContext* gc_src = source->GetGraphicsContext();
    if (gc_src)
        cr_src = static_cast<cairo_t*>(gc_src->GetNativeContext());

    if (cr == NULL || cr_src == NULL)
        return false;

    const int xsrc_dev = source->LogicalToDeviceX(xsrc);
    const int ysrc_dev = source->LogicalToDeviceY(ysrc);

    cairo_surface_t* surface = cairo_get_target(cr_src);
    cairo_surface_flush(surface);
    cairo_save(cr);
    cairo_translate(cr, xdest, ydest);
    cairo_rectangle(cr, 0, 0, dstWidth, dstHeight);
    double sx, sy;
    source->GetUserScale(&sx, &sy);
    cairo_scale(cr, dstWidth / (sx * srcWidth), dstHeight / (sy * srcHeight));
    cairo_set_source_surface(cr, surface, -xsrc_dev, -ysrc_dev);
    const wxRasterOperationMode rop_save = m_logicalFunction;
    SetLogicalFunction(rop);
    cairo_pattern_set_filter(cairo_get_source(cr), CAIRO_FILTER_NEAREST);
    cairo_surface_t* maskSurf = NULL;
    if (useMask)
    {
        const wxBitmap& bitmap = source->GetImpl()->GetSelectedBitmap();
        if (bitmap.IsOk())
        {
            wxMask* mask = bitmap.GetMask();
            if (mask)
                maskSurf = *mask;
        }
    }
    if (maskSurf)
    {
        int xsrcMask_dev = xsrc_dev;
        int ysrcMask_dev = ysrc_dev;
        if (xsrcMask != -1)
            xsrcMask_dev = source->LogicalToDeviceX(xsrcMask);
        if (ysrcMask != -1)
            ysrcMask_dev = source->LogicalToDeviceY(ysrcMask);
        cairo_clip(cr);
        cairo_mask_surface(cr, maskSurf, -xsrcMask_dev, -ysrcMask_dev);
    }
    else
    {
        cairo_fill(cr);
    }
    cairo_restore(cr);
    m_logicalFunction = rop_save;
    return true;
}