mono / libgdiplus

C-based implementation of the GDI+ API
http://www.mono-project.com/
MIT License
329 stars 171 forks source link

[Region Refactoring] Move region data into its own struct #675

Closed hughbe closed 10 months ago

hughbe commented 3 years ago

GDI+ internally actually stores regions as the following:

typedef enum {
    NodeTypeAnd = CombineModeIntersect,
    NodeTypeOr = CombineModeUnion,
    NodeTypeXor = CombineModeXor,
    NodeTypeExclude = CombineModeExclude,
    NodeTypeComplement = CombineModeComplement,
    NodeTypeRect = 0x10000000,
    NodeTypePath = 0x10000001,
    NodeTypeEmpty = 0x10000002,
    NodeTypeInfinite = 0x10000003,
    NodeTypeNotValid = 0xFFFFFFFF,
} RegionDataNodeType;

typedef struct {
    RegionDataNodeType type;

    union {
        GpRectF rect;
        struct {
            GpPath *path;
            BOOL lazy;
        };
        struct {
            int leftIndex;
            int rightIndex;
        };
    };
} RegionData;

struct GpRegion
{
    RegionData mainNode;
    RegionData *combineNodes;
    void *regionDataLazilyCreated;
}

Essentially, as a performance optimisation and for ease of implementation GDI+ actually doesn't perform any CombineMode operations when calling things like GdipCombineRegionRect/Path/Region. It just modifies the current mainNode to be a combine operation between two functions.

We need/should to copy GDI+ for several reasons

This PR does not actually make any headway towards these aims but is a necessary step along the way, because I will be refactoring the code to lazily create rects or tree/path. Therefore, storing all of the data in a structure called a RegionCachedData is a good thing for now. The PR just avoids horrible diffs in the future

This will not only align us more with GDI+, but it will improve our performance AND actually improve the accuracy of our functions as we will hopefully be getting rid of the horrible bitmap stuff.

Let me know if I'm not making sense!

hughbe commented 10 months ago

Closing, as libgdiplus is deprecated