Something went wrong. Try again.
Reactos
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331/* * Copyright (C) 2007 Google (Evan Stade) * Copyright (C) 2008 Nikolay Sivov <bunglehead at gmail dot com> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */
#include <stdarg.h>
#include "windef.h"#include "winbase.h"#include "wingdi.h"
#include "objbase.h"
#include "gdiplus.h"#include "gdiplus_private.h"#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(gdiplus);
GpStatus WINGDIPAPI GdipCreatePathIter(GpPathIterator **iterator, GpPath* path){ INT size;
TRACE("(%p, %p)\n", iterator, path);
if(!iterator) return InvalidParameter;
*iterator = heap_alloc_zero(sizeof(GpPathIterator)); if(!*iterator) return OutOfMemory;
if(path){ size = path->pathdata.Count;
(*iterator)->pathdata.Types = heap_alloc_zero(size); (*iterator)->pathdata.Points = heap_alloc_zero(size * sizeof(PointF));
memcpy((*iterator)->pathdata.Types, path->pathdata.Types, size); memcpy((*iterator)->pathdata.Points, path->pathdata.Points,size * sizeof(PointF)); (*iterator)->pathdata.Count = size; } else{ (*iterator)->pathdata.Types = NULL; (*iterator)->pathdata.Points = NULL; (*iterator)->pathdata.Count = 0; }
(*iterator)->subpath_pos = 0; (*iterator)->marker_pos = 0; (*iterator)->pathtype_pos = 0;
return Ok;}
GpStatus WINGDIPAPI GdipDeletePathIter(GpPathIterator *iter){ TRACE("(%p)\n", iter);
if(!iter) return InvalidParameter;
heap_free(iter->pathdata.Types); heap_free(iter->pathdata.Points); heap_free(iter);
return Ok;}
GpStatus WINGDIPAPI GdipPathIterCopyData(GpPathIterator* iterator, INT* resultCount, GpPointF* points, BYTE* types, INT startIndex, INT endIndex){ TRACE("(%p, %p, %p, %p, %d, %d)\n", iterator, resultCount, points, types, startIndex, endIndex);
if(!iterator || !types || !points) return InvalidParameter;
if(endIndex > iterator->pathdata.Count - 1 || startIndex < 0 || endIndex < startIndex){ *resultCount = 0; return Ok; }
*resultCount = endIndex - startIndex + 1;
memcpy(types, &(iterator->pathdata.Types[startIndex]), *resultCount); memcpy(points, &(iterator->pathdata.Points[startIndex]), *resultCount * sizeof(PointF));
return Ok;}
GpStatus WINGDIPAPI GdipPathIterHasCurve(GpPathIterator* iterator, BOOL* hasCurve){ INT i;
TRACE("(%p, %p)\n", iterator, hasCurve);
if(!iterator) return InvalidParameter;
*hasCurve = FALSE;
for(i = 0; i < iterator->pathdata.Count; i++) if((iterator->pathdata.Types[i] & PathPointTypePathTypeMask) == PathPointTypeBezier){ *hasCurve = TRUE; break; }
return Ok;}
GpStatus WINGDIPAPI GdipPathIterGetSubpathCount(GpPathIterator* iterator, INT* count){ INT i;
TRACE("(%p, %p)\n", iterator, count);
if(!iterator || !count) return InvalidParameter;
*count = 0; for(i = 0; i < iterator->pathdata.Count; i++){ if(iterator->pathdata.Types[i] == PathPointTypeStart) (*count)++; }
return Ok;}
GpStatus WINGDIPAPI GdipPathIterNextMarker(GpPathIterator* iterator, INT *resultCount, INT* startIndex, INT* endIndex){ INT i;
TRACE("(%p, %p, %p, %p)\n", iterator, resultCount, startIndex, endIndex);
if(!iterator || !startIndex || !endIndex) return InvalidParameter;
*resultCount = 0;
/* first call could start with second point as all subsequent, cause path couldn't contain only one */ for(i = iterator->marker_pos + 1; i < iterator->pathdata.Count; i++){ if((iterator->pathdata.Types[i] & PathPointTypePathMarker) || (i == iterator->pathdata.Count - 1)){ *startIndex = iterator->marker_pos; if(iterator->marker_pos > 0) (*startIndex)++; *endIndex = iterator->marker_pos = i; *resultCount= *endIndex - *startIndex + 1; break; } }
return Ok;}
GpStatus WINGDIPAPI GdipPathIterNextMarkerPath(GpPathIterator* iterator, INT* result, GpPath* path){ INT start, end;
TRACE("(%p, %p, %p)\n", iterator, result, path);
if(!iterator || !result) return InvalidParameter;
GdipPathIterNextMarker(iterator, result, &start, &end); /* return path */ if(((*result) > 0) && path){ GdipResetPath(path);
if(!lengthen_path(path, *result)) return OutOfMemory;
memcpy(path->pathdata.Points, &(iterator->pathdata.Points[start]), sizeof(GpPointF)*(*result)); memcpy(path->pathdata.Types, &(iterator->pathdata.Types[start]), sizeof(BYTE)*(*result)); path->pathdata.Count = *result; }
return Ok;}
GpStatus WINGDIPAPI GdipPathIterNextSubpath(GpPathIterator* iterator, INT *resultCount, INT* startIndex, INT* endIndex, BOOL* isClosed){ INT i, count;
TRACE("(%p, %p, %p, %p, %p)\n", iterator, resultCount, startIndex, endIndex, isClosed);
if(!iterator || !startIndex || !endIndex || !isClosed || !resultCount) return InvalidParameter;
count = iterator->pathdata.Count;
/* iterator created with NULL path */ if(count == 0){ *resultCount = 0; return Ok; }
if(iterator->subpath_pos == count){ *startIndex = *endIndex = *resultCount = 0; *isClosed = TRUE; return Ok; }
*startIndex = iterator->subpath_pos;
for(i = iterator->subpath_pos + 1; i < count && !(iterator->pathdata.Types[i] == PathPointTypeStart); i++);
*endIndex = i - 1; iterator->subpath_pos = i;
*resultCount = *endIndex - *startIndex + 1;
if(iterator->pathdata.Types[*endIndex] & PathPointTypeCloseSubpath) *isClosed = TRUE; else *isClosed = FALSE;
return Ok;}GpStatus WINGDIPAPI GdipPathIterRewind(GpPathIterator *iterator){ TRACE("(%p)\n", iterator);
if(!iterator) return InvalidParameter;
iterator->subpath_pos = 0; iterator->marker_pos = 0; iterator->pathtype_pos = 0;
return Ok;}
GpStatus WINGDIPAPI GdipPathIterGetCount(GpPathIterator* iterator, INT* count){ TRACE("(%p, %p)\n", iterator, count);
if(!iterator || !count) return InvalidParameter;
*count = iterator->pathdata.Count;
return Ok;}
GpStatus WINGDIPAPI GdipPathIterEnumerate(GpPathIterator* iterator, INT* resultCount, GpPointF *points, BYTE *types, INT count){ TRACE("(%p, %p, %p, %p, %d)\n", iterator, resultCount, points, types, count);
if((count < 0) || !resultCount) return InvalidParameter;
if(count == 0){ *resultCount = 0; return Ok; }
return GdipPathIterCopyData(iterator, resultCount, points, types, 0, count-1);}
GpStatus WINGDIPAPI GdipPathIterIsValid(GpPathIterator* iterator, BOOL* valid){ TRACE("(%p, %p)\n", iterator, valid);
if(!iterator || !valid) return InvalidParameter;
*valid = TRUE;
return Ok;}
GpStatus WINGDIPAPI GdipPathIterNextPathType(GpPathIterator* iter, INT* result, BYTE* type, INT* start, INT* end){ FIXME("(%p, %p, %p, %p, %p) stub\n", iter, result, type, start, end);
if(!iter || !result || !type || !start || !end) return InvalidParameter;
return NotImplemented;}
GpStatus WINGDIPAPI GdipPathIterNextSubpathPath(GpPathIterator* iter, INT* result, GpPath* path, BOOL* closed){ INT start, end;
TRACE("(%p, %p, %p, %p)\n", iter, result, path, closed);
if(!iter || !result || !closed) return InvalidParameter;
GdipPathIterNextSubpath(iter, result, &start, &end, closed); /* return path */ if(((*result) > 0) && path){ GdipResetPath(path);
if(!lengthen_path(path, *result)) return OutOfMemory;
memcpy(path->pathdata.Points, &(iter->pathdata.Points[start]), sizeof(GpPointF)*(*result)); memcpy(path->pathdata.Types, &(iter->pathdata.Types[start]), sizeof(BYTE)*(*result)); path->pathdata.Count = *result; }
return Ok;}