예제 #1
0
파일: region.c 프로젝트: AmesianX/RosWine
static inline GpStatus clone_element(const region_element* element,
        region_element** element2)
{
    GpStatus stat;

    /* root node is allocated with GpRegion */
    if(!*element2){
        *element2 = GdipAlloc(sizeof(region_element));
        if (!*element2)
            return OutOfMemory;
    }

    (*element2)->type = element->type;

    switch (element->type)
    {
        case RegionDataRect:
            (*element2)->elementdata.rect = element->elementdata.rect;
            break;
        case RegionDataEmptyRect:
        case RegionDataInfiniteRect:
            break;
        case RegionDataPath:
            (*element2)->elementdata.pathdata.pathheader = element->elementdata.pathdata.pathheader;
            stat = GdipClonePath(element->elementdata.pathdata.path,
                    &(*element2)->elementdata.pathdata.path);
            if (stat != Ok) goto clone_out;
            break;
        default:
            (*element2)->elementdata.combine.left  = NULL;
            (*element2)->elementdata.combine.right = NULL;

            stat = clone_element(element->elementdata.combine.left,
                    &(*element2)->elementdata.combine.left);
            if (stat != Ok) goto clone_out;
            stat = clone_element(element->elementdata.combine.right,
                    &(*element2)->elementdata.combine.right);
            if (stat != Ok) goto clone_out;
            break;
    }

    return Ok;

clone_out:
    delete_element(*element2);
    *element2 = NULL;
    return stat;
}
예제 #2
0
파일: region.c 프로젝트: AndreRH/wine
/*****************************************************************************
 * GdipCloneRegion [GDIPLUS.@]
 *
 * Creates a deep copy of the region
 *
 * PARAMS
 *  region  [I] source region
 *  clone   [O] resulting clone
 *
 * RETURNS
 *  SUCCESS: Ok
 *  FAILURE: InvalidParameter or OutOfMemory
 */
GpStatus WINGDIPAPI GdipCloneRegion(GpRegion *region, GpRegion **clone)
{
    region_element *element;

    TRACE("%p %p\n", region, clone);

    if (!(region && clone))
        return InvalidParameter;

    *clone = heap_alloc_zero(sizeof(GpRegion));
    if (!*clone)
        return OutOfMemory;
    element = &(*clone)->node;

    (*clone)->num_children = region->num_children;
    return clone_element(&region->node, &element);
}
예제 #3
0
파일: region.c 프로젝트: AndreRH/wine
/*****************************************************************************
 * GdipCombineRegionRect [GDIPLUS.@]
 */
GpStatus WINGDIPAPI GdipCombineRegionRect(GpRegion *region,
        GDIPCONST GpRectF *rect, CombineMode mode)
{
    GpRegion *rect_region;
    region_element *left, *right = NULL;
    GpStatus stat;

    TRACE("%p %s %d\n", region, debugstr_rectf(rect), mode);

    if (!(region && rect))
        return InvalidParameter;

    stat = GdipCreateRegionRect(rect, &rect_region);
    if (stat != Ok)
        return stat;

    /* simply replace region data */
    if(mode == CombineModeReplace){
        delete_element(&region->node);
        memcpy(region, rect_region, sizeof(GpRegion));
        heap_free(rect_region);
        return Ok;
    }

    left = heap_alloc_zero(sizeof(region_element));
    if (left)
    {
        memcpy(left, &region->node, sizeof(region_element));
        stat = clone_element(&rect_region->node, &right);
        if (stat == Ok)
        {
            fuse_region(region, left, right, mode);
            GdipDeleteRegion(rect_region);
            return Ok;
        }
    }
    else
        stat = OutOfMemory;

    heap_free(left);
    GdipDeleteRegion(rect_region);
    return stat;
}
예제 #4
0
파일: region.c 프로젝트: AmesianX/RosWine
/*****************************************************************************
 * GdipCombineRegionRect [GDIPLUS.@]
 */
GpStatus WINGDIPAPI GdipCombineRegionRect(GpRegion *region,
        GDIPCONST GpRectF *rect, CombineMode mode)
{
    GpRegion *rect_region;
    region_element *left, *right = NULL;
    GpStatus stat;

    TRACE("%p %p %d\n", region, rect, mode);

    if (!(region && rect))
        return InvalidParameter;

    stat = GdipCreateRegionRect(rect, &rect_region);
    if (stat != Ok)
        return stat;

    /* simply replace region data */
    if(mode == CombineModeReplace){
        delete_element(&region->node);
        memcpy(region, rect_region, sizeof(GpRegion));
        GdipFree(rect_region);
        return Ok;
    }

    left = GdipAlloc(sizeof(region_element));
    if (!left)
        goto out;
    memcpy(left, &region->node, sizeof(region_element));

    stat = clone_element(&rect_region->node, &right);
    if (stat != Ok)
        goto out;

    fuse_region(region, left, right, mode);

    GdipDeleteRegion(rect_region);
    return Ok;

out:
    GdipFree(left);
    GdipDeleteRegion(rect_region);
    return stat;
}
예제 #5
0
파일: region.c 프로젝트: AndreRH/wine
/*****************************************************************************
 * GdipCombineRegionPath [GDIPLUS.@]
 */
GpStatus WINGDIPAPI GdipCombineRegionPath(GpRegion *region, GpPath *path, CombineMode mode)
{
    GpRegion *path_region;
    region_element *left, *right = NULL;
    GpStatus stat;

    TRACE("%p %p %d\n", region, path, mode);

    if (!(region && path))
        return InvalidParameter;

    stat = GdipCreateRegionPath(path, &path_region);
    if (stat != Ok)
        return stat;

    /* simply replace region data */
    if(mode == CombineModeReplace){
        delete_element(&region->node);
        memcpy(region, path_region, sizeof(GpRegion));
        heap_free(path_region);
        return Ok;
    }

    left = heap_alloc_zero(sizeof(region_element));
    if (left)
    {
        *left = region->node;
        stat = clone_element(&path_region->node, &right);
        if (stat == Ok)
        {
            fuse_region(region, left, right, mode);
            GdipDeleteRegion(path_region);
            return Ok;
        }
    }
    else
        stat = OutOfMemory;

    heap_free(left);
    GdipDeleteRegion(path_region);
    return stat;
}
예제 #6
0
파일: region.c 프로젝트: AndreRH/wine
/*****************************************************************************
 * GdipCombineRegionRegion [GDIPLUS.@]
 */
GpStatus WINGDIPAPI GdipCombineRegionRegion(GpRegion *region1,
        GpRegion *region2, CombineMode mode)
{
    region_element *left, *right = NULL;
    GpStatus stat;
    GpRegion *reg2copy;

    TRACE("%p %p %d\n", region1, region2, mode);

    if(!(region1 && region2))
        return InvalidParameter;

    /* simply replace region data */
    if(mode == CombineModeReplace){
        stat = GdipCloneRegion(region2, &reg2copy);
        if(stat != Ok)  return stat;

        delete_element(&region1->node);
        memcpy(region1, reg2copy, sizeof(GpRegion));
        heap_free(reg2copy);
        return Ok;
    }

    left  = heap_alloc_zero(sizeof(region_element));
    if (!left)
        return OutOfMemory;

    *left = region1->node;
    stat = clone_element(&region2->node, &right);
    if (stat != Ok)
    {
        heap_free(left);
        return OutOfMemory;
    }

    fuse_region(region1, left, right, mode);
    region1->num_children += region2->num_children;

    return Ok;
}