Skip to content

Commit ea6d581

Browse files
authored
Merge pull request #50 from jingwood/feature/layerMask
add layer operation APIs, wip
2 parents 9785e45 + 8f077e1 commit ea6d581

File tree

12 files changed

+240
-46
lines changed

12 files changed

+240
-46
lines changed

src/D2DLibExport/D2DDevice.cs

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -98,13 +98,13 @@ public D2DRadialGradientBrush CreateRadialGradientBrush(D2DPoint origin, D2DPoin
9898
public D2DRectangleGeometry CreateRectangleGeometry(FLOAT width, FLOAT height)
9999
{
100100
var rect = new D2DRect(0, 0, width, height);
101-
return CreateRectangleGeometry(ref rect);
101+
return CreateRectangleGeometry(rect);
102102
}
103103

104-
public D2DRectangleGeometry CreateRectangleGeometry(ref D2DRect rect)
104+
public D2DRectangleGeometry CreateRectangleGeometry(D2DRect rect)
105105
{
106-
HANDLE rectHandle = D2D.CreateRectangleGeometry(this.Handle, ref rect);
107-
return new D2DRectangleGeometry(this.Handle, rectHandle);
106+
HANDLE rectGeometryHandle = D2D.CreateRectangleGeometry(this.Handle, ref rect);
107+
return new D2DRectangleGeometry(this.Handle, rectGeometryHandle);
108108
}
109109

110110
public D2DPathGeometry CreatePathGeometry()
@@ -113,7 +113,13 @@ public D2DPathGeometry CreatePathGeometry()
113113
return new D2DPathGeometry(this.Handle, geoHandle);
114114
}
115115

116-
public D2DGeometry CreatePieGeometry(D2DPoint origin, D2DSize size, float startAngle, float endAngle)
116+
public D2DGeometry CreateEllipseGeometry(D2DPoint origin, D2DSize size)
117+
{
118+
var ellipse = new D2DEllipse(origin, size);
119+
return new D2DGeometry(this.Handle, D2D.CreateEllipseGeometry(this.Handle, ref ellipse));
120+
}
121+
122+
public D2DGeometry CreatePieGeometry(D2DPoint origin, D2DSize size, float startAngle, float endAngle)
117123
{
118124
var path = this.CreatePathGeometry();
119125

@@ -171,6 +177,11 @@ public D2DBitmap CreateBitmapFromGDIBitmap(System.Drawing.Bitmap bmp)
171177
return this.CreateBitmapFromGDIBitmap(bmp, useAlphaChannel);
172178
}
173179

180+
public D2DLayer CreateLayer()
181+
{
182+
return new D2DLayer(D2D.CreateLayer(this.Handle));
183+
}
184+
174185
[DllImport("gdi32.dll")]
175186
public static extern bool DeleteObject(IntPtr obj);
176187

src/D2DLibExport/D2DGeometry.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,5 +59,11 @@ public D2DRect GetBounds()
5959
D2D.GetGeometryBounds(this.Handle, ref rect);
6060
return rect;
6161
}
62+
63+
public override void Dispose()
64+
{
65+
if (this.Handle != IntPtr.Zero) D2D.DestroyGeometry(this.Handle);
66+
this.handle = IntPtr.Zero;
67+
}
6268
}
6369
}

src/D2DLibExport/D2DGraphics.cs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,30 @@ public void PopClip()
231231
D2D.PopClip(this.Handle);
232232
}
233233

234+
public D2DLayer PushLayer(D2DGeometry geometry = null)
235+
{
236+
// FIXME: resolve to not use magic number
237+
D2DRect rectBounds = new D2DRect(-999999, -999999, 999999999, 999999999);
238+
239+
return PushLayer(rectBounds, geometry);
240+
}
241+
242+
public D2DLayer PushLayer(D2DRect rectBounds, D2DGeometry geometry = null)
243+
{
244+
var layer = this.Device.CreateLayer();
245+
return PushLayer(layer, rectBounds, geometry);
246+
}
247+
248+
public D2DLayer PushLayer(D2DLayer layer, D2DRect rectBounds, D2DGeometry geometry = null) {
249+
D2D.PushLayer(this.Handle, layer.Handle, ref rectBounds, geometry != null ? geometry.Handle : IntPtr.Zero);
250+
return layer;
251+
}
252+
253+
public void PopLayer()
254+
{
255+
D2D.PopLayer(this.Handle);
256+
}
257+
234258
public void SetTransform(D2DMatrix3x2 mat)
235259
{
236260
D2D.SetTransform(this.Handle, ref mat);

src/D2DLibExport/D2DLayer.cs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
5+
6+
using HANDLE = System.IntPtr;
7+
8+
namespace unvell.D2DLib
9+
{
10+
public class D2DLayer : D2DObject
11+
{
12+
public D2DLayer(HANDLE layerHandle)
13+
: base(layerHandle)
14+
{
15+
}
16+
}
17+
}

src/D2DLibExport/D2DLib.cs

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,16 @@ public static extern void PushClip([In] HANDLE context, [In] ref D2DRect rect,
123123
[DllImport(DLL_NAME, CallingConvention = CallingConvention.Cdecl)]
124124
public static extern void PopClip([In] HANDLE context);
125125

126-
[DllImport(DLL_NAME, CallingConvention = CallingConvention.Cdecl)]
126+
[DllImport(DLL_NAME, CallingConvention = CallingConvention.Cdecl)]
127+
public static extern HANDLE CreateLayer(HANDLE ctx);
128+
[DllImport(DLL_NAME, CallingConvention = CallingConvention.Cdecl)]
129+
public static extern HANDLE PushLayer(HANDLE ctx, HANDLE layerHandle, ref D2DRect contentBounds,
130+
[In, Optional] HANDLE geometryHandle, [In, Optional] HANDLE opacityBrush,
131+
LayerOptions layerOptions = LayerOptions.InitializeForClearType);
132+
[DllImport(DLL_NAME, CallingConvention = CallingConvention.Cdecl)]
133+
public static extern void PopLayer(HANDLE ctx);
134+
135+
[DllImport(DLL_NAME, CallingConvention = CallingConvention.Cdecl)]
127136
public static extern void PushTransform([In] HANDLE context);
128137
[DllImport(DLL_NAME, CallingConvention = CallingConvention.Cdecl)]
129138
public static extern void PopTransform([In] HANDLE context);
@@ -215,7 +224,19 @@ public static extern void MeasureText([In] HANDLE ctx, [In] string text, [In] st
215224
[DllImport(DLL_NAME, CallingConvention = CallingConvention.Cdecl)]
216225
public static extern HANDLE CreateRectangleGeometry([In] HANDLE ctx, [In] ref D2DRect rect);
217226

218-
[DllImport(DLL_NAME, CallingConvention = CallingConvention.Cdecl)]
227+
[DllImport(DLL_NAME, CallingConvention = CallingConvention.Cdecl)]
228+
public static extern void DestroyGeometry(HANDLE geometryContext);
229+
230+
[DllImport(DLL_NAME, CallingConvention = CallingConvention.Cdecl)]
231+
public static extern HANDLE CreateEllipseGeometry(HANDLE ctx, ref D2DEllipse ellipse);
232+
233+
[DllImport(DLL_NAME, CallingConvention = CallingConvention.Cdecl)]
234+
public static extern HANDLE CreatePathGeometry(HANDLE ctx);
235+
236+
[DllImport(DLL_NAME, CallingConvention = CallingConvention.Cdecl)]
237+
public static extern void DestroyPathGeometry(HANDLE ctx);
238+
239+
[DllImport(DLL_NAME, CallingConvention = CallingConvention.Cdecl)]
219240
public static extern void FillGeometryWithBrush([In] HANDLE ctx, [In] HANDLE geoHandle,
220241
[In] HANDLE brushHandle, [Optional] HANDLE opacityBrushHandle);
221242

@@ -227,12 +248,6 @@ public static extern void DrawPolygon(HANDLE ctx, D2DPoint[] points, UINT count,
227248
public static extern void DrawPolygonWithBrush(HANDLE ctx, D2DPoint[] points, UINT count,
228249
D2DColor strokeColor, FLOAT strokeWidth, D2DDashStyle dashStyle, HANDLE brushHandler);
229250

230-
[DllImport(DLL_NAME, CallingConvention = CallingConvention.Cdecl)]
231-
public static extern HANDLE CreatePathGeometry(HANDLE ctx);
232-
233-
[DllImport(DLL_NAME, CallingConvention = CallingConvention.Cdecl)]
234-
public static extern void DestroyPathGeometry(HANDLE ctx);
235-
236251
[DllImport(DLL_NAME, CallingConvention = CallingConvention.Cdecl)]
237252
public static extern void SetPathStartPoint(HANDLE ctx, D2DPoint startPoint);
238253

src/D2DLibExport/D2DPathGeometry.cs

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -64,12 +64,13 @@ public void AddBeziers(D2DBezierSegment[] bezierSegments)
6464
D2D.AddPathBeziers(this.Handle, bezierSegments);
6565
}
6666

67-
public void AddEllipse(D2DEllipse ellipse)
68-
{
69-
D2D.AddPathEllipse(this.Handle, ref ellipse);
70-
}
67+
// TODO: unnecessary API and it doesn't work very well, consider to remove
68+
//public void AddEllipse(D2DEllipse ellipse)
69+
//{
70+
// D2D.AddPathEllipse(this.Handle, ref ellipse);
71+
//}
7172

72-
public void AddArc(D2DPoint endPoint, D2DSize size, FLOAT sweepAngle,
73+
public void AddArc(D2DPoint endPoint, D2DSize size, FLOAT sweepAngle,
7374
D2D1_ARC_SIZE arcSize = D2D1_ARC_SIZE.D2D1_ARC_SIZE_SMALL,
7475
D2D1_SWEEP_DIRECTION sweepDirection = D2D1_SWEEP_DIRECTION.D2D1_SWEEP_DIRECTION_CLOCKWISE)
7576
{
@@ -93,7 +94,8 @@ public void ClosePath()
9394

9495
public override void Dispose()
9596
{
96-
D2D.DestroyPathGeometry(this.Handle);
97+
if (this.Handle != IntPtr.Zero) D2D.DestroyPathGeometry(this.Handle);
98+
this.handle = IntPtr.Zero;
9799
}
98100
}
99101
}

src/Examples/Examples.csproj

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,10 @@
1313
<ProjectReference Include="..\D2DWinForm\D2DWinForm.csproj" IncludeAssets="contentFiles" />
1414
</ItemGroup>
1515

16+
<ItemGroup>
17+
<Compile Update="SampleCode\ClipMaskDraw.cs">
18+
<SubType>Form</SubType>
19+
</Compile>
20+
</ItemGroup>
21+
1622
</Project>
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
/*
2+
* MIT License
3+
*
4+
* Copyright (c) 2009-2018 Jingwood, unvell.com. All right reserved.
5+
*
6+
* Permission is hereby granted, free of charge, to any person obtaining a copy
7+
* of this software and associated documentation files (the "Software"), to deal
8+
* in the Software without restriction, including without limitation the rights
9+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
* copies of the Software, and to permit persons to whom the Software is
11+
* furnished to do so, subject to the following conditions:
12+
*
13+
* The above copyright notice and this permission notice shall be included in all
14+
* copies or substantial portions of the Software.
15+
*
16+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22+
* SOFTWARE.
23+
*/
24+
25+
using System;
26+
using System.Collections.Generic;
27+
using System.Drawing;
28+
using System.Windows.Forms;
29+
using unvell.D2DLib.WinForm;
30+
31+
namespace unvell.D2DLib.Examples.SampleCode
32+
{
33+
public partial class ClipMaskDraw : ExampleForm
34+
{
35+
public ClipMaskDraw()
36+
{
37+
Text = "ClipMaskDraw - d2dlib Examples";
38+
39+
AnimationDraw = true;
40+
}
41+
42+
double offsetX = 0;
43+
double waveWidth = 100;
44+
double t = 0;
45+
46+
protected override void OnRender(D2DGraphics g)
47+
{
48+
using (var path = this.Device.CreateEllipseGeometry(
49+
new D2DPoint((float)(340 + waveWidth * offsetX), 200), new D2DSize(130, 130)))
50+
{
51+
using (var layer = g.PushLayer(path))
52+
{
53+
g.FillRectangle(ClientRectangle, new D2DColor(.7f, .7f, .7f));
54+
55+
g.DrawText("Text drawed via Direct2D API (d2dlib)", D2DColor.Blue, "Arial", 24, 140, 180);
56+
57+
g.PopLayer();
58+
}
59+
}
60+
}
61+
62+
protected override void OnFrame()
63+
{
64+
offsetX = Math.Sin(t);
65+
t += .03;
66+
67+
SceneChanged = true;
68+
}
69+
}
70+
71+
}

src/d2dlib/Context.cpp

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -31,14 +31,6 @@
3131
#include <stack>
3232
using namespace std;
3333

34-
// This is the constructor of a class that has been exported.
35-
// see D2DLib.h for the class definition
36-
//CD2DLib::CD2DLib()
37-
//{
38-
// return;
39-
//}
40-
41-
// This is an example of an exported function.
4234
HANDLE CreateContext(HWND hwnd)
4335
{
4436
D2DContext* context = new D2DContext();
@@ -317,15 +309,23 @@ HANDLE CreateLayer(HANDLE ctx)
317309
return (HANDLE)layer;
318310
}
319311

320-
void PushLayer(HANDLE ctx, HANDLE layerHandle, D2D1_RECT_F& contentBounds, __in_opt ID2D1Brush* opacityBrush,
321-
D2D1_LAYER_OPTIONS layerOptions)
312+
void PushLayer(HANDLE ctx, HANDLE layerHandle, D2D1_RECT_F& contentBounds, __in_opt HANDLE geometryHandle,
313+
__in_opt ID2D1Brush* opacityBrush, D2D1_LAYER_OPTIONS layerOptions)
322314
{
323315
RetrieveContext(ctx);
324316

317+
ID2D1Geometry* geometry = NULL;
318+
319+
if (geometryHandle != NULL) {
320+
D2DGeometryContext* geometryContext = reinterpret_cast<D2DGeometryContext*>(geometryHandle);
321+
geometry = geometryContext->geometry;
322+
}
323+
324+
D2D1_LAYER_PARAMETERS params = D2D1::LayerParameters(contentBounds, geometry,
325+
D2D1_ANTIALIAS_MODE_PER_PRIMITIVE, D2D1::IdentityMatrix(), 1, opacityBrush, layerOptions);
326+
325327
ID2D1Layer* layer = reinterpret_cast<ID2D1Layer*>(layerHandle);
326-
context->renderTarget->PushLayer(
327-
D2D1::LayerParameters(contentBounds, NULL, D2D1_ANTIALIAS_MODE_PER_PRIMITIVE,
328-
D2D1::IdentityMatrix(), 1, opacityBrush, layerOptions), layer);
328+
context->renderTarget->PushLayer(&params, layer);
329329
}
330330

331331
void PopLayer(HANDLE ctx)

src/d2dlib/Context.h

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,11 +58,30 @@ typedef struct D2DContext
5858
};
5959

6060
std::stack<D2D1_MATRIX_3X2_F>* matrixStack;
61+
//std::stack<ID2D1Layer*> layerStack;
6162

6263
HRESULT lastErrorCode;
6364

6465
} D2DContext;
6566

67+
typedef enum GeometryType {
68+
GeoType_RectangleGeometry,
69+
GeoType_PathGeometry,
70+
};
71+
72+
typedef struct D2DGeometryContext {
73+
D2DContext* d2context;
74+
ID2D1Geometry* geometry;
75+
} D2DGeometryContext;
76+
77+
typedef struct D2DPathContext : D2DGeometryContext
78+
{
79+
ID2D1PathGeometry* path;
80+
ID2D1GeometrySink* sink;
81+
bool isOpen;
82+
bool isClosed;
83+
} D2DPathContext;
84+
6685
//typedef struct D2DBitmapRenderTargetContext
6786
//{
6887
// ID2D1Factory *factory;
@@ -131,7 +150,8 @@ extern "C"
131150

132151
D2DLIB_API HANDLE CreateLayer(HANDLE context);
133152
D2DLIB_API void PushLayer(HANDLE ctx, HANDLE layerHandle, D2D1_RECT_F& contentBounds = D2D1::InfiniteRect(),
134-
__in_opt ID2D1Brush *opacityBrush = NULL, D2D1_LAYER_OPTIONS layerOptions = D2D1_LAYER_OPTIONS_NONE);
153+
__in_opt HANDLE geometryHandle = NULL, __in_opt ID2D1Brush *opacityBrush = NULL,
154+
D2D1_LAYER_OPTIONS layerOptions = D2D1_LAYER_OPTIONS_NONE);
135155
D2DLIB_API void PopLayer(HANDLE ctx);
136156

137157
D2DLIB_API HRESULT GetLastErrorCode(HANDLE ctx);

0 commit comments

Comments
 (0)