Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Start parsing EmfPlusPen, EmfPlusBrush, and EmfPlusDrawlines #4

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

willibrandon
Copy link

@willibrandon willibrandon commented Jan 7, 2021

This is in regards to dotnet/winforms#4341

I've started enumerating and parsing the GDI+ records using the EMF+ specification and would greatly appreciate your feedback when you have a moment. Specifically I'm looking for some feedback on how I'm walking the byte pointer and casting to the structures, and whether or not there is a better way to do this. I haven't used pointers in this fashion before and feel like there is room for improvement here.

In the meantime, I'll start looking at enumerating and parsing the same data via the equivalent callback.

@RussKie
Copy link
Contributor

RussKie commented Feb 15, 2021

Hey @willibrandon hope you've been well. Checking if you had any more progress with this.

@JeremyKuhne
Copy link
Owner

@willibrandon So sorry I missed this. I was on an extended vacation. 🙏

Copy link
Owner

@JeremyKuhne JeremyKuhne left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added some initial feedback, many apologies for not seeing the change sooner.


if((_penDataFlags & flag) != 0)
{
if ((_penDataFlags & PenDataFlags.PenDataTransform) != 0)
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor nit- .HasFlag() is easier to read and is fully optimized by the JIT now.

// TODO: Refactor this.
private unsafe int GetOptionalDataOffset(PenDataFlags flag)
{
int offset = 8;
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where does the 8 come from?

private readonly byte _data;

// TODO: Refactor this.
private unsafe int GetOptionalDataOffset(PenDataFlags flag)
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would probably be clearer if you have this method return the pointer to the data or null if the given option doesn't exist. private unsafe byte* GetOptionalData(PenDataFlags flag).

return offset;

if ((_penDataFlags & PenDataFlags.PenDataStartCap) != 0)
offset += sizeof(uint);
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use sizeof(LineCap) to be clearer (presuming the enum type is the right size).

[StructLayout(LayoutKind.Sequential)]
public readonly ref struct MetafilePlusPenData
{
private readonly byte _data;
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Better here to define the fixed data as a normal struct.

    public readonly ref struct MetafilePlusPenData
    {
        public PenDataFlags PenDataFlags;
        public UnitType PenUnit;
        public float PenWidth;
        public MetafilePlusPenOptionalData* OptionalData
        {
             // This needs to be fixed- omitting for clarity
             get => (MetafilePlusPenOptionalData*)((byte*)&PenDataFlags + sizeof(MetafilePlusPenData));

             // If this struct was _not_ a ref struct you can avoid the fixed statements using Unsafe.AsPointer
             get => (MetafilePlusPenOptionalData*)((byte*)Unsafe.AsPointer(ref this) + sizeof(MetafilePlusPenData));
        }
    }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants