ReactOS 0.4.15-dev-7942-gd23573b
customlinecap.c
Go to the documentation of this file.
1/*
2 * Copyright (C) 2007 Google (Evan Stade)
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
17 */
18
19#include <stdarg.h>
20#include <assert.h>
21
22#include "windef.h"
23#include "winbase.h"
24#include "wingdi.h"
25
26#include "objbase.h"
27
28#include "gdiplus.h"
29#include "gdiplus_private.h"
30#include "wine/debug.h"
31
33
35 GpCustomLineCap** to)
36{
37 TRACE("(%p, %p)\n", from, to);
38
39 if(!from || !to)
40 return InvalidParameter;
41
42 if (from->type == CustomLineCapTypeDefault)
43 *to = heap_alloc_zero(sizeof(GpCustomLineCap));
44 else
45 *to = heap_alloc_zero(sizeof(GpAdjustableArrowCap));
46
47 if (!*to)
48 return OutOfMemory;
49
50 if (from->type == CustomLineCapTypeDefault)
51 **to = *from;
52 else
54
55 /* Duplicate path data */
56 (*to)->pathdata.Points = heap_alloc_zero(from->pathdata.Count * sizeof(PointF));
57 (*to)->pathdata.Types = heap_alloc_zero(from->pathdata.Count);
58
59 if((!(*to)->pathdata.Types || !(*to)->pathdata.Points) && (*to)->pathdata.Count){
60 heap_free((*to)->pathdata.Points);
61 heap_free((*to)->pathdata.Types);
62 heap_free(*to);
63 return OutOfMemory;
64 }
65
66 memcpy((*to)->pathdata.Points, from->pathdata.Points, from->pathdata.Count
67 * sizeof(PointF));
68 memcpy((*to)->pathdata.Types, from->pathdata.Types, from->pathdata.Count);
69
70 TRACE("<-- %p\n", *to);
71
72 return Ok;
73}
74
76 REAL base_inset)
77{
78 cap->fill = fill;
79
80 cap->pathdata.Points = heap_alloc_zero(pathdata->Count * sizeof(PointF));
81 cap->pathdata.Types = heap_alloc_zero(pathdata->Count);
82
83 if ((!cap->pathdata.Types || !cap->pathdata.Points) && pathdata->Count)
84 {
85 heap_free(cap->pathdata.Points);
86 heap_free(cap->pathdata.Types);
87 cap->pathdata.Points = NULL;
88 cap->pathdata.Types = NULL;
89 return OutOfMemory;
90 }
91
92 if (pathdata->Points)
93 memcpy(cap->pathdata.Points, pathdata->Points, pathdata->Count * sizeof(PointF));
94 if (pathdata->Types)
95 memcpy(cap->pathdata.Types, pathdata->Types, pathdata->Count);
96 cap->pathdata.Count = pathdata->Count;
97
98 cap->inset = base_inset;
99 cap->cap = basecap;
100 cap->join = LineJoinMiter;
101 cap->scale = 1.0;
102
103 return Ok;
104}
105
106/* FIXME: Sometimes when fillPath is non-null and stroke path is null, the native
107 * version of this function returns NotImplemented. I cannot figure out why. */
109 GpLineCap baseCap, REAL baseInset, GpCustomLineCap **customCap)
110{
111 GpPathData *pathdata;
113
114 TRACE("%p %p %d %f %p\n", fillPath, strokePath, baseCap, baseInset, customCap);
115
116 if(!customCap || !(fillPath || strokePath))
117 return InvalidParameter;
118
119 *customCap = heap_alloc_zero(sizeof(GpCustomLineCap));
120 if(!*customCap) return OutOfMemory;
121
122 if (strokePath)
123 pathdata = &strokePath->pathdata;
124 else
125 pathdata = &fillPath->pathdata;
126
127 stat = init_custom_linecap(*customCap, pathdata, fillPath != NULL, baseCap, baseInset);
128 if (stat != Ok)
129 {
130 heap_free(*customCap);
131 return stat;
132 }
133
134 TRACE("<-- %p\n", *customCap);
135
136 return Ok;
137}
138
140{
141 TRACE("(%p)\n", customCap);
142
143 if(!customCap)
144 return InvalidParameter;
145
146 heap_free(customCap->pathdata.Points);
147 heap_free(customCap->pathdata.Types);
148 heap_free(customCap);
149
150 return Ok;
151}
152
154 GpLineJoin* lineJoin)
155{
156 TRACE("(%p, %p)\n", customCap, lineJoin);
157
158 if(!customCap || !lineJoin)
159 return InvalidParameter;
160
161 *lineJoin = customCap->join;
162
163 return Ok;
164}
165
167 REAL* widthScale)
168{
169 TRACE("(%p, %p)\n", custom, widthScale);
170
171 if(!custom || !widthScale)
172 return InvalidParameter;
173
174 *widthScale = custom->scale;
175
176 return Ok;
177}
178
181{
182 static int calls;
183
184 TRACE("(%p,%u,%u)\n", custom, start, end);
185
186 if(!custom)
187 return InvalidParameter;
188
189 if(!(calls++))
190 FIXME("not implemented\n");
191
192 return NotImplemented;
193}
194
197{
198 static int calls;
199
200 TRACE("(%p,%u)\n", custom, base);
201
202 if(!(calls++))
203 FIXME("not implemented\n");
204
205 return NotImplemented;
206}
207
209 REAL* inset)
210{
211 TRACE("(%p, %p)\n", custom, inset);
212
213 if(!custom || !inset)
214 return InvalidParameter;
215
216 *inset = custom->inset;
217
218 return Ok;
219}
220
222 REAL inset)
223{
224 static int calls;
225
226 TRACE("(%p,%0.2f)\n", custom, inset);
227
228 if(!(calls++))
229 FIXME("not implemented\n");
230
231 return NotImplemented;
232}
233
234/*FIXME: LineJoin completely ignored now */
237{
238 TRACE("(%p, %d)\n", custom, join);
239
240 if(!custom)
241 return InvalidParameter;
242
243 custom->join = join;
244
245 return Ok;
246}
247
249{
250 TRACE("(%p,%0.2f)\n", custom, width);
251
252 if(!custom)
253 return InvalidParameter;
254
255 custom->scale = width;
256
257 return Ok;
258}
259
261{
262 TRACE("(%p, %p)\n", customCap, baseCap);
263
264 if(!customCap || !baseCap)
265 return InvalidParameter;
266
267 *baseCap = customCap->cap;
268
269 return Ok;
270}
271
273{
274 TRACE("(%p, %p)\n", customCap, type);
275
276 if(!customCap || !type)
277 return InvalidParameter;
278
279 *type = customCap->type;
280 return Ok;
281}
282
284{
285 static const BYTE types_filled[] =
286 {
288 };
289 static const BYTE types_unfilled[] =
290 {
292 };
294
295 assert(cap->cap.pathdata.Count == 3 || cap->cap.pathdata.Count == 4);
296
297 points = cap->cap.pathdata.Points;
298 if (cap->cap.fill)
299 {
300 memcpy(cap->cap.pathdata.Types, types_filled, sizeof(types_filled));
301 cap->cap.pathdata.Count = 4;
302 points[0].X = -cap->width / 2.0;
303 points[0].Y = -cap->height;
304 points[1].X = 0.0;
305 points[1].Y = 0.0;
306 points[2].X = cap->width / 2.0;
307 points[2].Y = -cap->height;
308 points[3].X = 0.0;
309 points[3].Y = -cap->height - cap->middle_inset;
310 }
311 else
312 {
313 memcpy(cap->cap.pathdata.Types, types_unfilled, sizeof(types_unfilled));
314 cap->cap.pathdata.Count = 3;
315 points[0].X = -cap->width / 4.0;
316 points[0].Y = -cap->height / 2.0;
317 points[1].X = 0.0;
318 points[1].Y = 0.0;
319 points[2].X = cap->width / 4.0;
320 points[2].Y = -cap->height / 2.0;
321 }
322
323 if (cap->width == 0.0)
324 cap->cap.inset = 0.0;
325 else
326 cap->cap.inset = cap->height / cap->width;
327}
328
331{
332 GpPathData pathdata;
334
335 TRACE("(%0.2f,%0.2f,%i,%p)\n", height, width, fill, cap);
336
337 if (!cap)
338 return InvalidParameter;
339
340 *cap = heap_alloc_zero(sizeof(**cap));
341 if (!*cap)
342 return OutOfMemory;
343
344 /* We'll need 4 points at most. */
345 pathdata.Count = 4;
346 pathdata.Points = NULL;
347 pathdata.Types = NULL;
348 stat = init_custom_linecap(&(*cap)->cap, &pathdata, fill, LineCapTriangle, width != 0.0 ? height / width : 0.0);
349 if (stat != Ok)
350 {
351 heap_free(*cap);
352 return stat;
353 }
354
355 (*cap)->cap.type = CustomLineCapTypeAdjustableArrow;
356 (*cap)->height = height;
357 (*cap)->width = width;
358 (*cap)->middle_inset = 0.0;
360
361 return Ok;
362}
363
365{
366 TRACE("(%p,%p)\n", cap, fill);
367
368 if (!cap || !fill)
369 return InvalidParameter;
370
371 *fill = cap->cap.fill;
372 return Ok;
373}
374
376{
377 TRACE("(%p,%p)\n", cap, height);
378
379 if (!cap || !height)
380 return InvalidParameter;
381
382 *height = cap->height;
383 return Ok;
384}
385
387{
388 TRACE("(%p,%p)\n", cap, middle);
389
390 if (!cap || !middle)
391 return InvalidParameter;
392
393 *middle = cap->middle_inset;
394 return Ok;
395}
396
398{
399 TRACE("(%p,%p)\n", cap, width);
400
401 if (!cap || !width)
402 return InvalidParameter;
403
404 *width = cap->width;
405 return Ok;
406}
407
409{
410 TRACE("(%p,%i)\n", cap, fill);
411
412 if (!cap)
413 return InvalidParameter;
414
415 cap->cap.fill = fill;
417 return Ok;
418}
419
421{
422 TRACE("(%p,%0.2f)\n", cap, height);
423
424 if (!cap)
425 return InvalidParameter;
426
427 cap->height = height;
429 return Ok;
430}
431
433{
434 TRACE("(%p,%0.2f)\n", cap, middle);
435
436 if (!cap)
437 return InvalidParameter;
438
439 cap->middle_inset = middle;
441 return Ok;
442}
443
445{
446 TRACE("(%p,%0.2f)\n", cap, width);
447
448 if (!cap)
449 return InvalidParameter;
450
451 cap->width = width;
453 return Ok;
454}
_STLP_MOVE_TO_STD_NAMESPACE void fill(_ForwardIter __first, _ForwardIter __last, const _Tp &__val)
Definition: _algobase.h:449
#define stat
Definition: acwin.h:99
static BOOL heap_free(void *mem)
Definition: appwiz.h:76
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
#define FIXME(fmt,...)
Definition: debug.h:111
#define NULL
Definition: types.h:112
float REAL
Definition: types.h:41
GpStatus WINGDIPAPI GdipGetCustomLineCapBaseCap(GpCustomLineCap *customCap, GpLineCap *baseCap)
GpStatus WINGDIPAPI GdipGetAdjustableArrowCapFillState(GpAdjustableArrowCap *cap, BOOL *fill)
GpStatus WINGDIPAPI GdipSetCustomLineCapWidthScale(GpCustomLineCap *custom, REAL width)
GpStatus WINGDIPAPI GdipCreateCustomLineCap(GpPath *fillPath, GpPath *strokePath, GpLineCap baseCap, REAL baseInset, GpCustomLineCap **customCap)
GpStatus WINGDIPAPI GdipSetCustomLineCapBaseInset(GpCustomLineCap *custom, REAL inset)
GpStatus WINGDIPAPI GdipGetCustomLineCapBaseInset(GpCustomLineCap *custom, REAL *inset)
GpStatus WINGDIPAPI GdipSetAdjustableArrowCapHeight(GpAdjustableArrowCap *cap, REAL height)
GpStatus WINGDIPAPI GdipSetAdjustableArrowCapFillState(GpAdjustableArrowCap *cap, BOOL fill)
GpStatus WINGDIPAPI GdipGetAdjustableArrowCapHeight(GpAdjustableArrowCap *cap, REAL *height)
GpStatus WINGDIPAPI GdipGetCustomLineCapStrokeJoin(GpCustomLineCap *customCap, GpLineJoin *lineJoin)
GpStatus WINGDIPAPI GdipSetCustomLineCapBaseCap(GpCustomLineCap *custom, GpLineCap base)
static void arrowcap_update_path(GpAdjustableArrowCap *cap)
GpStatus WINGDIPAPI GdipSetAdjustableArrowCapWidth(GpAdjustableArrowCap *cap, REAL width)
GpStatus WINGDIPAPI GdipSetCustomLineCapStrokeCaps(GpCustomLineCap *custom, GpLineCap start, GpLineCap end)
GpStatus WINGDIPAPI GdipGetCustomLineCapWidthScale(GpCustomLineCap *custom, REAL *widthScale)
GpStatus WINGDIPAPI GdipDeleteCustomLineCap(GpCustomLineCap *customCap)
GpStatus WINGDIPAPI GdipCloneCustomLineCap(GpCustomLineCap *from, GpCustomLineCap **to)
Definition: customlinecap.c:34
GpStatus WINGDIPAPI GdipGetCustomLineCapType(GpCustomLineCap *customCap, CustomLineCapType *type)
static GpStatus init_custom_linecap(GpCustomLineCap *cap, GpPathData *pathdata, BOOL fill, GpLineCap basecap, REAL base_inset)
Definition: customlinecap.c:75
GpStatus WINGDIPAPI GdipGetAdjustableArrowCapWidth(GpAdjustableArrowCap *cap, REAL *width)
GpStatus WINGDIPAPI GdipCreateAdjustableArrowCap(REAL height, REAL width, BOOL fill, GpAdjustableArrowCap **cap)
GpStatus WINGDIPAPI GdipSetCustomLineCapStrokeJoin(GpCustomLineCap *custom, GpLineJoin join)
GpStatus WINGDIPAPI GdipGetAdjustableArrowCapMiddleInset(GpAdjustableArrowCap *cap, REAL *middle)
GpStatus WINGDIPAPI GdipSetAdjustableArrowCapMiddleInset(GpAdjustableArrowCap *cap, REAL middle)
#define assert(x)
Definition: debug.h:53
unsigned int BOOL
Definition: ntddk_ex.h:94
LineJoin
Definition: gdiplusenums.h:105
@ LineJoinMiter
Definition: gdiplusenums.h:106
CustomLineCapType
Definition: gdiplusenums.h:77
@ CustomLineCapTypeAdjustableArrow
Definition: gdiplusenums.h:79
@ CustomLineCapTypeDefault
Definition: gdiplusenums.h:78
LineCap
Definition: gdiplusenums.h:60
@ LineCapTriangle
Definition: gdiplusenums.h:64
@ PathPointTypeLine
Definition: gdiplusenums.h:85
@ PathPointTypeCloseSubpath
Definition: gdiplusenums.h:90
@ PathPointTypeStart
Definition: gdiplusenums.h:84
#define WINGDIPAPI
Definition: gdiplusflat.h:22
Status
Definition: gdiplustypes.h:25
@ Ok
Definition: gdiplustypes.h:26
@ InvalidParameter
Definition: gdiplustypes.h:28
@ OutOfMemory
Definition: gdiplustypes.h:29
@ NotImplemented
Definition: gdiplustypes.h:32
GLuint start
Definition: gl.h:1545
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLuint GLuint end
Definition: gl.h:1545
GLint GLint GLsizei GLsizei height
Definition: gl.h:1546
GLint GLint GLsizei width
Definition: gl.h:1546
GLenum cap
Definition: glext.h:9639
GLsizei const GLfloat * points
Definition: glext.h:8112
LOCAL int join(int *aux, int a, int b)
Definition: match.c:560
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define TRACE(s)
Definition: solgame.cpp:4
CardRegion * from
Definition: spigame.cpp:19
GpPathData pathdata
CustomLineCapType type
GpPathData pathdata
PointF * Points
Definition: gdiplustypes.h:655
BYTE * Types
Definition: gdiplustypes.h:656
Definition: stat.h:55
unsigned char BYTE
Definition: xxhash.c:193