ReactOS  0.4.14-dev-342-gdc047f9
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;
112  GpStatus stat;
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 
196  GpLineCap base)
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  };
293  GpPointF *points;
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;
333  GpStatus stat;
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 }
GpStatus WINGDIPAPI GdipSetCustomLineCapStrokeCaps(GpCustomLineCap *custom, GpLineCap start, GpLineCap end)
GpStatus WINGDIPAPI GdipCreateCustomLineCap(GpPath *fillPath, GpPath *strokePath, GpLineCap baseCap, REAL baseInset, GpCustomLineCap **customCap)
GLint GLint GLsizei width
Definition: gl.h:1546
GpStatus WINGDIPAPI GdipGetCustomLineCapWidthScale(GpCustomLineCap *custom, REAL *widthScale)
GpStatus WINGDIPAPI GdipGetCustomLineCapBaseInset(GpCustomLineCap *custom, REAL *inset)
GpStatus WINGDIPAPI GdipSetCustomLineCapBaseCap(GpCustomLineCap *custom, GpLineCap base)
BYTE * Types
Definition: gdiplustypes.h:256
GpStatus WINGDIPAPI GdipGetAdjustableArrowCapWidth(GpAdjustableArrowCap *cap, REAL *width)
GpPathData pathdata
GpStatus WINGDIPAPI GdipGetCustomLineCapType(GpCustomLineCap *customCap, CustomLineCapType *type)
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
#define assert(x)
Definition: debug.h:53
LineJoin
Definition: gdiplusenums.h:103
static GpStatus init_custom_linecap(GpCustomLineCap *cap, GpPathData *pathdata, BOOL fill, GpLineCap basecap, REAL base_inset)
Definition: customlinecap.c:75
GLuint GLuint end
Definition: gl.h:1545
GpStatus WINGDIPAPI GdipDeleteCustomLineCap(GpCustomLineCap *customCap)
static void arrowcap_update_path(GpAdjustableArrowCap *cap)
GLenum cap
Definition: glext.h:9639
unsigned int BOOL
Definition: ntddk_ex.h:94
#define FIXME(fmt,...)
Definition: debug.h:110
#define WINGDIPAPI
Definition: gdiplusflat.h:22
smooth NULL
Definition: ftsmooth.c:416
GpStatus WINGDIPAPI GdipGetAdjustableArrowCapHeight(GpAdjustableArrowCap *cap, REAL *height)
LOCAL int join(int *aux, int a, int b)
Definition: match.c:560
WINE_DEFAULT_DEBUG_CHANNEL(gdiplus)
#define TRACE(s)
Definition: solgame.cpp:4
GpStatus WINGDIPAPI GdipSetAdjustableArrowCapFillState(GpAdjustableArrowCap *cap, BOOL fill)
CustomLineCapType type
_STLP_MOVE_TO_STD_NAMESPACE void fill(_ForwardIter __first, _ForwardIter __last, const _Tp &__val)
Definition: _algobase.h:449
LineCap
Definition: gdiplusenums.h:59
GpStatus WINGDIPAPI GdipSetAdjustableArrowCapWidth(GpAdjustableArrowCap *cap, REAL width)
GpStatus WINGDIPAPI GdipSetAdjustableArrowCapHeight(GpAdjustableArrowCap *cap, REAL height)
GLsizei const GLfloat * points
Definition: glext.h:8112
Definition: stat.h:55
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
unsigned char BYTE
Definition: mem.h:68
GpStatus WINGDIPAPI GdipCloneCustomLineCap(GpCustomLineCap *from, GpCustomLineCap **to)
Definition: customlinecap.c:34
GpStatus WINGDIPAPI GdipSetCustomLineCapWidthScale(GpCustomLineCap *custom, REAL width)
GLint GLint GLsizei GLsizei height
Definition: gl.h:1546
Status
Definition: gdiplustypes.h:24
GpStatus WINGDIPAPI GdipCreateAdjustableArrowCap(REAL height, REAL width, BOOL fill, GpAdjustableArrowCap **cap)
GpStatus WINGDIPAPI GdipGetCustomLineCapBaseCap(GpCustomLineCap *customCap, GpLineCap *baseCap)
_CRTIMP int __cdecl stat(const char *_Filename, struct stat *_Stat)
Definition: stat.h:345
GpStatus WINGDIPAPI GdipGetAdjustableArrowCapMiddleInset(GpAdjustableArrowCap *cap, REAL *middle)
GpPathData pathdata
GpStatus WINGDIPAPI GdipSetAdjustableArrowCapMiddleInset(GpAdjustableArrowCap *cap, REAL middle)
GLuint start
Definition: gl.h:1545
GpStatus WINGDIPAPI GdipSetCustomLineCapStrokeJoin(GpCustomLineCap *custom, GpLineJoin join)
PointF * Points
Definition: gdiplustypes.h:255
GpStatus WINGDIPAPI GdipGetCustomLineCapStrokeJoin(GpCustomLineCap *customCap, GpLineJoin *lineJoin)
CustomLineCapType
Definition: gdiplusenums.h:76
float REAL
Definition: types.h:41
CardRegion * from
Definition: spigame.cpp:19
GpStatus WINGDIPAPI GdipSetCustomLineCapBaseInset(GpCustomLineCap *custom, REAL inset)
GpStatus WINGDIPAPI GdipGetAdjustableArrowCapFillState(GpAdjustableArrowCap *cap, BOOL *fill)
static BOOL heap_free(void *mem)
Definition: appwiz.h:75