1use std::mem;
23use std::ptr::null_mut;
24
25use winapi::Interface;
26use winapi::ctypes::{c_void};
27use winapi::um::d2d1::*;
28use winapi::um::dcommon::*;
29use winapi::um::winuser::*;
30use winapi::shared::dxgi::*;
31use winapi::shared::dxgi1_2::*;
32use winapi::shared::dxgiformat::*;
33use winapi::shared::windef::*;
34use winapi::shared::winerror::*;
35
36use direct2d;
37use direct2d::enums::{AlphaMode, RenderTargetType};
38use direct2d::render_target::{DxgiSurfaceRenderTarget, GenericRenderTarget, HwndRenderTarget};
39
40use Error;
41use util::as_result;
42
43pub struct PaintCtx<'a> {
45 pub(crate) d2d_factory: &'a direct2d::Factory,
46 pub(crate) render_target: &'a mut GenericRenderTarget,
47}
48
49pub(crate) unsafe fn create_render_target(d2d_factory: &direct2d::Factory, hwnd: HWND)
50 -> Result<HwndRenderTarget, Error>
51{
52 let mut rect: RECT = mem::uninitialized();
53 GetClientRect(hwnd, &mut rect);
54 let width = (rect.right - rect.left) as u32;
55 let height = (rect.bottom - rect.top) as u32;
56 let res = HwndRenderTarget::create(d2d_factory)
57 .with_hwnd(hwnd)
58 .with_target_type(RenderTargetType::Default)
59 .with_alpha_mode(AlphaMode::Unknown)
60 .with_pixel_size(width, height)
61 .build();
62 if let Err(ref e) = res {
63 println!("Error creating hwnd render target: {:?}", e);
64 }
65 res.map_err(|_| Error::D2Error)
66}
67
68pub(crate) unsafe fn create_render_target_dxgi(d2d_factory: &direct2d::Factory,
72 swap_chain: *mut IDXGISwapChain1, dpi: f32) -> Result<DxgiSurfaceRenderTarget, Error>
73{
74 let mut buffer: *mut IDXGISurface = null_mut();
75 as_result((*swap_chain).GetBuffer(0, &IDXGISurface::uuidof(),
76 &mut buffer as *mut _ as *mut *mut c_void))?;
77 let props = D2D1_RENDER_TARGET_PROPERTIES {
78 _type: D2D1_RENDER_TARGET_TYPE_DEFAULT,
79 pixelFormat: D2D1_PIXEL_FORMAT {
80 format: DXGI_FORMAT_B8G8R8A8_UNORM,
81 alphaMode: D2D1_ALPHA_MODE_IGNORE,
82 },
83 dpiX: dpi,
84 dpiY: dpi,
85 usage: D2D1_RENDER_TARGET_USAGE_NONE,
86 minLevel: D2D1_FEATURE_LEVEL_DEFAULT,
87 };
88
89 let mut render_target: *mut ID2D1RenderTarget = null_mut();
90 let res = (*d2d_factory.get_raw()).CreateDxgiSurfaceRenderTarget(
91 buffer, &props, &mut render_target);
92 (*buffer).Release();
93 if SUCCEEDED(res) {
94 Ok(DxgiSurfaceRenderTarget::from_raw(render_target))
96 } else {
97 Err(res.into())
98 }
99}
100
101impl<'a> PaintCtx<'a> {
102
103 pub fn d2d_factory(&self) -> &direct2d::Factory {
106 self.d2d_factory
107 }
108
109 pub fn render_target(&mut self) -> &mut GenericRenderTarget {
112 self.render_target
113 }
114}