""" Enhanced Meta File """ from construct import * record_type = Enum(ULInt32("record_type"), ABORTPATH = 68, ANGLEARC = 41, ARC = 45, ARCTO = 55, BEGINPATH = 59, BITBLT = 76, CHORD = 46, CLOSEFIGURE = 61, CREATEBRUSHINDIRECT = 39, CREATEDIBPATTERNBRUSHPT = 94, CREATEMONOBRUSH = 93, CREATEPALETTE = 49, CREATEPEN = 38, DELETEOBJECT = 40, ELLIPSE = 42, ENDPATH = 60, EOF = 14, EXCLUDECLIPRECT = 29, EXTCREATEFONTINDIRECTW = 82, EXTCREATEPEN = 95, EXTFLOODFILL = 53, EXTSELECTCLIPRGN = 75, EXTTEXTOUTA = 83, EXTTEXTOUTW = 84, FILLPATH = 62, FILLRGN = 71, FLATTENPATH = 65, FRAMERGN = 72, GDICOMMENT = 70, HEADER = 1, INTERSECTCLIPRECT = 30, INVERTRGN = 73, LINETO = 54, MASKBLT = 78, MODIFYWORLDTRANSFORM = 36, MOVETOEX = 27, OFFSETCLIPRGN = 26, PAINTRGN = 74, PIE = 47, PLGBLT = 79, POLYBEZIER = 2, POLYBEZIER16 = 85, POLYBEZIERTO = 5, POLYBEZIERTO16 = 88, POLYDRAW = 56, POLYDRAW16 = 92, POLYGON = 3, POLYGON16 = 86, POLYLINE = 4, POLYLINE16 = 87, POLYLINETO = 6, POLYLINETO16 = 89, POLYPOLYGON = 8, POLYPOLYGON16 = 91, POLYPOLYLINE = 7, POLYPOLYLINE16 = 90, POLYTEXTOUTA = 96, POLYTEXTOUTW = 97, REALIZEPALETTE = 52, RECTANGLE = 43, RESIZEPALETTE = 51, RESTOREDC = 34, ROUNDRECT = 44, SAVEDC = 33, SCALEVIEWPORTEXTEX = 31, SCALEWINDOWEXTEX = 32, SELECTCLIPPATH = 67, SELECTOBJECT = 37, SELECTPALETTE = 48, SETARCDIRECTION = 57, SETBKCOLOR = 25, SETBKMODE = 18, SETBRUSHORGEX = 13, SETCOLORADJUSTMENT = 23, SETDIBITSTODEVICE = 80, SETMAPMODE = 17, SETMAPPERFLAGS = 16, SETMETARGN = 28, SETMITERLIMIT = 58, SETPALETTEENTRIES = 50, SETPIXELV = 15, SETPOLYFILLMODE = 19, SETROP2 = 20, SETSTRETCHBLTMODE = 21, SETTEXTALIGN = 22, SETTEXTCOLOR = 24, SETVIEWPORTEXTEX = 11, SETVIEWPORTORGEX = 12, SETWINDOWEXTEX = 9, SETWINDOWORGEX = 10, SETWORLDTRANSFORM = 35, STRETCHBLT = 77, STRETCHDIBITS = 81, STROKEANDFILLPATH = 63, STROKEPATH = 64, WIDENPATH = 66, _default_ = Pass, ) generic_record = Struct("records", record_type, ULInt32("record_size"), # Size of the record in bytes Union("params", # Parameters Field("raw", lambda ctx: ctx._.record_size - 8), Array(lambda ctx: (ctx._.record_size - 8) // 4, ULInt32("params")) ), ) header_record = Struct("header_record", Const(record_type, "HEADER"), ULInt32("record_size"), # Size of the record in bytes SLInt32("bounds_left"), # Left inclusive bounds SLInt32("bounds_right"), # Right inclusive bounds SLInt32("bounds_top"), # Top inclusive bounds SLInt32("bounds_bottom"), # Bottom inclusive bounds SLInt32("frame_left"), # Left side of inclusive picture frame SLInt32("frame_right"), # Right side of inclusive picture frame SLInt32("frame_top"), # Top side of inclusive picture frame SLInt32("frame_bottom"), # Bottom side of inclusive picture frame Const(ULInt32("signature"), 0x464D4520), ULInt32("version"), # Version of the metafile ULInt32("size"), # Size of the metafile in bytes ULInt32("num_of_records"), # Number of records in the metafile ULInt16("num_of_handles"), # Number of handles in the handle table Padding(2), ULInt32("description_size"), # Size of description string in WORDs ULInt32("description_offset"), # Offset of description string in metafile ULInt32("num_of_palette_entries"), # Number of color palette entries SLInt32("device_width_pixels"), # Width of reference device in pixels SLInt32("device_height_pixels"), # Height of reference device in pixels SLInt32("device_width_mm"), # Width of reference device in millimeters SLInt32("device_height_mm"), # Height of reference device in millimeters # description string Pointer(lambda ctx: ctx.description_offset, StringAdapter( Array(lambda ctx: ctx.description_size, Field("description", 2) ) ) ), # padding up to end of record Padding(lambda ctx: ctx.record_size - 88), ) emf_file = Struct("emf_file", header_record, Array(lambda ctx: ctx.header_record.num_of_records - 1, generic_record ), ) if __name__ == "__main__": obj = emf_file.parse_stream(open("../../../tests/emf1.emf", "rb")) print (obj)