Exemple #1
0
/*****************************************************************************
 * 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;
}
Exemple #2
0
/*****************************************************************************
 * GdipGetRegionBounds [GDIPLUS.@]
 */
GpStatus WINGDIPAPI GdipGetRegionBounds(GpRegion *region, GpGraphics *graphics, GpRectF *rect)
{
    HRGN hrgn;
    RECT r;
    GpStatus status;

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

    if(!region || !graphics || !rect)
        return InvalidParameter;

    /* Contrary to MSDN, native ignores the graphics transform. */
    status = GdipGetRegionHRgn(region, NULL, &hrgn);
    if(status != Ok)
        return status;

    /* infinite */
    if(!hrgn){
        rect->X = rect->Y = -(REAL)(1 << 22);
        rect->Width = rect->Height = (REAL)(1 << 23);
        TRACE("%p => infinite\n", region);
        return Ok;
    }

    if(GetRgnBox(hrgn, &r)){
        rect->X = r.left;
        rect->Y = r.top;
        rect->Width  = r.right  - r.left;
        rect->Height = r.bottom - r.top;
        TRACE("%p => %s\n", region, debugstr_rectf(rect));
    }
    else
        status = GenericError;

    DeleteObject(hrgn);

    return status;
}
GpStatus WINGDIPAPI GdipEnumerateMetafileSrcRectDestPoints(GpGraphics *graphics,
    GDIPCONST GpMetafile *metafile, GDIPCONST GpPointF *destPoints, INT count,
    GDIPCONST GpRectF *srcRect, Unit srcUnit, EnumerateMetafileProc callback,
    VOID *callbackData, GDIPCONST GpImageAttributes *imageAttributes)
{
    struct enum_metafile_data data;
    GpStatus stat;
    GpMetafile *real_metafile = (GpMetafile*)metafile; /* whoever made this const was joking */
    GraphicsContainer state;
    GpPath *dst_path;

    TRACE("(%p,%p,%p,%i,%p,%i,%p,%p,%p)\n", graphics, metafile,
        destPoints, count, srcRect, srcUnit, callback, callbackData,
        imageAttributes);

    if (!graphics || !metafile || !destPoints || count != 3 || !srcRect)
        return InvalidParameter;

    if (!metafile->hemf)
        return InvalidParameter;

    if (metafile->playback_graphics)
        return ObjectBusy;

    TRACE("%s %i -> %s %s %s\n", debugstr_rectf(srcRect), srcUnit,
        debugstr_pointf(&destPoints[0]), debugstr_pointf(&destPoints[1]),
        debugstr_pointf(&destPoints[2]));

    data.callback = callback;
    data.callback_data = callbackData;
    data.metafile = real_metafile;

    real_metafile->playback_graphics = graphics;
    real_metafile->playback_dc = NULL;
    real_metafile->src_rect = *srcRect;

    memcpy(real_metafile->playback_points, destPoints, sizeof(PointF) * 3);
    stat = GdipTransformPoints(graphics, CoordinateSpaceDevice, CoordinateSpaceWorld, real_metafile->playback_points, 3);

    if (stat == Ok)
        stat = GdipBeginContainer2(graphics, &state);

    if (stat == Ok)
    {
        stat = GdipSetPageScale(graphics, 1.0);

        if (stat == Ok)
            stat = GdipSetPageUnit(graphics, UnitPixel);

        if (stat == Ok)
            stat = GdipResetWorldTransform(graphics);

        if (stat == Ok)
            stat = GdipCreateRegion(&real_metafile->base_clip);

        if (stat == Ok)
            stat = GdipGetClip(graphics, real_metafile->base_clip);

        if (stat == Ok)
            stat = GdipCreatePath(FillModeAlternate, &dst_path);

        if (stat == Ok)
        {
            GpPointF clip_points[4];

            clip_points[0] = real_metafile->playback_points[0];
            clip_points[1] = real_metafile->playback_points[1];
            clip_points[2].X = real_metafile->playback_points[1].X + real_metafile->playback_points[2].X
                - real_metafile->playback_points[0].X;
            clip_points[2].Y = real_metafile->playback_points[1].Y + real_metafile->playback_points[2].Y
                - real_metafile->playback_points[0].Y;
            clip_points[3] = real_metafile->playback_points[2];

            stat = GdipAddPathPolygon(dst_path, clip_points, 4);

            if (stat == Ok)
                stat = GdipCombineRegionPath(real_metafile->base_clip, dst_path, CombineModeIntersect);

            GdipDeletePath(dst_path);
        }

        if (stat == Ok)
            stat = GdipCreateMatrix(&real_metafile->world_transform);

        if (stat == Ok)
        {
            real_metafile->page_unit = UnitDisplay;
            real_metafile->page_scale = 1.0;
            stat = METAFILE_PlaybackUpdateWorldTransform(real_metafile);
        }

        if (stat == Ok)
        {
            stat = METAFILE_PlaybackUpdateClip(real_metafile);
        }

        if (stat == Ok && (metafile->metafile_type == MetafileTypeEmf ||
            metafile->metafile_type == MetafileTypeWmfPlaceable ||
            metafile->metafile_type == MetafileTypeWmf))
            stat = METAFILE_PlaybackGetDC(real_metafile);

        if (stat == Ok)
            EnumEnhMetaFile(0, metafile->hemf, enum_metafile_proc, &data, NULL);

        METAFILE_PlaybackReleaseDC(real_metafile);

        GdipDeleteMatrix(real_metafile->world_transform);
        real_metafile->world_transform = NULL;

        GdipDeleteRegion(real_metafile->base_clip);
        real_metafile->base_clip = NULL;

        GdipEndContainer(graphics, state);
    }

    real_metafile->playback_graphics = NULL;

    return stat;
}