Esempio n. 1
0
HDC
wdStartGdi(WD_HCANVAS hCanvas, BOOL bKeepContents)
{
    if(d2d_enabled()) {
        d2d_canvas_t* c = (d2d_canvas_t*) hCanvas;
        dummy_ID2D1GdiInteropRenderTarget* gdi_interop;
        dummy_D2D1_DC_INITIALIZE_MODE init_mode;
        HRESULT hr;
        HDC dc;

        hr = dummy_ID2D1RenderTarget_QueryInterface(c->target,
                    &dummy_IID_ID2D1GdiInteropRenderTarget, (void**) &gdi_interop);
        if(FAILED(hr)) {
            WD_TRACE_HR("wdStartGdi: ID2D1RenderTarget::"
                        "QueryInterface(IID_ID2D1GdiInteropRenderTarget) failed.");
            return NULL;
        }

        init_mode = (bKeepContents ? dummy_D2D1_DC_INITIALIZE_MODE_COPY
                        : dummy_D2D1_DC_INITIALIZE_MODE_CLEAR);
        hr = dummy_ID2D1GdiInteropRenderTarget_GetDC(gdi_interop, init_mode, &dc);
        if(FAILED(hr)) {
            WD_TRACE_HR("wdStartGdi: ID2D1GdiInteropRenderTarget::GetDC() failed.");
            dummy_ID2D1GdiInteropRenderTarget_Release(gdi_interop);
            return NULL;
        }

        c->gdi_interop = gdi_interop;

        if(c->flags & D2D_CANVASFLAG_RTL)
            SetLayout(dc, LAYOUT_RTL);

        return dc;
    } else {
        gdix_canvas_t* c = (gdix_canvas_t*) hCanvas;
        int status;
        HDC dc;

        status = gdix_vtable->fn_GetDC(c->graphics, &dc);
        if(status != 0) {
            WD_TRACE_ERR_("wdStartGdi: GdipGetDC() failed.", status);
            return NULL;
        }

        SetLayout(dc, c->dc_layout);

        if(c->dc_layout & LAYOUT_RTL)
            SetViewportOrgEx(dc, c->x + c->cx - (c->width-1), -c->y, NULL);

        return dc;
    }
}
Esempio n. 2
0
WD_HPATH
wdCreatePath(WD_HCANVAS hCanvas)
{
    if(d2d_enabled()) {
        dummy_ID2D1PathGeometry* g;
        HRESULT hr;

        wd_lock();
        hr = dummy_ID2D1Factory_CreatePathGeometry(d2d_factory, &g);
        wd_unlock();
        if(FAILED(hr)) {
            WD_TRACE_HR("wdCreatePath: "
                        "ID2D1Factory::CreatePathGeometry() failed.");
            return NULL;
        }

        return (WD_HPATH) g;
    } else {
        dummy_GpPath* p;
        int status;

        status = gdix_vtable->fn_CreatePath(dummy_FillModeAlternate, &p);
        if(status != 0) {
            WD_TRACE("wdCreatePath: GdipCreatePath() failed. [%d]", status);
            return NULL;
        }

        return (WD_HPATH) p;
    }
}
Esempio n. 3
0
BOOL
wdEndPaint(WD_HCANVAS hCanvas)
{
    if(d2d_enabled()) {
        d2d_canvas_t* c = (d2d_canvas_t*) hCanvas;
        HRESULT hr;

        d2d_reset_clip(c);

        hr = dummy_ID2D1RenderTarget_EndDraw(c->target, NULL, NULL);
        if(FAILED(hr)) {
            if(hr != D2DERR_RECREATE_TARGET)
                WD_TRACE_HR("wdEndPaint: ID2D1RenderTarget::EndDraw() failed.");
            return FALSE;
        }
        return TRUE;
    } else {
        gdix_canvas_t* c = (gdix_canvas_t*) hCanvas;

        /* If double-buffering, blit the memory DC to the display DC. */
        if(c->real_dc != NULL)
            BitBlt(c->real_dc, c->x, c->y, c->cx, c->cy, c->dc, 0, 0, SRCCOPY);

        SetLayout(c->real_dc, c->dc_layout);

        /* For GDI+, disable caching. */
        return FALSE;
    }
}
Esempio n. 4
0
WD_HBRUSH
wdCreateSolidBrush(WD_HCANVAS hCanvas, WD_COLOR color)
{
    if(d2d_enabled()) {
        d2d_canvas_t* c = (d2d_canvas_t*) hCanvas;
        ID2D1SolidColorBrush* b;
        D2D_COLOR_F clr;
        HRESULT hr;

        d2d_init_color(&clr, color);
        hr = ID2D1RenderTarget_CreateSolidColorBrush(
                        c->target, &clr, NULL, &b);
        if(FAILED(hr)) {
            WD_TRACE_HR("wdCreateSolidBrush: "
                        "ID2D1RenderTarget::CreateSolidColorBrush() failed.");
            return NULL;
        }
        return (WD_HBRUSH) b;
    } else {
        dummy_GpSolidFill* b;
        int status;

        status = gdix_vtable->fn_CreateSolidFill(color, &b);
        if(status != 0) {
            WD_TRACE("wdCreateSolidBrush: "
                     "GdipCreateSolidFill() failed. [%d]", status);
            return NULL;
        }
        return (WD_HBRUSH) b;
    }
}
Esempio n. 5
0
WD_HCACHEDIMAGE
wdCreateCachedImage(WD_HCANVAS hCanvas, WD_HIMAGE hImage)
{
    if(d2d_enabled()) {
        d2d_canvas_t* c = (d2d_canvas_t*) hCanvas;
        ID2D1Bitmap* b;
        HRESULT hr;

        hr = ID2D1RenderTarget_CreateBitmapFromWicBitmap(c->target,
                (IWICBitmapSource*) hImage, NULL, &b);
        if(FAILED(hr)) {
            WD_TRACE_HR("wdCreateCachedImage: "
                        "ID2D1RenderTarget::CreateBitmapFromWicBitmap() failed.");
            return NULL;
        }

        return (WD_HCACHEDIMAGE) b;
    } else {
        gdix_canvas_t* c = (gdix_canvas_t*) hCanvas;
        dummy_GpCachedBitmap* cb;
        int status;

        status = gdix_vtable->fn_CreateCachedBitmap((dummy_GpImage*) hImage,
                 c->graphics, &cb);
        if(status != 0) {
            WD_TRACE("wdCreateCachedImage: "
                     "GdipCreateCachedBitmap() failed. [%d]", status);
            return NULL;
        }

        return (WD_HCACHEDIMAGE) cb;
    }
}
Esempio n. 6
0
BOOL
wdResizeCanvas(WD_HCANVAS hCanvas, UINT uWidth, UINT uHeight)
{
    if(d2d_enabled()) {
        d2d_canvas_t* c = (d2d_canvas_t*) hCanvas;
        if(c->type == D2D_CANVASTYPE_HWND) {
            dummy_D2D1_SIZE_U size = { uWidth, uHeight };
            HRESULT hr;

            hr = dummy_ID2D1HwndRenderTarget_Resize(c->hwnd_target, &size);
            if(FAILED(hr)) {
                WD_TRACE_HR("wdResizeCanvas: "
                            "ID2D1HwndRenderTarget_Resize() failed.");
                return FALSE;
            }

            /* In RTL mode, we have to update the transformation matrix
             * accordingly. */
            if(c->flags & D2D_CANVASFLAG_RTL) {
                dummy_D2D1_MATRIX_3X2_F m;

                dummy_ID2D1RenderTarget_GetTransform(c->target, &m);
                m._31 = m._11 * (float)(uWidth - c->width);
                m._32 = m._12 * (float)(uWidth - c->width);
                dummy_ID2D1RenderTarget_SetTransform(c->target, &m);

                c->width = uWidth;
            }
            return TRUE;
        } else {
            /* Operation not supported. */
            WD_TRACE("wdResizeCanvas: Not supported (not ID2D1HwndRenderTarget).");
            return FALSE;
        }
    } else {
        /* Actually we should never be here as GDI+ back-end never allows
         * caching of the canvas so there is no need to ever resize it. */
        WD_TRACE("wdResizeCanvas: Not supported (GDI+ back-end).");
        return FALSE;
    }
}
Esempio n. 7
0
BOOL
wdOpenPathSink(WD_PATHSINK* pSink, WD_HPATH hPath)
{
    if(d2d_enabled()) {
        dummy_ID2D1PathGeometry* g = (dummy_ID2D1PathGeometry*) hPath;
        dummy_ID2D1GeometrySink* s;
        HRESULT hr;

        hr = dummy_ID2D1PathGeometry_Open(g, &s);
        if(FAILED(hr)) {
            WD_TRACE_HR("wdOpenPathSink: ID2D1PathGeometry::Open() failed.");
            return FALSE;
        }

        pSink->pData = (void*) s;
        return TRUE;
    } else {
        /* GDI+ doesn't have any concept of path sink as Direct2D does, it
         * operates directly with the path object. */
        pSink->pData = (void*) hPath;
        return TRUE;
    }
}
Esempio n. 8
0
WD_HCANVAS
wdCreateCanvasWithHDC(HDC hDC, const RECT* pRect, DWORD dwFlags)
{
    if(d2d_enabled()) {
        dummy_D2D1_RENDER_TARGET_PROPERTIES props = {
            dummy_D2D1_RENDER_TARGET_TYPE_DEFAULT,
            { dummy_DXGI_FORMAT_B8G8R8A8_UNORM, dummy_D2D1_ALPHA_MODE_PREMULTIPLIED },
            0.0f, 0.0f,
            ((dwFlags & WD_CANVAS_NOGDICOMPAT) ?
                        0 : dummy_D2D1_RENDER_TARGET_USAGE_GDI_COMPATIBLE),
            dummy_D2D1_FEATURE_LEVEL_DEFAULT
        };
        d2d_canvas_t* c;
        dummy_ID2D1DCRenderTarget* target;
        HRESULT hr;

        wd_lock();
        hr = dummy_ID2D1Factory_CreateDCRenderTarget(d2d_factory, &props, &target);
        wd_unlock();
        if(FAILED(hr)) {
            WD_TRACE_HR("wdCreateCanvasWithHDC: "
                        "ID2D1Factory::CreateDCRenderTarget() failed.");
            goto err_CreateDCRenderTarget;
        }

        hr = dummy_ID2D1DCRenderTarget_BindDC(target, hDC, pRect);
        if(FAILED(hr)) {
            WD_TRACE_HR("wdCreateCanvasWithHDC: "
                        "ID2D1Factory::BindDC() failed.");
            goto err_BindDC;
        }

        c = d2d_canvas_alloc((dummy_ID2D1RenderTarget*)target, D2D_CANVASTYPE_DC,
                pRect->right - pRect->left, (dwFlags & WD_CANVAS_LAYOUTRTL));
        if(c == NULL) {
            WD_TRACE("wdCreateCanvasWithHDC: d2d_canvas_alloc() failed.");
            goto err_d2d_canvas_alloc;
        }

        /* make sure text anti-aliasing is clear type */
        dummy_ID2D1RenderTarget_SetTextAntialiasMode(c->target, dummy_D2D1_TEXT_ANTIALIAS_MODE_CLEARTYPE);

        return (WD_HCANVAS) c;

err_d2d_canvas_alloc:
err_BindDC:
        dummy_ID2D1RenderTarget_Release((dummy_ID2D1RenderTarget*)target);
err_CreateDCRenderTarget:
        return NULL;
    } else {
        BOOL use_doublebuffer = (dwFlags & WD_CANVAS_DOUBLEBUFFER);
        gdix_canvas_t* c;

        c = gdix_canvas_alloc(hDC, (use_doublebuffer ? pRect : NULL),
                pRect->right - pRect->left, (dwFlags & WD_CANVAS_LAYOUTRTL));
        if(c == NULL) {
            WD_TRACE("wdCreateCanvasWithHDC: gdix_canvas_alloc() failed.");
            return NULL;
        }
        return (WD_HCANVAS) c;
    }
}
Esempio n. 9
0
void
wdSetClip(WD_HCANVAS hCanvas, const WD_RECT* pRect, const WD_HPATH hPath)
{
    if(d2d_enabled()) {
        d2d_canvas_t* c = (d2d_canvas_t*) hCanvas;

        d2d_reset_clip(c);

        if(hPath != NULL) {
            dummy_ID2D1PathGeometry* g = (dummy_ID2D1PathGeometry*) hPath;
            dummy_D2D1_LAYER_PARAMETERS layer_params;
            HRESULT hr;

            hr = dummy_ID2D1RenderTarget_CreateLayer(c->target, NULL, &c->clip_layer);
            if(FAILED(hr)) {
                WD_TRACE_HR("wdSetClip: ID2D1RenderTarget::CreateLayer() failed.");
                return;
            }

            if(pRect != NULL) {
                layer_params.contentBounds.left = pRect->x0;
                layer_params.contentBounds.top = pRect->y0;
                layer_params.contentBounds.right = pRect->x1;
                layer_params.contentBounds.bottom = pRect->y1;
            } else {
                layer_params.contentBounds.left = FLT_MIN;
                layer_params.contentBounds.top = FLT_MIN;
                layer_params.contentBounds.right = FLT_MAX;
                layer_params.contentBounds.bottom = FLT_MAX;
            }
            layer_params.geometricMask = (dummy_ID2D1Geometry*) g;
            layer_params.maskAntialiasMode = dummy_D2D1_ANTIALIAS_MODE_PER_PRIMITIVE;
            layer_params.maskTransform._11 = 1.0f;
            layer_params.maskTransform._12 = 0.0f;
            layer_params.maskTransform._21 = 0.0f;
            layer_params.maskTransform._22 = 1.0f;
            layer_params.maskTransform._31 = 0.0f;
            layer_params.maskTransform._32 = 0.0f;
            layer_params.opacity = 1.0f;
            layer_params.opacityBrush = NULL;
            layer_params.layerOptions = dummy_D2D1_LAYER_OPTIONS_NONE;

            dummy_ID2D1RenderTarget_PushLayer(c->target, &layer_params, c->clip_layer);
        } else if(pRect != NULL) {
            dummy_ID2D1RenderTarget_PushAxisAlignedClip(c->target,
                    (const dummy_D2D1_RECT_F*) pRect, dummy_D2D1_ANTIALIAS_MODE_PER_PRIMITIVE);
            c->flags |= D2D_CANVASFLAG_RECTCLIP;
        }
    } else {
        gdix_canvas_t* c = (gdix_canvas_t*) hCanvas;
        int mode;

        if(pRect == NULL  &&  hPath == NULL) {
            gdix_vtable->fn_ResetClip(c->graphics);
            return;
        }

        mode = dummy_CombineModeReplace;

        if(pRect != NULL) {
            gdix_vtable->fn_SetClipRect(c->graphics, pRect->x0, pRect->y0,
                             pRect->x1, pRect->y1, mode);
            mode = dummy_CombineModeIntersect;
        }

        if(hPath != NULL)
            gdix_vtable->fn_SetClipPath(c->graphics, (void*) hPath, mode);
    }
}
Esempio n. 10
0
WD_HCANVAS
wdCreateCanvasWithPaintStruct(HWND hWnd, PAINTSTRUCT* pPS, DWORD dwFlags)
{
    RECT rect;

    GetClientRect(hWnd, &rect);

    if(d2d_enabled()) {
        dummy_D2D1_RENDER_TARGET_PROPERTIES props = {
            dummy_D2D1_RENDER_TARGET_TYPE_DEFAULT,
            { dummy_DXGI_FORMAT_B8G8R8A8_UNORM, dummy_D2D1_ALPHA_MODE_PREMULTIPLIED },
            0.0f, 0.0f,
            ((dwFlags & WD_CANVAS_NOGDICOMPAT) ?
                        0 : dummy_D2D1_RENDER_TARGET_USAGE_GDI_COMPATIBLE),
            dummy_D2D1_FEATURE_LEVEL_DEFAULT
        };
        dummy_D2D1_HWND_RENDER_TARGET_PROPERTIES props2;
        d2d_canvas_t* c;
        dummy_ID2D1HwndRenderTarget* target;
        HRESULT hr;

        props2.hwnd = hWnd;
        props2.pixelSize.width = rect.right - rect.left;
        props2.pixelSize.height = rect.bottom - rect.top;
        props2.presentOptions = dummy_D2D1_PRESENT_OPTIONS_NONE;

        wd_lock();
        /* Note ID2D1HwndRenderTarget is implicitly double-buffered. */
        hr = dummy_ID2D1Factory_CreateHwndRenderTarget(d2d_factory, &props, &props2, &target);
        wd_unlock();
        if(FAILED(hr)) {
            WD_TRACE_HR("wdCreateCanvasWithPaintStruct: "
                        "ID2D1Factory::CreateHwndRenderTarget() failed.");
            return NULL;
        }

        c = d2d_canvas_alloc((dummy_ID2D1RenderTarget*)target, D2D_CANVASTYPE_HWND,
                    rect.right, (dwFlags & WD_CANVAS_LAYOUTRTL));
        if(c == NULL) {
            WD_TRACE("wdCreateCanvasWithPaintStruct: d2d_canvas_alloc() failed.");
            dummy_ID2D1RenderTarget_Release((dummy_ID2D1RenderTarget*)target);
            return NULL;
        }

        /* make sure text anti-aliasing is clear type */
        dummy_ID2D1RenderTarget_SetTextAntialiasMode(c->target, dummy_D2D1_TEXT_ANTIALIAS_MODE_CLEARTYPE);

        return (WD_HCANVAS) c;
    } else {
        BOOL use_doublebuffer = (dwFlags & WD_CANVAS_DOUBLEBUFFER);
        gdix_canvas_t* c;

        c = gdix_canvas_alloc(pPS->hdc, (use_doublebuffer ? &pPS->rcPaint : NULL),
                    rect.right, (dwFlags & WD_CANVAS_LAYOUTRTL));
        if(c == NULL) {
            WD_TRACE("wdCreateCanvasWithPaintStruct: gdix_canvas_alloc() failed.");
            return NULL;
        }
        return (WD_HCANVAS) c;
    }
}