diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 18:24:48 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 18:24:48 +0000 |
commit | cca66b9ec4e494c1d919bff0f71a820d8afab1fa (patch) | |
tree | 146f39ded1c938019e1ed42d30923c2ac9e86789 /src/3rdparty/libuemf/upmf_print.c | |
parent | Initial commit. (diff) | |
download | inkscape-upstream.tar.xz inkscape-upstream.zip |
Adding upstream version 1.2.2.upstream/1.2.2upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/3rdparty/libuemf/upmf_print.c')
-rw-r--r-- | src/3rdparty/libuemf/upmf_print.c | 3400 |
1 files changed, 3400 insertions, 0 deletions
diff --git a/src/3rdparty/libuemf/upmf_print.c b/src/3rdparty/libuemf/upmf_print.c new file mode 100644 index 0000000..69fad36 --- /dev/null +++ b/src/3rdparty/libuemf/upmf_print.c @@ -0,0 +1,3400 @@ +/** + @file upmf_print.c + + @brief Functions for printing EMF records +*/ + +/* +File: upmf_print.c +Version: 0.0.8 +Date: 26-JAN-2016 +Author: David Mathog, Biology Division, Caltech +email: mathog@caltech.edu +Copyright: 2016 David Mathog and California Institute of Technology (Caltech) +*/ + +/* compiler options: + +-DNOBRUSH causes brush objects to be treated as pen objects. PowerPoint 2003 and 2010 define pen objects +as brush objects, and this is one way to see their structure even though they are misidentified. +This option should only be used for tiny test files, consisting of just line objects. +*/ + +#ifdef __cplusplus +extern "C" { +#endif + +#include <stdlib.h> +#include <stdio.h> +#include <stddef.h> /* for offsetof() macro */ +#include <string.h> +#include "upmf_print.h" +#include "uemf_print.h" +#include "uemf_safe.h" + + +//! \cond + +#define UNUSED(x) (void)(x) //! Please ignore - Doxygen simply insisted on including this + +/* + this function is not visible in the API. Print "data" for one of the many records that has none. +*/ +int U_PMR_NODATAREC_print(const char *contents){ + U_PMF_CMN_HDR Header; + int status = U_PMR_RESETCLIP_get(contents,&Header); /* One of many possibilities */ + if(status)status = Header.Size; + return(status); +} + +/* + this function is not visible in the API. Common routine used by many functions that draw points. +*/ +void U_PMF_VARPOINTS_print(const char **contents, int Flags, uint32_t Elements, const char *blimit){ + unsigned int i; + U_FLOAT Xpos, Ypos; + + if( Flags & U_PPF_P){ printf(" + Points(Relative):"); } + else if(Flags & U_PPF_C){ printf(" + Points(Int16):"); } + else { printf(" + Points(Float):"); } + for(Xpos = Ypos = i = 0; i<Elements; i++){ + printf(" %d:",i); + if( Flags & U_PPF_P){ (void) U_PMF_POINTR_print(contents, &Xpos, &Ypos, blimit); } + else if(Flags & U_PPF_C){ (void) U_PMF_POINT_print(contents, blimit); } + else { (void) U_PMF_POINTF_print(contents, blimit); } + } +#if 0 +int residual; +uintptr_t holdptr = (uintptr_t) *contents; + residual = holdptr & 0x3; + if(residual){ *contents += (4-residual); } +printf("DEBUG U_PMF_VARPOINTS_print residual:%d *contents:%p\n",residual,*contents);fflush(stdout); +#endif + printf("\n"); +} + +/* + this function is not visible in the API. Common routine used by many functions that draw points. +*/ +void U_PMF_VARPOINTF_S_print(U_PMF_POINTF *Points, uint32_t Elements){ + unsigned int i; + printf(" + Points:"); + for(i=0; i<Elements; i++, Points++){ + printf(" %d:",i); + (void) U_PMF_POINTF_S_print(Points); + } + printf("\n"); +} + +/* + this function is not visible in the API. Common routine used by many functions that draw rectangles. +*/ +int U_PMF_VARRECTF_S_print(U_PMF_RECTF *Rects, uint32_t Elements){ + if(!Elements)return(0); + if(Elements == 1){ printf(" Rect(Float):"); } + else { printf(" Rects(Float):"); } + while(1){ + U_PMF_RECTF_S_print(Rects++); + Elements--; + if(!Elements)break; + printf(" "); + } + return(1); +} + +/* + this function is not visible in the API. Common routine used by many functions. +*/ +int U_PMF_VARBRUSHID_print(int btype, uint32_t BrushID){ + if(btype){ + printf(" Color:"); + (void) U_PMF_ARGB_print((char *)&(BrushID)); + } + else { + printf(" BrushID:%u",BrushID); + } + return(1); +} +//! \endcond + +/** + \brief Print any EMF+ record + \returns record length for a normal record, 0 for EMREOF or , -1 for a bad record + \param contents pointer to a buffer holding this EMF+ record + \param blimit one byte after this EMF+ record + \param recnum EMF number of this record in contents + \param off Offset from the beginning of the EMF+ file to the start of this record. +*/ +int U_pmf_onerec_print(const char *contents, const char *blimit, int recnum, int off){ + int status; + int rstatus; + static U_OBJ_ACCUM ObjCont={NULL,0,0,0,0}; /* for keeping track of object continuation. These may + be split across multiple EMF Comment records */ + U_PMF_CMN_HDR Header; + const char *contemp = contents; + + /* Check that COMMON header data in record can be touched without an access violation. If it cannot be + this is either a corrupt EMF or one engineered to cause a buffer overflow. Pointer math + could wrap so check both sides of the range. + */ + if(IS_MEM_UNSAFE(contents, sizeof(U_PMF_CMN_HDR), blimit))return(-1); + if(!U_PMF_CMN_HDR_get(&contemp, &Header)){return(-1);} + + int type = Header.Type & U_PMR_TYPE_MASK; /* strip the U_PMR_RECFLAG bit, leaving the indexable part */ + if(type < U_PMR_MIN || type > U_PMR_MAX)return(-1); /* unknown EMF+ record type */ + status = U_PMF_CMN_HDR_print(contents, Header, recnum, off); /* EMF+ part */ + + /* Buggy EMF+ can set the continue bit and then do something else. In that case, force out the pending + Object. Side effect - clears the pending object. */ + if((type != U_PMR_OBJECT) && (ObjCont.used > 0)){ + U_PMR_OBJECT_print(contents, blimit, &ObjCont, 1); + } + + /* Check that the record size is OK, abort if not. */ + if(Header.Size < sizeof(U_PMF_CMN_HDR) || + IS_MEM_UNSAFE(contents, Header.Size, blimit))return(-1); + + switch(type){ + case (U_PMR_HEADER): rstatus = U_PMR_HEADER_print(contents); break; + case (U_PMR_ENDOFFILE): rstatus = U_PMR_ENDOFFILE_print(contents); + U_OA_release(&ObjCont); break; + case (U_PMR_COMMENT): rstatus = U_PMR_COMMENT_print(contents); break; + case (U_PMR_GETDC): rstatus = U_PMR_GETDC_print(contents); break; + case (U_PMR_MULTIFORMATSTART): rstatus = U_PMR_MULTIFORMATSTART_print(contents); break; + case (U_PMR_MULTIFORMATSECTION): rstatus = U_PMR_MULTIFORMATSECTION_print(contents); break; + case (U_PMR_MULTIFORMATEND): rstatus = U_PMR_MULTIFORMATEND_print(contents); break; + case (U_PMR_OBJECT): rstatus = U_PMR_OBJECT_print(contents,blimit,&ObjCont,0); break; + case (U_PMR_CLEAR): rstatus = U_PMR_CLEAR_print(contents); break; + case (U_PMR_FILLRECTS): rstatus = U_PMR_FILLRECTS_print(contents); break; + case (U_PMR_DRAWRECTS): rstatus = U_PMR_DRAWRECTS_print(contents); break; + case (U_PMR_FILLPOLYGON): rstatus = U_PMR_FILLPOLYGON_print(contents); break; + case (U_PMR_DRAWLINES): rstatus = U_PMR_DRAWLINES_print(contents); break; + case (U_PMR_FILLELLIPSE): rstatus = U_PMR_FILLELLIPSE_print(contents); break; + case (U_PMR_DRAWELLIPSE): rstatus = U_PMR_DRAWELLIPSE_print(contents); break; + case (U_PMR_FILLPIE): rstatus = U_PMR_FILLPIE_print(contents); break; + case (U_PMR_DRAWPIE): rstatus = U_PMR_DRAWPIE_print(contents); break; + case (U_PMR_DRAWARC): rstatus = U_PMR_DRAWARC_print(contents); break; + case (U_PMR_FILLREGION): rstatus = U_PMR_FILLREGION_print(contents); break; + case (U_PMR_FILLPATH): rstatus = U_PMR_FILLPATH_print(contents); break; + case (U_PMR_DRAWPATH): rstatus = U_PMR_DRAWPATH_print(contents); break; + case (U_PMR_FILLCLOSEDCURVE): rstatus = U_PMR_FILLCLOSEDCURVE_print(contents); break; + case (U_PMR_DRAWCLOSEDCURVE): rstatus = U_PMR_DRAWCLOSEDCURVE_print(contents); break; + case (U_PMR_DRAWCURVE): rstatus = U_PMR_DRAWCURVE_print(contents); break; + case (U_PMR_DRAWBEZIERS): rstatus = U_PMR_DRAWBEZIERS_print(contents); break; + case (U_PMR_DRAWIMAGE): rstatus = U_PMR_DRAWIMAGE_print(contents); break; + case (U_PMR_DRAWIMAGEPOINTS): rstatus = U_PMR_DRAWIMAGEPOINTS_print(contents); break; + case (U_PMR_DRAWSTRING): rstatus = U_PMR_DRAWSTRING_print(contents); break; + case (U_PMR_SETRENDERINGORIGIN): rstatus = U_PMR_SETRENDERINGORIGIN_print(contents); break; + case (U_PMR_SETANTIALIASMODE): rstatus = U_PMR_SETANTIALIASMODE_print(contents); break; + case (U_PMR_SETTEXTRENDERINGHINT): rstatus = U_PMR_SETTEXTRENDERINGHINT_print(contents); break; + case (U_PMR_SETTEXTCONTRAST): rstatus = U_PMR_SETTEXTCONTRAST_print(contents); break; + case (U_PMR_SETINTERPOLATIONMODE): rstatus = U_PMR_SETINTERPOLATIONMODE_print(contents); break; + case (U_PMR_SETPIXELOFFSETMODE): rstatus = U_PMR_SETPIXELOFFSETMODE_print(contents); break; + case (U_PMR_SETCOMPOSITINGMODE): rstatus = U_PMR_SETCOMPOSITINGMODE_print(contents); break; + case (U_PMR_SETCOMPOSITINGQUALITY): rstatus = U_PMR_SETCOMPOSITINGQUALITY_print(contents); break; + case (U_PMR_SAVE): rstatus = U_PMR_SAVE_print(contents); break; + case (U_PMR_RESTORE): rstatus = U_PMR_RESTORE_print(contents); break; + case (U_PMR_BEGINCONTAINER): rstatus = U_PMR_BEGINCONTAINER_print(contents); break; + case (U_PMR_BEGINCONTAINERNOPARAMS): rstatus = U_PMR_BEGINCONTAINERNOPARAMS_print(contents); break; + case (U_PMR_ENDCONTAINER): rstatus = U_PMR_ENDCONTAINER_print(contents); break; + case (U_PMR_SETWORLDTRANSFORM): rstatus = U_PMR_SETWORLDTRANSFORM_print(contents); break; + case (U_PMR_RESETWORLDTRANSFORM): rstatus = U_PMR_RESETWORLDTRANSFORM_print(contents); break; + case (U_PMR_MULTIPLYWORLDTRANSFORM): rstatus = U_PMR_MULTIPLYWORLDTRANSFORM_print(contents); break; + case (U_PMR_TRANSLATEWORLDTRANSFORM): rstatus = U_PMR_TRANSLATEWORLDTRANSFORM_print(contents); break; + case (U_PMR_SCALEWORLDTRANSFORM): rstatus = U_PMR_SCALEWORLDTRANSFORM_print(contents); break; + case (U_PMR_ROTATEWORLDTRANSFORM): rstatus = U_PMR_ROTATEWORLDTRANSFORM_print(contents); break; + case (U_PMR_SETPAGETRANSFORM): rstatus = U_PMR_SETPAGETRANSFORM_print(contents); break; + case (U_PMR_RESETCLIP): rstatus = U_PMR_RESETCLIP_print(contents); break; + case (U_PMR_SETCLIPRECT): rstatus = U_PMR_SETCLIPRECT_print(contents); break; + case (U_PMR_SETCLIPPATH): rstatus = U_PMR_SETCLIPPATH_print(contents); break; + case (U_PMR_SETCLIPREGION): rstatus = U_PMR_SETCLIPREGION_print(contents); break; + case (U_PMR_OFFSETCLIP): rstatus = U_PMR_OFFSETCLIP_print(contents); break; + case (U_PMR_DRAWDRIVERSTRING): rstatus = U_PMR_DRAWDRIVERSTRING_print(contents); break; + case (U_PMR_STROKEFILLPATH): rstatus = U_PMR_STROKEFILLPATH_print(contents); break; + case (U_PMR_SERIALIZABLEOBJECT): rstatus = U_PMR_SERIALIZABLEOBJECT_print(contents); break; + case (U_PMR_SETTSGRAPHICS): rstatus = U_PMR_SETTSGRAPHICS_print(contents); break; + case (U_PMR_SETTSCLIP): rstatus = U_PMR_SETTSCLIP_print(contents); break; + } + if(!rstatus)status=-1; + return(status); +} + +/** + \brief Print data from a U_PMF_CMN_HDR object + \return number of bytes in record, 0 on error + \param contents pointer to a buffer holding this EMF+ record + \param Header Header of the record + \param precnum EMF+ record number in file. + \param off Offset in file to the start of this EMF+ record. + common structure present at the beginning of all(*) EMF+ records +*/ +int U_PMF_CMN_HDR_print(const char *contents, U_PMF_CMN_HDR Header, int precnum, int off){ + printf(" %-29srec+:%5d type:%X offset:%8d rsize:%8u dsize:%8u flags:%4.4X crc32:%8.8X\n", + U_pmr_names(Header.Type &U_PMR_TYPE_MASK),precnum, Header.Type,off,Header.Size,Header.DataSize,Header.Flags, + lu_crc32(contents,Header.Size)); + return((int) Header.Size); +} + +/** + \brief Print data from a an array of uint8_t values + \return 1 + \param Start Text to lead array data + \param Array uint8_t array of data passed as char * + \param Elements Number of elements in Array + \param End Text to follow array data +*/ +int U_PMF_UINT8_ARRAY_print(const char *Start, const uint8_t *Array, int Elements, char *End){ + if(Start)printf("%s",Start); + for(; Elements--; Array++){ printf(" %u", *Array); } + if(End)printf("%s",End); + return(1); +} + +/** + \brief Print value of an BrushType Enumeration + \returns record 1 on sucess, 0 on error + \param otype Value to print. + EMF+ manual 2.1.1.3, Microsoft name: BrushType Enumeration +*/ +int U_PMF_BRUSHTYPEENUMERATION_print(int otype){ + int status=1; + switch(otype){ + case U_BT_SolidColor: printf("SolidColor"); break; + case U_BT_HatchFill: printf("HatchFill"); break; + case U_BT_TextureFill: printf("TextureFill"); break; + case U_BT_PathGradient: printf("PathGradient"); break; + case U_BT_LinearGradient: printf("LinearGradient"); break; + default: status=0; printf("INVALID(%d)",otype); break; + } + return(status); +} + +/** + \brief Print value of an BrushType Enumeration + \returns record 1 on sucess, 0 on error + \param otype Value to print. + EMF+ manual 2.1.1.4, Microsoft name: BrushType Enumeration +*/ +int U_PMF_COMBINEMODEENUMERATION_print(int otype){ + int status=1; + switch(otype){ + case U_CM_Replace: printf("Replace" ); break; + case U_CM_Intersect: printf("Intersect" ); break; + case U_CM_Union: printf("Union" ); break; + case U_CM_XOR: printf("XOR" ); break; + case U_CM_Exclude: printf("Exclude" ); break; + case U_CM_Complement: printf("Complement"); break; + default: status=0; printf("INVALID(%d)",otype); break; + } + return(status); +} + +/** + \brief Print value of a HatchStyle Enumeration + \returns record 1 on sucess, 0 on error + \param hstype Value to print. + EMF+ manual 2.1.1.13, Microsoft name: HatchStyle Enumeration +*/ +int U_PMF_HATCHSTYLEENUMERATION_print(int hstype){ + int status=1; + switch(hstype){ + case U_HSP_Horizontal: printf("Horizontal"); break; + case U_HSP_Vertical: printf("Vertical"); break; + case U_HSP_ForwardDiagonal: printf("ForwardDiagonal"); break; + case U_HSP_BackwardDiagonal: printf("BackwardDiagonal"); break; + case U_HSP_LargeGrid: printf("LargeGrid"); break; + case U_HSP_DiagonalCross: printf("DiagonalCross"); break; + case U_HSP_05Percent: printf("05Percent"); break; + case U_HSP_10Percent: printf("10Percent"); break; + case U_HSP_20Percent: printf("20Percent"); break; + case U_HSP_25Percent: printf("25Percent"); break; + case U_HSP_30Percent: printf("30Percent"); break; + case U_HSP_40Percent: printf("40Percent"); break; + case U_HSP_50Percent: printf("50Percent"); break; + case U_HSP_60Percent: printf("60Percent"); break; + case U_HSP_70Percent: printf("70Percent"); break; + case U_HSP_75Percent: printf("75Percent"); break; + case U_HSP_80Percent: printf("80Percent"); break; + case U_HSP_90Percent: printf("90Percent"); break; + case U_HSP_LightDownwardDiagonal: printf("LightDownwardDiagonal"); break; + case U_HSP_LightUpwardDiagonal: printf("LightUpwardDiagonal"); break; + case U_HSP_DarkDownwardDiagonal: printf("DarkDownwardDiagonal"); break; + case U_HSP_DarkUpwardDiagonal: printf("DarkUpwardDiagonal"); break; + case U_HSP_WideDownwardDiagonal: printf("WideDownwardDiagonal"); break; + case U_HSP_WideUpwardDiagonal: printf("WideUpwardDiagonal"); break; + case U_HSP_LightVertical: printf("LightVertical"); break; + case U_HSP_LightHorizontal: printf("LightHorizontal"); break; + case U_HSP_NarrowVertical: printf("NarrowVertical"); break; + case U_HSP_NarrowHorizontal: printf("NarrowHorizontal"); break; + case U_HSP_DarkVertical: printf("DarkVertical"); break; + case U_HSP_DarkHorizontal: printf("DarkHorizontal"); break; + case U_HSP_DashedDownwardDiagonal: printf("DashedDownwardDiagonal"); break; + case U_HSP_DashedUpwardDiagonal: printf("DashedUpwardDiagonal"); break; + case U_HSP_DashedHorizontal: printf("DashedHorizontal"); break; + case U_HSP_DashedVertical: printf("DashedVertical"); break; + case U_HSP_SmallConfetti: printf("SmallConfetti"); break; + case U_HSP_LargeConfetti: printf("LargeConfetti"); break; + case U_HSP_ZigZag: printf("ZigZag"); break; + case U_HSP_Wave: printf("Wave"); break; + case U_HSP_DiagonalBrick: printf("DiagonalBrick"); break; + case U_HSP_HorizontalBrick: printf("HorizontalBrick"); break; + case U_HSP_Weave: printf("Weave"); break; + case U_HSP_Plaid: printf("Plaid"); break; + case U_HSP_Divot: printf("Divot"); break; + case U_HSP_DottedGrid: printf("DottedGrid"); break; + case U_HSP_DottedDiamond: printf("DottedDiamond"); break; + case U_HSP_Shingle: printf("Shingle"); break; + case U_HSP_Trellis: printf("Trellis"); break; + case U_HSP_Sphere: printf("Sphere"); break; + case U_HSP_SmallGrid: printf("SmallGrid"); break; + case U_HSP_SmallCheckerBoard: printf("SmallCheckerBoard"); break; + case U_HSP_LargeCheckerBoard: printf("LargeCheckerBoard"); break; + case U_HSP_OutlinedDiamond: printf("OutlinedDiamond"); break; + case U_HSP_SolidDiamond: printf("SolidDiamond"); break; + default: status=0; printf("INVALID(%d)",hstype); break; + } + return(status); +} + +/** + \brief Print value of an ObjectType Enumeration + \returns record 1 on sucess, 0 on error + \param otype Value to print. + EMF+ manual 2.1.1.22, Microsoft name: ObjectType Enumeration +*/ +int U_PMF_OBJECTTYPEENUMERATION_print(int otype){ + int status=1; + switch(otype){ + case U_OT_Invalid: printf("Invalid"); break; + case U_OT_Brush: printf("Brush"); break; + case U_OT_Pen: printf("Pen"); break; + case U_OT_Path: printf("Path"); break; + case U_OT_Region: printf("Region"); break; + case U_OT_Image: printf("Image"); break; + case U_OT_Font: printf("Font"); break; + case U_OT_StringFormat: printf("StringFormat"); break; + case U_OT_ImageAttributes: printf("ImageAttributes"); break; + case U_OT_CustomLineCap: printf("CustomLineCap"); break; + default: + status=0; printf("INVALID(%d)",otype); break; + } + return(status); +} + +/** + \brief Print value of a U_PMF_PATHPOINTTYPE_ENUM object + \return 1 + \param Type Value to print + EMF+ manual 2.1.1.23, Microsoft name: PathPointType Enumeration +*/ +int U_PMF_PATHPOINTTYPE_ENUM_print(int Type){ + switch(Type & U_PPT_MASK){ + case U_PPT_Start : printf("Start"); break; + case U_PPT_Line : printf("Line"); break; + case U_PPT_Bezier: printf("Bezier"); break; + default: printf("INVALID(%d)",Type); break; + } + return(1); +} + +/** + \brief Print data from a PixelFormat Enumeration value + \return 1 always + \param pfe A PixelFormat Enumeration value + EMF+ manual 2.1.1.25, Microsoft name: PixelFormat Enumeration (U_PF_*) +*/ +int U_PMF_PX_FMT_ENUM_print(int pfe){ + uint8_t idx; + printf(" + PxFmtEnum: "); + printf(" 32Bit:%c", (pfe & 1<< 9 ? 'Y' : 'N')); + printf(" 16Bit:%c", (pfe & 1<<10 ? 'Y' : 'N')); + printf(" PreAlpha:%c", (pfe & 1<<11 ? 'Y' : 'N')); + printf(" Alpha:%c", (pfe & 1<<12 ? 'Y' : 'N')); + printf(" GDI:%c", (pfe & 1<<13 ? 'Y' : 'N')); + printf(" LUT:%c", (pfe & 1<<14 ? 'Y' : 'N')); + printf(" BitsPerPx:%u", (pfe >> 16) & 0xFF); + idx = pfe >> 24; + printf(" Type:%u(",idx); + switch(idx){ + case 0: printf("undefined"); break; + case 1: printf("monochrome with LUT"); break; + case 2: printf("4 bit with LUT"); break; + case 3: printf("8 bit with LUT"); break; + case 4: printf("16 bits grey values"); break; + case 5: printf("16 bit RGB values (5,5,5,(1 ignored))"); break; + case 6: printf("16 bit RGB values (5,6,5)"); break; + case 7: printf("16 bit ARGB values (1 alpha, 5,5,5 colors)"); break; + case 8: printf("24 bit RGB values (8,8.8)"); break; + case 9: printf("32 bit RGB value (8,8,8,(8 ignored))"); break; + case 10: printf("32 bit ARGB values (8 alpha,8,8,8)"); break; + case 11: printf("32 bit PARGB values (8,8,8,8, but RGB already multiplied by A)"); break; + case 12: printf("48 bit RGB (16,16,16)"); break; + case 13: printf("64 bit ARGB (16 alpha, 16,16,16)"); break; + case 14: printf("64 bit PARGB (16,16,16,16, but RGB already multiplied by A)"); break; + default: printf("INVALID(%d)",idx); break; + } + printf(")"); + return(1); +} + +/** + \brief Print as text a RegionNodeDataType Enumeration + \return 1 + \param Type RegionNodeDataType Enumeration + EMF+ manual 2.1.1.27, Microsoft name: RegionNodeDataType Enumeration (U_RNDT_*) +*/ +int U_PMF_NODETYPE_print(int Type){ + if( Type == U_RNDT_And ){ printf("And" ); } + else if(Type == U_RNDT_Or ){ printf("Or" ); } + else if(Type == U_RNDT_Xor ){ printf("Xor" ); } + else if(Type == U_RNDT_Exclude ){ printf("Exclude" ); } + else if(Type == U_RNDT_Complement){ printf("Complement"); } + else if(Type == U_RNDT_Rect ){ printf("Rect" ); } + else if(Type == U_RNDT_Path ){ printf("Path" ); } + else if(Type == U_RNDT_Empty ){ printf("Empty" ); } + else if(Type == U_RNDT_Infinite ){ printf("Infinite" ); } + else { printf("Undefined" ); return(0); } + return(1); +} + +/** + \brief Print data from a U_PMF_BRUSH object + \return 1 on success, 0 on error + \param contents Record from which to print data + \param blimit one byte past the end of data + EMF+ manual 2.2.1.1, Microsoft name: EmfPlusBrush Object +*/ +int U_PMF_BRUSH_print(const char *contents, const char *blimit){ + uint32_t Version, Type; + const char *Data; + int status = U_PMF_BRUSH_get(contents, &Version, &Type, &Data, blimit); + if(status){ + printf(" + Brush:"); + (void) U_PMF_GRAPHICSVERSION_memsafe_print((char *)&Version);; + printf(" Type:%X(",Type); + (void) U_PMF_BRUSHTYPEENUMERATION_print(Type); + printf(")"); + switch(Type){ + case U_BT_SolidColor: + status = U_PMF_ARGB_print(Data); + break; + case U_BT_HatchFill: + printf("\n"); + status = U_PMF_HATCHBRUSHDATA_print(Data, blimit); + break; + case U_BT_TextureFill: + printf("\n"); + status = U_PMF_TEXTUREBRUSHDATA_print(Data, blimit); + break; + case U_BT_PathGradient: + printf("\n"); + status = U_PMF_PATHGRADIENTBRUSHDATA_print(Data, blimit); + break; + case U_BT_LinearGradient: + printf("\n"); + status = U_PMF_LINEARGRADIENTBRUSHDATA_print(Data, blimit); + break; + default: + status = 0; + } + printf("\n"); + } + return(status); +} + +/** + \brief Print data from a U_PMF_CUSTOMLINECAP object + \return 1 on success, 0 on error + \param contents Record from which to print data + \param Which A string which is either "Start" or "End". + \param blimit one byte past the end of data + EMF+ manual 2.2.1.2, Microsoft name: EmfPlusCustomLineCap Object +*/ +int U_PMF_CUSTOMLINECAP_print(const char *contents, const char *Which, const char *blimit){ + uint32_t Version, Type; + const char *Data; + int status = U_PMF_CUSTOMLINECAP_get(contents, &Version, &Type, &Data, blimit); + + if(status){ + printf(" + %sLineCap:",Which); + (void) U_PMF_GRAPHICSVERSION_memsafe_print((char *)&Version);; + printf(", Type %X\n",Type); + switch(Type){ + case U_CLCDT_Default: + status = U_PMF_CUSTOMLINECAPDATA_print(Data, blimit); + break; + case U_CLCDT_AdjustableArrow: + status = U_PMF_CUSTOMLINECAPARROWDATA_print(Data, blimit); + break; + default: + status = 0; + } + } + return(status); +} + +/** + \brief Print data from a U_PMF_FONT object + \return 1 on success, 0 on error + \param contents Record from which to print data + \param blimit one byte past the end of data + EMF+ manual 2.2.1.3, Microsoft name: EmfPlusFont Object +*/ +int U_PMF_FONT_print(const char *contents, const char *blimit){ + uint32_t Version, SizeUnit, Length; + U_FLOAT EmSize; + int32_t FSFlags; + const char *Data; + char *string; + int status = U_PMF_FONT_get(contents, &Version, &EmSize, &SizeUnit, &FSFlags, &Length, &Data, blimit); + if(status){ + printf(" + Font:"); + (void) U_PMF_GRAPHICSVERSION_memsafe_print((char *)&Version);; + printf(" EmSize:%f ", EmSize ); + printf(" SizeUnit:%d ",SizeUnit); + printf(" FSFlags:%d ", FSFlags ); + printf(" Length:%d", Length ); + string = U_Utf16leToUtf8((uint16_t *)Data, Length, NULL); + if(string){ + printf(" Family:<%s>\n",string); + free(string); + } + else { + printf(" Family:<>\n"); + } + } + return(status); +} + + +/** + \brief Print data from a U_PMF_IMAGE object + \return 1 on success, 0 on error + \param contents Record from which to print data + \param blimit one byte past the end of data + + EMF+ manual 2.2.1.4, Microsoft name: EmfPlusImage Object +*/ +int U_PMF_IMAGE_print(const char *contents, const char *blimit){ + uint32_t Version, Type; + const char *Data; + int status = U_PMF_IMAGE_get(contents, &Version, &Type, &Data, blimit); + if(status){ + printf(" + Image:"); + (void) U_PMF_GRAPHICSVERSION_memsafe_print((char *)&Version);; + printf(" Type:%X\n",Type); + switch(Type){ + case U_IDT_Unknown: + printf(" + Unknown Image Type\n"); + break; + case U_IDT_Bitmap: + status = U_PMF_BITMAP_print(Data, blimit); + break; + case U_IDT_Metafile: + status = U_PMF_METAFILE_print(Data, blimit); + break; + default: + status = 0; + } + } + return(status); +} + + +/** + \brief Print data from a U_PMF_IMAGEATTRIBUTES object + \return 1 on success, 0 on error + \param contents Record from which to print data + \param blimit one byte past the end of data + EMF+ manual 2.2.1.5, Microsoft name: EmfPlusImageAttributes Object +*/ +int U_PMF_IMAGEATTRIBUTES_print(const char *contents, const char *blimit){ + uint32_t Version, WrapMode, ClampColor, ObjectClamp; + int status = U_PMF_IMAGEATTRIBUTES_get(contents, &Version, &WrapMode, &ClampColor, &ObjectClamp, blimit); + + if(status){ + printf(" + Image Attributes: "); + (void) U_PMF_GRAPHICSVERSION_memsafe_print((char *)&Version);; + printf(" WrapMode:%X", WrapMode); + printf(" ClampColor:%X", ClampColor); + printf(" ObjectClamp:%X\n", ObjectClamp); + } + return(status); +} + + + +/** + \brief Print data from a U_PMF_PATH object + \return 1 on success, 0 on error + \param contents Record from which to print data + \param blimit one byte past the end of data + EMF+ manual 2.2.1.6, Microsoft name: EmfPlusPath Object +*/ +int U_PMF_PATH_print(const char *contents, const char *blimit){ + unsigned int i, pos; + uint32_t Version, Count; + uint16_t Flags; + const char *Points; + const char *Types; + int status = U_PMF_PATH_get(contents, &Version, &Count, &Flags, &Points, &Types, blimit); + if(status){ + printf(" + Path: Version:%X Count:%d Flags:%X\n",Version, Count, Flags); + + /* Points part */ + U_PMF_VARPOINTS_print(&Points, Flags, Count, blimit); + + /* Types part */ + printf(" + Types:"); + pos = 0; + for(i=0; i<Count; i++){ + /* EMF+ manual says that the first of these two cases can actually contain either type + of PATHPOINT, but it does not say how the program is supposed to figure out which record + is which type. */ + if(Flags & U_PPF_R){ + printf(" %u:",pos); + pos += U_PMF_PATHPOINTTYPERLE_print(Types, blimit); + Types+=2; + } + else { + printf(" %d:",i); + (void) U_PMF_PATHPOINTTYPE_print(Types, blimit); + Types++; + } + } + printf("\n"); + } + return(status); +} + +/** + \brief Print data from a U_PMF_PEN object + \return 1 on success, 0 on error + \param contents Record from which to print data + EMF+ manual 2.2.1.7, Microsoft name: EmfPlusPen Object +*/ +int U_PMF_PEN_print(const char *contents, const char *blimit){ + uint32_t Version, Type; + const char *PenData; + const char *Brush; + int status = U_PMF_PEN_get(contents, &Version, &Type, &PenData, &Brush, blimit); + if(status){ + printf(" + Pen: Version:%X Type:%d\n",Version,Type); + (void) U_PMF_PENDATA_print(PenData, blimit); + (void) U_PMF_BRUSH_print(Brush, blimit); + } + return(status); +} + +/** + \brief Print data from a U_PMF_REGION object + \return 1 on success, 0 on error + \param contents Record from which to print data + \param blimit one byte past the end of data + + EMF+ manual 2.2.1.8, Microsoft name: EmfPlusRegion Object +*/ +int U_PMF_REGION_print(const char *contents, const char *blimit){ + uint32_t Version, Count; + const char *Nodes; + int status = U_PMF_REGION_get(contents, &Version, &Count, &Nodes, blimit); + if(status){ + printf(" + "); + (void) U_PMF_GRAPHICSVERSION_memsafe_print((char *)&Version);; + printf(" ChildNodes:%d",Count); + (void) U_PMF_REGIONNODE_print(Nodes, 1, blimit); /* 1 == top level*/ + } + return(status); +} + +/** + \brief Print data from a U_PMF_STRINGFORMAT object + \return 1 on success, 0 on error + \param contents Record from which to print data + \param blimit one byte past the end of data + EMF+ manual 2.2.1.9, Microsoft name: EmfPlusStringFormat Object +*/ +int U_PMF_STRINGFORMAT_print(const char *contents, const char *blimit){ + U_PMF_STRINGFORMAT Sfs; + const char *Data; + int status = U_PMF_STRINGFORMAT_get(contents, &Sfs, &Data, blimit); + if(status){ + printf(" + StringFormat: "); + printf(" Version:%X", Sfs.Version ); + printf(" Flags:%X", Sfs.Flags ); + printf(" Language"); (void) U_PMF_LANGUAGEIDENTIFIER_print(Sfs.Language); + printf(" StringAlignment:%X", Sfs.StringAlignment ); + printf(" LineAlign:%X", Sfs.LineAlign ); + printf(" DigitSubstitution:%X",Sfs.DigitSubstitution); + printf(" DigitLanguage"); (void) U_PMF_LANGUAGEIDENTIFIER_print(Sfs.DigitLanguage); + printf(" FirstTabOffset:%f", Sfs.FirstTabOffset ); + printf(" HotkeyPrefix:%d", Sfs.HotkeyPrefix ); + printf(" LeadingMargin:%f", Sfs.LeadingMargin ); + printf(" TrailingMargin:%f", Sfs.TrailingMargin ); + printf(" Tracking:%f", Sfs.Tracking ); + printf(" Trimming:%X", Sfs.Trimming ); + printf(" TabStopCount:%u", Sfs.TabStopCount ); + printf(" RangeCount:%u", Sfs.RangeCount ); + (void) U_PMF_STRINGFORMATDATA_print(Data, Sfs.TabStopCount, Sfs.RangeCount, blimit); + } + return(status); +} + +/** + \brief Print data from a U_PMF_ARGB object + \return 1 on success, 0 on error + \param contents Record from which to print data + + Does not accept a blimit value. + EMF+ manual 2.2.2.1, Microsoft name: EmfPlusARGB Object +*/ +int U_PMF_ARGB_print(const char *contents){ + uint8_t Blue, Green, Red, Alpha; + int status = U_PMF_ARGB_get(contents, &Blue, &Green, &Red, &Alpha, contents + sizeof(U_RGBQUAD)); + if(status){ + printf(" RGBA{%2.2X,%2.2X,%2.2X,%2.2X}", Red, Green, Blue, Alpha); + } + return(status); +} + + +/** + \brief Print data from a U_PMF_BITMAP object + \return 1 on success, 0 on error + \param contents Record from which to print data + \param blimit one byte past the end of data + EMF+ manual 2.2.2.2, Microsoft name: EmfPlusBitmap Object +*/ +int U_PMF_BITMAP_print(const char *contents, const char *blimit){ + U_PMF_BITMAP Bs; + const char *Data; + int status = U_PMF_BITMAP_get(contents, &Bs, &Data, blimit); + if(status){ + printf(" + Bitmap: Width:%d Height:%d Stride:%d\n",Bs.Width, Bs.Height, Bs.Stride); + U_PMF_PX_FMT_ENUM_print(Bs.PxFormat); + switch(Bs.Type){ + case 0: printf(" Type:MSBitmap\n"); break; + case 1: printf(" Type:(PNG|JPG|GIF|EXIF|TIFF)\n"); break; + default: printf(" Type:INVALID(%d)\n",Bs.Type); break; + } + /* Pixel data is never shown - it could easily swamp the output for even a smallish picture */ + } + return(status); +} + + +/** + \brief Print data from a U_PMF_BITMAPDATA object + \return 1 on success, 0 on error + \param contents Record from which to print data + \param blimit one byte past the end of data + EMF+ manual 2.2.2.3, Microsoft name: EmfPlusBitmapData Object +*/ +int U_PMF_BITMAPDATA_print(const char *contents, const char *blimit){ + unsigned int i; + U_PMF_PALETTE Ps; + const char *Colors; + const char *Data; + int status = U_PMF_BITMAPDATA_get(contents, &Ps, &Colors, &Data, blimit); + if(status){ + status = 0; + printf(" BMData: Flags:%X, Elements:%u Colors:", Ps.Flags, Ps.Elements); + for(i=0; i<Ps.Elements; i++, Colors+=sizeof(U_PMF_ARGB)){ + (void) U_PMF_ARGB_print(Colors); + } + } + return(status); +} + +/** + \brief Print data from a U_PMF_BLENDCOLORS object + \return size in bytes on success, 0 on error + \param contents Record from which to print data + \param blimit one byte past the end of data + EMF+ manual 2.2.2.4, Microsoft name: EmfPlusBlendColors Object +*/ +int U_PMF_BLENDCOLORS_print(const char *contents, const char *blimit){ + unsigned int i; + uint32_t Elements; + U_FLOAT *Positions; + const char *Colors; + int status = U_PMF_BLENDCOLORS_get(contents, &Elements, &Positions, &Colors, blimit); + if(status){ + printf(" + BlendColors: Entries:%d (entry,pos,color): ", Elements); + for(i=0; i<Elements; i++){ + printf(" (%d,%f,", i, Positions[i]); + (void) U_PMF_ARGB_print(Colors); + Colors += sizeof(U_PMF_ARGB); + printf(")"); + } + status = sizeof(uint32_t) + Elements*sizeof(U_FLOAT) + Elements*sizeof(U_PMF_ARGB); + free(Positions); + } + return(status); +} + +/** + \brief Print data from a U_PMF_BLENDFACTORS object + \return size on success, 0 on error + \param type Type of BlendFactors, usually H or V + \param contents Record from which to print data + \param blimit one byte past the end of data + EMF+ manual 2.2.2.5, Microsoft name: EmfPlusBlendFactors Object +*/ +int U_PMF_BLENDFACTORS_print(const char *contents, const char *type, const char *blimit){ + unsigned int i; + uint32_t Elements; + U_FLOAT *Positions; + U_FLOAT *Factors; + int status = U_PMF_BLENDFACTORS_get(contents, &Elements, &Positions, &Factors, blimit); + if(status){ + printf(" + BlendFactors%s: Entries:%d (entry,pos,factor): ",type, Elements); + for(i=0; i<Elements; i++){ + printf(" (%d,%f,%f)", i, Positions[i],Factors[i]); + } + status = sizeof(uint32_t) + Elements*2*sizeof(U_FLOAT); + free(Positions); + free(Factors); + } + return(status); +} + +/** + \brief Print data from a U_PMF_BOUNDARYPATHDATA object + \return size on success, 0 on error + \param contents Record from which to print data + \param blimit one byte past the end of data + EMF+ manual 2.2.2.6, Microsoft name: EmfPlusBoundaryPathData Object +*/ +int U_PMF_BOUNDARYPATHDATA_print(const char *contents, const char * blimit){ + int32_t Size; + const char *Data; + int status = U_PMF_BOUNDARYPATHDATA_get(contents, &Size, &Data, blimit); + if(status){ + printf(" + BoundaryPathData: Size:%d\n",Size); + (void) U_PMF_PATH_print(Data, blimit); + } + return(status); +} + + +/** + \brief Print data from a U_PMF_BOUNDARYPOINTDATA object + \return size on success, 0 on error + \param contents Record from which to print data + \param blimit one byte past the end of data + EMF+ manual 2.2.2.7, Microsoft name: EmfPlusBoundaryPointData Object +*/ +int U_PMF_BOUNDARYPOINTDATA_print(const char *contents, const char *blimit){ + int32_t Elements; + U_PMF_POINTF *Points; + int status = U_PMF_BOUNDARYPOINTDATA_get(contents, &Elements, &Points, blimit); + if(status){ + printf(" + BoundaryPointData: Elements:%u\n",Elements); + U_PMF_VARPOINTF_S_print(Points, Elements); + free(Points); + } + return(status); +} + +/** + \brief Print data from a U_PMF_CHARACTERRANGE object + \return 1 on success, 0 on error + \param contents Record from which to print data + \param blimit one byte past the end of data + EMF+ manual 2.2.2.8, Microsoft name: EmfPlusCharacterRange Object +*/ +int U_PMF_CHARACTERRANGE_print(const char *contents, const char *blimit){ + int32_t First, Length; + int status = U_PMF_CHARACTERRANGE_get(contents, &First, &Length, blimit); + if(status){ + printf(" {%d,%d}",First,Length); + } + return(status); +} + +/** + \brief Print data from a U_PMF_DASHEDLINEDATA object + \return 1 on success, 0 on error + \param blimit one byte past the end of data + \param contents Record from which to print data + EMF+ manual 2.2.2.9, Microsoft name: EmfPlusCompoundLineData Object +*/ +int U_PMF_COMPOUNDLINEDATA_print(const char *contents, const char *blimit){ + int32_t Elements; + U_FLOAT *Widths; + U_FLOAT *hold; + int status = U_PMF_COMPOUNDLINEDATA_get(contents, &Elements, &Widths, blimit); + if(status){ + printf(" + CompoundLineData: Elements:%u {",Elements); + Elements--; + for(hold=Widths; Elements; Elements--,Widths++){ printf("%f, ",*Widths); } + printf("%f}",*Widths); + free(hold); + printf("\n"); + } + return(status); +} + +/** + \brief Print data from a U_PMF_COMPRESSEDIMAGE object + \return 1 on success, 0 on error + \param contents Record from which to print data + \param blimit one byte past the end of data + EMF+ manual 2.2.2.10, Microsoft name: EmfPlusCompressedImage Object + + This function does not do anything useful, but it is included so that all objects have a corresponding _get(). +*/ +int U_PMF_COMPRESSEDIMAGE_print(const char *contents, const char *blimit){ + const char *Data; + int status = U_PMF_COMPRESSEDIMAGE_get(contents, &Data, blimit); + if(status){ + printf("CompressedImage:\n"); + } + return(status); +} + +/** + \brief Print data from a U_PMF_CUSTOMENDCAPDATA object + \return 1 on success, 0 on error + \param contents Record from which to print data + \param blimit one byte past the end of data + EMF+ manual 2.2.2.11, Microsoft name: EmfPlusCustomEndCapData Object +*/ +int U_PMF_CUSTOMENDCAPDATA_print(const char *contents, const char *blimit){ + int32_t Size; + const char *Data; + int status = U_PMF_CUSTOMENDCAPDATA_get(contents, &Size, &Data, blimit); + if(status){ + printf(" + CustomEndCap: Size:%d\n",Size); + (void) U_PMF_CUSTOMLINECAP_print(Data, "End", blimit); + } + return(status); +} + +/** + \brief Print data from a U_PMF_CUSTOMLINECAPARROWDATA object + \return 1 on success, 0 on error + \param contents Record from which to print data + \param blimit one byte past the end of data + EMF+ manual 2.2.2.12, Microsoft name: EmfPlusCustomLineCapArrowData Object +*/ +int U_PMF_CUSTOMLINECAPARROWDATA_print(const char *contents, const char *blimit){ + U_PMF_CUSTOMLINECAPARROWDATA Ccad; + int status = U_PMF_CUSTOMLINECAPARROWDATA_get(contents, &Ccad, blimit); + if(status){ + printf("CustomLineCapArrowData: "); + printf(" Width:%f", Ccad.Width ); + printf(" Height:%f", Ccad.Height ); + printf(" MiddleInset:%f", Ccad.MiddleInset ); + printf(" FillState:%u", Ccad.FillState ); + printf(" StartCap:%X", Ccad.StartCap ); + printf(" EndCap:%X", Ccad.EndCap ); + printf(" Join:%X", Ccad.Join ); + printf(" MiterLimit:%f", Ccad.MiterLimit ); + printf(" WidthScale:%f", Ccad.WidthScale ); + printf(" FillHotSpot:{%f,%f}",Ccad.FillHotSpot[0],Ccad.FillHotSpot[1]); + printf(" LineHotSpot:{%f,%f}",Ccad.LineHotSpot[0],Ccad.LineHotSpot[1]); + printf("\n"); + } + return(status); +} + +/** + \brief Print data from a U_PMF_CUSTOMLINECAPDATA object + \return 1 on success, 0 on error + \param contents Record from which to print data + \param blimit one byte past the end of data + EMF+ manual 2.2.2.13, Microsoft name: EmfPlusCustomLineCapData Object +*/ +int U_PMF_CUSTOMLINECAPDATA_print(const char *contents, const char *blimit){ + U_PMF_CUSTOMLINECAPDATA Clcd; + const char *Data; + int status = U_PMF_CUSTOMLINECAPDATA_get(contents, &Clcd, &Data, blimit); + if(status){ + printf(" + CustomLineCapData: "); + printf(" Flags:%X", Clcd.Flags ); + printf(" Cap:%X", Clcd.Cap ); + printf(" Inset:%f", Clcd.Inset ); + printf(" StartCap:%X", Clcd.StartCap ); + printf(" EndCap:%X", Clcd.EndCap ); + printf(" Join:%X", Clcd.Join ); + printf(" MiterLimit:%f", Clcd.MiterLimit ); + printf(" WidthScale:%f", Clcd.WidthScale ); + printf(" FillHotSpot:{%f,%f}",Clcd.FillHotSpot[0],Clcd.FillHotSpot[1]); + printf(" LineHotSpot:{%f,%f}\n",Clcd.LineHotSpot[0],Clcd.LineHotSpot[1]); + (void) U_PMF_CUSTOMLINECAPOPTIONALDATA_print(Data, Clcd.Flags, blimit); + /* preceding line always emits an EOL */ + } + return(status); +} + + +/** + \brief Print data from a U_PMF_CUSTOMLINECAPOPTIONALDATA object + \return 1 on success, 0 on error + \param contents Record from which to print data + \param Flags CustomLineCapData Flags + \param blimit one byte past the end of data + + EMF+ manual 2.2.2.14, Microsoft name: EmfPlusCustomLineCapOptionalData Object +*/ +int U_PMF_CUSTOMLINECAPOPTIONALDATA_print(const char *contents, uint32_t Flags, const char *blimit){ + const char *FillData; + const char *LineData; + int status = U_PMF_CUSTOMLINECAPOPTIONALDATA_get(contents, Flags, &FillData, &LineData, blimit); + if(status){ /* True even if there is nothing in it! */ + printf(" + CustomLineCapOptionalData:"); + if(FillData || LineData){ + if(FillData){ (void) U_PMF_FILLPATHOBJ_print(FillData, blimit); } + if(LineData){ (void) U_PMF_LINEPATH_print(LineData, blimit); } + } + else { + printf("None"); + } + } + if(status<=1){ printf("\n"); } + return(status); +} + +/** + \brief Print data from a U_PMF_CUSTOMSTARTCAPDATA object + \return 1 on success, 0 on error + \param contents Record from which to print data + \param blimit one byte past the end of data + EMF+ manual 2.2.2.15, Microsoft name: EmfPlusCustomStartCapData Object +*/ +int U_PMF_CUSTOMSTARTCAPDATA_print(const char *contents, const char *blimit){ + int32_t Size; + const char *Data; + int status = U_PMF_CUSTOMSTARTCAPDATA_get(contents, &Size, &Data, blimit); + if(status){ + printf(" + CustomStartCap: Size:%d ",Size); + (void) U_PMF_CUSTOMLINECAP_print(Data, "Start", blimit); + } + return(status); +} + +/** + \brief Print data from a U_PMF_DASHEDLINEDATA object + \return 1 on success, 0 on error + \param contents Record from which to print data + \param blimit one byte past the end of data + EMF+ manual 2.2.2.16, Microsoft name: EmfPlusDashedLineData Object +*/ +int U_PMF_DASHEDLINEDATA_print(const char *contents, const char *blimit){ + int32_t Elements; + U_FLOAT *Lengths; + U_FLOAT *hold; + int status = U_PMF_DASHEDLINEDATA_get(contents, &Elements, &Lengths, blimit); + if(status){ + printf(" DashedLineData: Elements:%u {",Elements); + Elements--; + for(hold=Lengths; Elements; Elements--, Lengths++){ printf("%f, ", *Lengths); } + printf("%f}", *Lengths); + free(hold); + } + return(status); +} + +/** + \brief Print data from a U_PMF_FILLPATHOBJ object + \return 1 on success, 0 on error + \param contents Record from which to print data + \param blimit one byte past the end of data + EMF+ manual 2.2.2.17, Microsoft name: EmfPlusFillPath Object +*/ +int U_PMF_FILLPATHOBJ_print(const char *contents, const char * blimit){ + int32_t Size; + const char *Data; + int status = U_PMF_FILLPATHOBJ_get(contents, &Size, &Data, blimit); + if(status){ + printf(" FillPathObj: Size:%d\n",Size); + if(Size){ (void) U_PMF_PATH_print(Data, blimit); } + } + return(status); +} + +/** + \brief Print data from a U_PMF_FOCUSSCALEDATA object + \return 1 on success, 0 on error + \param contents Record from which to print data + \param blimit one byte past the end of data + EMF+ manual 2.2.2.18, Microsoft name: EmfPlusFocusScaleData Object +*/ +int U_PMF_FOCUSSCALEDATA_print(const char *contents, const char *blimit){ + uint32_t Count; + U_FLOAT ScaleX, ScaleY; + int status = U_PMF_FOCUSSCALEDATA_get(contents, &Count, &ScaleX, &ScaleY, blimit); + if(status){ + printf(" FocusScaleData: Count:%d ScaleX:%f ScaleY:%f ",Count,ScaleX,ScaleY); + } + return(status); +} + +/** + \brief Print data from a U_PMF_GRAPHICSVERSION object already known to be memory safe + \return 1 on success, 0 on error + \param contents Record from which to print data + EMF+ manual 2.2.2.19, Microsoft name: EmfPlusGraphicsVersion Object + + In this module the only time a U_PMF_GRAPHICSVERSION is printed is after it + has already been copied into a safe memory structure. This routine fakes up + a blimit for the general routine. + +*/ +int U_PMF_GRAPHICSVERSION_memsafe_print(const char *contents){ + const char *blimit = contents + sizeof(U_PMF_GRAPHICSVERSION); + return(U_PMF_GRAPHICSVERSION_print(contents, blimit)); +} + +/** + \brief Print data from a U_PMF_GRAPHICSVERSION object + \return 1 on success, 0 on error + \param contents Record from which to print data + \param blimit one byte past the end of data + EMF+ manual 2.2.2.19, Microsoft name: EmfPlusGraphicsVersion Object +*/ +int U_PMF_GRAPHICSVERSION_print(const char *contents, const char *blimit){ + int Signature,GrfVersion; + int status = U_PMF_GRAPHICSVERSION_get(contents, &Signature, &GrfVersion, blimit); + if(status){ + printf(" MetaFileSig:%X",Signature ); + printf(" GraphicsVersion:%X", GrfVersion); + } + return(status); +} + + +/** + \brief Print data from a U_PMF_HATCHBRUSHDATA object + \return 1 on success, 0 on error + \param contents Record from which to print data + \param blimit One byte past the last record in memory. + EMF+ manual 2.2.2.20, Microsoft name: EmfPlusHatchBrushData Object +*/ +int U_PMF_HATCHBRUSHDATA_print(const char *contents, const char *blimit){ + uint32_t Style; + U_PMF_ARGB Foreground, Background; + int status = U_PMF_HATCHBRUSHDATA_get(contents, &Style, &Foreground, &Background, blimit); + if(status){ + printf(" + HBdata: Style:%u(",Style); + U_PMF_HATCHSTYLEENUMERATION_print(Style); + printf(") FG:{"); + (void) U_PMF_ARGB_print((char *)&Foreground); + printf("} BG:{"); + (void) U_PMF_ARGB_print((char *)&Background); + printf("}"); + } + return(status); +} + +/** + \brief Print data from a U_PMF_LANGUAGEIDENTIFIER object + \return 1 on success, 0 on error + \param LId Record from which to print data + EMF+ manual 2.2.2.23, Microsoft name: EmfPlusLanguageIdentifier Object +*/ +int U_PMF_LANGUAGEIDENTIFIER_print(U_PMF_LANGUAGEIDENTIFIER LId){ + int SubLId, PriLId; + int status = U_PMF_LANGUAGEIDENTIFIER_get(LId, &SubLId, &PriLId); + if(status){ /* do it the hard way just to verify that the preceding call works, OK to just print LId directly */ + printf("{%4.4X}",U_PMF_LANGUAGEIDENTIFIEROBJ_set(SubLId, PriLId)); + } + return(status); +} + + + +/** + \brief Print data from a U_PMF_LINEARGRADIENTBRUSHDATA object + \return 1 on success, 0 on error + \param contents Record from which to print data + \param blimit One byte past the last record in memory. + EMF+ manual 2.2.2.24, Microsoft name: EmfPlusLinearGradientBrushData Object +*/ +int U_PMF_LINEARGRADIENTBRUSHDATA_print(const char *contents, const char *blimit){ + U_PMF_LINEARGRADIENTBRUSHDATA Lgbd; + const char *Data; + int status = U_PMF_LINEARGRADIENTBRUSHDATA_get(contents, &Lgbd, &Data, blimit); + if(status){ + printf(" + LinearGradientBrushData: Flags:%X WrapMode:%d Rect:",Lgbd.Flags, Lgbd.WrapMode); + (void) U_PMF_RECTF_S_print(&(Lgbd.RectF)); + printf(" StartColor:"); + (void) U_PMF_ARGB_print((char *)&(Lgbd.StartColor)); + printf(" EndColor:"); + (void) U_PMF_ARGB_print((char *)&(Lgbd.EndColor)); + /* Technically these are to be ignored, in practice they must be colors with the same value as the preceding 2*/ + printf(" Reserved1:"); + (void) U_PMF_ARGB_print((char *)&(Lgbd.Reserved1)); + printf(" Reserved2:"); + (void) U_PMF_ARGB_print((char *)&(Lgbd.Reserved2)); + printf("\n"); + (void) U_PMF_LINEARGRADIENTBRUSHOPTIONALDATA_print(Data, Lgbd.Flags, blimit); + } + return(status); +} + + + +/** + \brief Print data from a U_PMF_LINEARGRADIENTBRUSHOPTIONALDATA object + \return 1 on success, 0 on error + \param contents Record from which to print data + \param BDFlag Describes optional values in contents + \param blimit One byte past the last record in memory. + EMF+ manual 2.2.2.25, Microsoft name: EmfPlusLinearGradientBrushOptionalData Object +*/ +int U_PMF_LINEARGRADIENTBRUSHOPTIONALDATA_print(const char *contents, int BDFlag, const char *blimit){ + U_PMF_TRANSFORMMATRIX Tm; + const char *Bc; + const char *BfH; + const char *BfV; + int None=1; + printf(" + LinearGradientBrushOptionalData: "); + int status = U_PMF_LINEARGRADIENTBRUSHOPTIONALDATA_get(contents, BDFlag, &Tm, &Bc, &BfH, &BfV, blimit); + if(status){ + if(BDFlag & U_BD_Transform){ + U_PMF_TRANSFORMMATRIX2_print(&Tm); + None=0; + } + if(Bc){ + printf("\n"); + (void) U_PMF_BLENDCOLORS_print(Bc, blimit); + None=0; + } + if(BfH){ + printf("\n"); + (void) U_PMF_BLENDFACTORS_print(BfH,"H", blimit); + None=0; + } + if(BfV){ + printf("\n"); + (void) U_PMF_BLENDFACTORS_print(BfV,"V", blimit); + None=0; + } + if(None){ + printf("(none)"); + } + } + return(status); +} + +/** + \brief Print data from a U_PMF_LINEPATH object + \return 1 on success, 0 on error + \param contents Record from which to print data + \param blimit one byte past the end of data + EMF+ manual 2.2.2.26, Microsoft name: EmfPlusLinePath Object +*/ +int U_PMF_LINEPATH_print(const char *contents, const char * blimit){ + int32_t Size; + const char *Data; + int status = U_PMF_LINEPATH_get(contents, &Size, &Data, blimit); + if(status){ + printf(" LinePath: Size:%d\n", Size); + (void) U_PMF_PATH_print(Data, blimit); + } + return(status); +} + +/** + \brief Print data from a U_PMF_METAFILE object + \return 1 on success, 0 on error + \param contents Record from which to print data + \param blimit one byte past the end of data + EMF+ manual 2.2.2.27, Microsoft name: EmfPlusMetafile Object +*/ +int U_PMF_METAFILE_print(const char *contents, const char * blimit){ + uint32_t Type; + uint32_t Size; + const char *Data; + int status = U_PMF_METAFILE_get(contents, &Type, &Size, &Data, blimit); + if(status){ + printf(" MetaFile: Type:%X Size:%d",Type, Size); + /* embedded metafiles are not handled beyond this*/ + } + return(status); +} + +/** + \brief Print data from a U_PMF_PALETTE object + \return 1 on success, 0 on error + \param contents Record from which to print data + \param blimit one byte past the end of data + EMF+ manual 2.2.2.28, Microsoft name: EmfPlusPalette Object +*/ +int U_PMF_PALETTE_print(const char *contents, const char *blimit){ + unsigned int i; + uint32_t Flags; + uint32_t Elements; + const char *Data; + int status = U_PMF_PALETTE_get(contents, &Flags, &Elements, &Data, blimit); + if(status){ + printf(" Palette: Flags:%X Elements:%u Colors:",Flags, Elements); + for(i=0; i<Elements; i++){ + (void) U_PMF_ARGB_print(Data); + Data += sizeof(U_PMF_ARGB); + } + printf("\n"); + } + return(status); +} + +/** + \brief Print data from a U_PMF_PATHGRADIENTBRUSHDATA object + \return 1 on success, 0 on error + \param contents Record from which to print data + \param blimit one byte past the end of data + EMF+ manual 2.2.2.29, Microsoft name: EmfPlusPathGradientBrushData Object +*/ +int U_PMF_PATHGRADIENTBRUSHDATA_print(const char *contents, const char *blimit){ + U_PMF_PATHGRADIENTBRUSHDATA Pgbd; + const char *Gradient; + const char *Boundary; + const char *Data=NULL; + unsigned int i; + int status = U_PMF_PATHGRADIENTBRUSHDATA_get(contents, &Pgbd, &Gradient, &Boundary, &Data, blimit); + if(status){ + printf(" + PathGradientBrushData: Flags:%X WrapMode:%d, CenterColor:",Pgbd.Flags, Pgbd.WrapMode); + (void) U_PMF_ARGB_print((char *)&(Pgbd.CenterColor)); + printf(" Center:"); + (void) U_PMF_POINTF_S_print(&(Pgbd.Center)); + printf(" Elements:%u\n",Pgbd.Elements); + if(Pgbd.Elements){ + printf(" + SurroundingColor: "); + for(i=Pgbd.Elements; i; i--, Gradient+=4){ + (void) U_PMF_ARGB_print(Gradient); + } + printf("\n"); + } + if(Pgbd.Flags & U_BD_Path){ + (void) U_PMF_BOUNDARYPATHDATA_print(Boundary, blimit); + } + else { + (void) U_PMF_BOUNDARYPOINTDATA_print(Boundary, blimit); + } + (void) U_PMF_PATHGRADIENTBRUSHOPTIONALDATA_print(Data, Pgbd.Flags, blimit); + } + return(status); +} + +/** + \brief Print data from a U_PMF_PATHGRADIENTBRUSHOPTIONALDATA object + \return 1 on success, 0 on error + \param contents Record from which to print data + \param BDFlag Describes optional values in contents + \param blimit one byte past the end of data + EMF+ manual 2.2.2.30, Microsoft name: EmfPlusPathGradientBrushOptionalData Object +*/ +int U_PMF_PATHGRADIENTBRUSHOPTIONALDATA_print(const char *contents, int BDFlag, const char *blimit){ + if(BDFlag & (U_BD_Transform | U_BD_PresetColors | U_BD_BlendFactorsH | U_BD_FocusScales)){ + printf(" + PathGradientBrushOptionalData: "); + } + if(BDFlag & U_BD_Transform){ + U_PMF_TRANSFORMMATRIX_print(contents, blimit); + contents += sizeof(U_PMF_TRANSFORMMATRIX); + } + if(BDFlag & U_BD_PresetColors){ /* If this is present, BlendFactorsH will not be */ + contents += U_PMF_BLENDCOLORS_print(contents, blimit); + } + if(BDFlag & U_BD_BlendFactorsH){/* If this is present, U_BD_PresetColors will not be */ + contents += U_PMF_BLENDFACTORS_print(contents,"", blimit); + } + if(BDFlag & U_BD_FocusScales){ + contents += U_PMF_BLENDFACTORS_print(contents,"", blimit); + U_PMF_FOCUSSCALEDATA_print(contents, blimit); + } + return(1); +} + +/** + \brief Print data from a U_PMF_PATHPOINTTYPE object + \return 1 on success, 0 on error + \param contents Record from which to print data + \param blimit one byte past the end of data + EMF+ manual 2.2.2.31, Microsoft name: EmfPlusPathPointType Object +*/ +int U_PMF_PATHPOINTTYPE_print(const char *contents, const char *blimit){ + int Flags, Type; + int status = U_PMF_PATHPOINTTYPE_get(contents, &Flags, &Type, blimit); + if(status){ + printf("{Flags:%X Type:",Flags); + (void) U_PMF_PATHPOINTTYPE_ENUM_print(Type); + printf("}"); + } + return(status); +} + +/** + \brief Print data from a U_PMF_PATHPOINTTYPERLE object + \return Number of elements in the run, 0 on error + \param contents Record from which to print data + \param blimit one byte past the end of data + EMF+ manual 2.2.2.32, Microsoft name: EmfPlusPathPointTypeRLE Object +*/ +int U_PMF_PATHPOINTTYPERLE_print(const char *contents, const char *blimit){ + int Bezier, Elements, Type; + int status = U_PMF_PATHPOINTTYPERLE_get(contents, &Bezier, &Elements, &Type, blimit); + if(status){ + status = Elements; + printf(" PathPointTypeRLE: Bezier:%c Elements:%u, Type: ",(Bezier ? 'Y' : 'N'), Elements); + (void) U_PMF_PATHPOINTTYPE_ENUM_print(Type); + printf("\n"); + } + return(status); +} + +/** + \brief Print data from a U_PMF_PATHPOINTTYPERLE object + \return 1 on success, 0 on error + \param contents Record from which to print data + \param blimit one byte past the end of data + EMF+ manual 2.2.2.33, Microsoft name: EmfPlusPenData Object +*/ +int U_PMF_PENDATA_print(const char *contents, const char *blimit){ + uint32_t Flags, Unit; + U_FLOAT Width; + const char *Data; + int status = U_PMF_PENDATA_get(contents, &Flags, &Unit, &Width, &Data, blimit); + if(status){ + printf(" + Pendata: Flags:%X Unit:%X Width:%f",Flags, Unit, Width); + (void) U_PMF_PENOPTIONALDATA_print(Data, Flags, blimit); /* prints a new line at end */ + } + return(status); +} + + + +/** + \brief Print data from a U_PMF_PENOPTIONALDATA object + \return 1 on success, 0 on error + \param contents Record from which to print data + \param blimit one byte past the end of data + \param Flags PenData Flags that determine which optionaldata fields are present in the record. + + EMF+ manual 2.2.2.34, Microsoft name: EmfPlusPenOptionalData Object +*/ +int U_PMF_PENOPTIONALDATA_print(const char *contents, int Flags, const char *blimit){ + U_PMF_TRANSFORMMATRIX Matrix; + int32_t StartCap; + int32_t EndCap; + uint32_t Join; + U_FLOAT MiterLimit; + int32_t Style; + int32_t DLCap; + U_FLOAT DLOffset; + const char *DLData; + int32_t Alignment; + const char *CmpndLineData; + const char *CSCapData; + const char *CECapData; + int status = U_PMF_PENOPTIONALDATA_get( + contents, + Flags, // determines which fields are filled + &Matrix, + &StartCap, + &EndCap, + &Join, + &MiterLimit, + &Style, + &DLCap, + &DLOffset, + &DLData, + &Alignment, + &CmpndLineData, + &CSCapData, + &CECapData, + blimit); + if(status){ + if(Flags & U_PD_Transform){ (void) U_PMF_TRANSFORMMATRIX2_print(&Matrix);} + if(Flags & U_PD_StartCap){ printf(" StartCap:%d", StartCap );} + if(Flags & U_PD_EndCap){ printf(" EndCap:%d", EndCap );} + if(Flags & U_PD_Join){ printf(" Join:%X", Join );} + if(Flags & U_PD_MiterLimit){ printf(" MiterLimit:%f", MiterLimit );} + if(Flags & U_PD_LineStyle){ printf(" Style:%X", Style );} + if(Flags & U_PD_DLCap){ printf(" DLCap:%X", DLCap );} + if(Flags & U_PD_DLOffset){ printf(" DLOffset:%f", DLOffset );} + if(Flags & U_PD_DLData){ (void) U_PMF_DASHEDLINEDATA_print(DLData, blimit );} + if(Flags & U_PD_NonCenter){ printf(" Alignment:%d", Alignment );} + if(Flags & (U_PD_Transform | U_PD_StartCap | U_PD_EndCap | + U_PD_Join | U_PD_MiterLimit | U_PD_LineStyle | + U_PD_DLCap | U_PD_DLOffset |U_PD_DLData |U_PD_NonCenter)){ printf("\n"); } + if(Flags & U_PD_CLData){ (void) U_PMF_COMPOUNDLINEDATA_print(CmpndLineData, blimit); } + if(Flags & U_PD_CustomStartCap){ (void) U_PMF_CUSTOMSTARTCAPDATA_print(CSCapData, blimit); } + if(Flags & U_PD_CustomEndCap){ (void) U_PMF_CUSTOMENDCAPDATA_print(CECapData, blimit); } + } + return(status); +} +/** + \brief Print data from a U_PMF_POINT object + \return 1 on success, 0 on error + \param contents Record from which to print data + \param blimit one byte past the end of data + EMF+ manual 2.2.2.35, Microsoft name: EmfPlusPoint Object +*/ +int U_PMF_POINT_print(const char **contents, const char *blimit){ + U_FLOAT X, Y; + int status = U_PMF_POINT_get(contents, &X, &Y, blimit); + if(status){ + printf("{%f,%f}", X, Y); + } + return(status); +} + +/** + \brief Print data from a U_PMF_POINT Structure + \return 1 on success, 0 on error + \param Point U_PMF_POINT Structure to print + EMF+ manual 2.2.2.35, Microsoft name: EmfPlusPoint Object +*/ +int U_PMF_POINT_S_print(U_PMF_POINT *Point){\ + if(!Point){ return(0); } + printf("{%d,%d}", Point->X, Point->Y); + return(1); +} + +/** + \brief Print data from a U_PMF_POINTF object + \return 1 on success, 0 on error + \param contents Record from which to print data + \param blimit one byte past the end of data + EMF+ manual 2.2.2.36, Microsoft name: EmfPlusPointF Object +*/ +int U_PMF_POINTF_print(const char **contents, const char *blimit){ + U_FLOAT X, Y; + int status = U_PMF_POINTF_get(contents, &X, &Y, blimit); + if(status){ + printf("{%f,%f}", X, Y); + } + return(status); +} + +/** + \brief Print data from a U_PMF_POINTF Structure + \return 1 on success, 0 on error + \param Point U_PMF_POINTF Structure to print + EMF+ manual 2.2.2.36, Microsoft name: EmfPlusPointF Object +*/ +int U_PMF_POINTF_S_print(U_PMF_POINTF *Point){ + if(!Point){ return(0); } + printf("{%f,%f}", Point->X, Point->Y); + return(1); +} + +/** + \brief Print data from a U_PMF_POINTR object + \return bytes traversed on success, 0 on error + \param contents Pointer to next data to print + \param Xpos X coordinate for current point + \param Ypos Y coordinate for current point + \param blimit one byte past the end of data + + On each call the next relative offset is extracted, the current + coordinates are modified with that offset, and the pointer is + advanced to the next data point. + + EMF+ manual 2.2.2.37, Microsoft name: EmfPlusPointR Object +*/ +int U_PMF_POINTR_print(const char **contents, U_FLOAT *Xpos, U_FLOAT *Ypos, const char *blimit){ + U_FLOAT X, Y; + int status = U_PMF_POINTR_get(contents, &X, &Y, blimit); + *Xpos += X; + *Ypos += Y; + if(status){ + printf("{%f,%f(%f,%f)}", *Xpos, *Ypos, X, Y); + } + return(status); +} + +/** + \brief Print data from a U_PMF_RECT object + \return 1 on success, 0 on error + \param contents Record from which to print data + \param blimit one byte past the end of data + EMF+ manual 2.2.2.38, Microsoft name: EmfPlusRect Object +*/ +int U_PMF_RECT_print(const char **contents, const char *blimit){ + int16_t X, Y, Width, Height; + int status = U_PMF_RECT_get(contents, &X, &Y, &Width, &Height, blimit); + if(status){ + printf("{UL{%d,%d},WH{%d,%d}}", X, Y, Width, Height); + } + return(status); +} + +/** + \brief Print data from a U_PMF_RECT Structure + \return 1 on success, 0 on error + \param Rect U_PMF_RECT structure + EMF+ manual 2.2.2.39, Microsoft name: EmfPlusRectF Object +*/ +int U_PMF_RECT_S_print(U_PMF_RECT *Rect){ + printf("{UL{%d,%d},WH{%d,%d}}", Rect->X, Rect->Y, Rect->Width, Rect->Height); + return(1); +} + +/** + \brief Print data from a U_PMF_RECTF object + \return 1 on success, 0 on error + \param contents Record from which to print data + \param blimit one byte past the end of data + EMF+ manual 2.2.2.39, Microsoft name: EmfPlusRectF Object +*/ +int U_PMF_RECTF_print(const char **contents, const char *blimit){ + U_FLOAT X, Y, Width, Height; + int status = U_PMF_RECTF_get(contents, &X, &Y, &Width, &Height, blimit); + if(status){ + printf("{UL{%f,%f},WH{%f,%f}}", X, Y, Width, Height); + } + return(status); +} + +/** + \brief Print data from a U_PMF_RECTF Structure + \return 1 on success, 0 on error + \param Rect U_PMF_RECTF Structure + EMF+ manual 2.2.2.39, Microsoft name: EmfPlusRectF Object +*/ +int U_PMF_RECTF_S_print(U_PMF_RECTF *Rect){ + printf("{UL{%f,%f},WH{%f,%f}}", Rect->X, Rect->Y, Rect->Width, Rect->Height); + return(1); +} + +/** + \brief Print data from a U_PMF_REGIONNODE object + \return size on success, 0 on error + \param contents Record from which to print data + \param Level Tree level. This routine is recursive and could go down many levels. 1 is the top, >1 are child nodes. + \param blimit one byte past the end of data + EMF+ manual 2.2.2.40, Microsoft name: EmfPlusRegionNode Object +*/ +int U_PMF_REGIONNODE_print(const char *contents, int Level, const char *blimit){ + int len=4; /* Type will always be present */ + uint32_t Type; + const char *Data; + int status = U_PMF_REGIONNODE_get(contents, &Type, &Data, blimit); + if(status){ + printf("\n + RegionNode(Level:%d) { Type:%X(",Level,Type); + U_PMF_NODETYPE_print(Type); + printf(")"); + if(Type >= U_RNDT_And && Type <= U_RNDT_Complement){ + len += U_PMF_REGIONNODECHILDNODES_print(Data, Level+1, blimit); + } + else if(Type == U_RNDT_Rect){ + len += sizeof(U_PMF_RECTF); + (void) U_PMF_RECTF_print(&Data, blimit); + printf("\n"); + } + else if(Type == U_RNDT_Path){ + len += U_PMF_REGIONNODEPATH_print(Data, blimit); + } + /* U_RNDT_Empty and U_RNDT_Infinite do not change the length */ + else if(Type == U_RNDT_Empty ){ printf(" Empty" ); } + else if(Type == U_RNDT_Infinite ){ printf(" Infinite" ); } + printf(" + RegionNode(Level:%d) }",Level); + status = len; /* length of data + length of type */ + } + printf("\n"); + return(status); +} + +/** + \brief Print data from a U_PMF_REGIONNODECHILDNODES object + \return size on success, 0 on error + \param contents Record from which to print data + \param Level Tree level. This routine is recursive and could go down many levels. 1 is the top, >1 are child nodes. + \param blimit one byte past the end of data + EMF+ manual 2.2.2.41, Microsoft name: EmfPlusRegionNodeChildNodes Object +*/ +int U_PMF_REGIONNODECHILDNODES_print(const char *contents, int Level, const char *blimit){ + uint32_t size,rsize; + printf(" RegionNodeChildNodes:\n"); + printf(" + RNCN__Left(Level:%d) {", Level); + size = U_PMF_REGIONNODE_print(contents, Level, blimit); + printf(" + RNCN__Left(Level:%d) },\n", Level); + if(size){ + contents += size; + printf(" + RNCN_Right(Level:%d) {", Level); + rsize = U_PMF_REGIONNODE_print(contents, Level, blimit); + size += rsize; + printf(" + RNCN_Right(Level:%d) },\n",Level); + } + return(size); +} + +/** + \brief Print data from a U_PMF_REGIONNODEPATH object + \return Size of data on success, 0 on error + \param contents Record from which to print data + \param blimit one byte past the end of data + EMF+ manual 2.2.2.42, Microsoft name: EmfPlusRegionNodePath Object +*/ +int U_PMF_REGIONNODEPATH_print(const char *contents, const char * blimit){ + int32_t Size; + const char *Data; + int status = U_PMF_REGIONNODEPATH_get(contents, &Size, &Data, blimit); + if(status){ + printf(" RegionNodePath: \n"); + (void) U_PMF_PATH_print(Data, blimit); + status = Size + 4; /* data sizee + the 4 bytes encoding the size */ + } + return(status); +} + + +/** + \brief Print data from a U_PMF_SOLIDBRUSHDATA object + \return 1 on success, 0 on error + \param contents Record from which to print data + \param blimit one byte past the end of data + EMF+ manual 2.2.2.43, Microsoft name: EmfPlusSolidBrushData Object +*/ +int U_PMF_SOLIDBRUSHDATA_print(const char *contents, const char *blimit){ + U_PMF_ARGB Color; + int status = U_PMF_SOLIDBRUSHDATA_get(contents, &Color, blimit); + if(status){ + printf(" SolidBrushData: "); + (void) U_PMF_ARGB_print((char *) &Color); + } + return(status); +} + +/** + \brief Print data from a U_PMF_STRINGFORMATDATA object + \return 1 on success, 0 on error + \param contents Record from which to print data + \param TabStopCount Entries in TabStop array + \param RangeCount Entries in CharRange array + \param blimit one byte past the end of data + EMF+ manual 2.2.2.44, Microsoft name: EmfPlusStringFormatData Object +*/ +int U_PMF_STRINGFORMATDATA_print(const char *contents, uint32_t TabStopCount, uint32_t RangeCount, const char *blimit){ + const U_FLOAT *TabStops; + const U_PMF_CHARACTERRANGE *CharRange; + int status = U_PMF_STRINGFORMATDATA_get(contents, TabStopCount, RangeCount, &TabStops, &CharRange, blimit); + if(status){ + printf(" SFdata: TabStopCount:%u RangeCount:%u\n", TabStopCount, RangeCount); + + printf(" Tabstops:"); + for(; TabStopCount; TabStopCount--,TabStops++){ printf(" %f",*TabStops); } + printf("\n"); + + printf(" CharRange:"); + for(; RangeCount; RangeCount--,CharRange++){ printf(" {%d,%d}",CharRange->First,CharRange->Length); } + printf("\n"); + + } + return(status); +} + +/** + \brief Print data from a U_PMF_TEXTUREBRUSHDATA object + \return 1 on success, 0 on error + \param contents Record from which to print data + \param blimit one byte past the end of data + EMF+ manual 2.2.2.45, Microsoft name: EmfPlusTextureBrushData Object +*/ +int U_PMF_TEXTUREBRUSHDATA_print(const char *contents, const char *blimit){ + uint32_t Flags; + int32_t WrapMode; + const char *Data; + int status = U_PMF_TEXTUREBRUSHDATA_get(contents, &Flags, &WrapMode, &Data, blimit); + if(status){ + printf(" + TBdata: Flags:%X WrapMode:%d", Flags, WrapMode); + } + return(status); +} + +/** + \brief Print data from a U_PMF_TEXTUREBRUSHOPTIONALDATA object + \return 1 on success, 0 on error + \param contents Record from which to print data + \param HasMatrix True if the record contains a matrix. + \param HasImage True if the record contains an image. + \param blimit one byte past the end of data + + EMF+ manual 2.2.2.46, Microsoft name: EmfPlusTextureBrushOptionalData Object +*/ +int U_PMF_TEXTUREBRUSHOPTIONALDATA_print(const char *contents, int HasMatrix, int HasImage, const char *blimit){ + U_PMF_TRANSFORMMATRIX Matrix; + U_PMF_TRANSFORMMATRIX *pMatrix; + const char *Image; + if(HasMatrix){ pMatrix = &Matrix; } + else { pMatrix = NULL; } + int status = U_PMF_TEXTUREBRUSHOPTIONALDATA_get(contents, HasImage, pMatrix, &Image, blimit); + if(status){ + printf(" + TBOptdata: Image:%c", (HasImage ? 'Y' : 'N')); + (void) U_PMF_TRANSFORMMATRIX2_print(&Matrix); + (void) U_PMF_IMAGE_print(Image, blimit); + } + return(status); +} + +/** + \brief Print data from a U_PMF_TRANSFORMMATRIX object stored in file byte order. + \return 1 on success, 0 on error + \param contents Record from which to print data + \param blimit one byte past the end of data + EMF+ manual 2.2.2.47, Microsoft name: EmfPlusTransformMatrix Object +*/ +int U_PMF_TRANSFORMMATRIX_print(const char *contents, const char *blimit){ + U_PMF_TRANSFORMMATRIX Tm; + int status = U_PMF_TRANSFORMMATRIX_get(contents, &Tm, blimit); + if(status){ + U_PMF_TRANSFORMMATRIX2_print(&Tm); + } + return(status); +} + +/** + \brief Print data from a U_PMF_TRANSFORMMATRIX structure + \return 1 on success, 0 on error + \param Tm U_PMF_TRANSFORMMATRIX structure + EMF+ manual 2.2.2.47, Microsoft name: EmfPlusTransformMatrix Object +*/ +int U_PMF_TRANSFORMMATRIX2_print(U_PMF_TRANSFORMMATRIX *Tm){ + if(Tm){ + printf(" Matrix:{%f,%f,%f,%f,%f,%f}", Tm->m11, Tm->m12, Tm->m21, Tm->m22, Tm->dX, Tm->dY); + } + else { + printf(" Matrix:(None)"); + } + return(1); +} + +/** + \brief Print data from a U_PMF_ROTMATRIX object + \return 1 on success, 0 on error + \param Rm U_PMF_ROTMATRIX object + NOT DOCUMENTED, like EMF+ manual 2.2.2.47, Microsoft name: EmfPlusTransformMatrix Object, but missing offset values +*/ +int U_PMF_ROTMATRIX2_print(U_PMF_ROTMATRIX *Rm){ + printf(" Matrix:{%f,%f,%f,%f}", Rm->m11, Rm->m12, Rm->m21, Rm->m22); + return(1); +} + +/** + \brief Print data from a U_PMF_IE_BLUR object + \return 1 on success, 0 on error + \param contents Record from which to print data + \param blimit one byte past the end of data + EMF+ manual 2.2.3.1, Microsoft name: BlurEffect Object +*/ +int U_PMF_IE_BLUR_print(const char *contents, const char *blimit){ + U_FLOAT Radius; + uint32_t ExpandEdge; + int status = U_PMF_IE_BLUR_get(contents, &Radius, &ExpandEdge, blimit); + if(status){ + printf("BlurEffect Radius:%f ExpandEdge:%u\n", Radius, ExpandEdge); + } + return(status); +} + +/** + \brief Print data from a U_PMF_IE_BRIGHTNESSCONTRAST object + \return 1 on success, 0 on error + \param contents Record from which to print data + \param blimit one byte past the end of data + EMF+ manual 2.2.3.2, Microsoft name: BrightnessContrastEffect Object +*/ +int U_PMF_IE_BRIGHTNESSCONTRAST_print(const char *contents, const char *blimit){ + int32_t Brightness, Contrast; + int status = U_PMF_IE_BRIGHTNESSCONTRAST_get(contents, &Brightness, &Contrast, blimit); + if(status){ + printf("BrightnessContrastEffect Brightness:%d Contrast:%d\n", Brightness, Contrast); + } + return(status); +} + +/** + \brief Print data from a U_PMF_IE_COLORBALANCE object + \return 1 on success, 0 on error + \param contents Record from which to print data + \param blimit one byte past the end of data + EMF+ manual 2.2.3.3, Microsoft name: ColorBalanceEffect Object +*/ +int U_PMF_IE_COLORBALANCE_print(const char *contents, const char *blimit){ + int32_t CyanRed, MagentaGreen, YellowBlue; + int status = U_PMF_IE_COLORBALANCE_get(contents, &CyanRed, &MagentaGreen, &YellowBlue, blimit); + if(status){ + printf("ColorBalanceEffect CyanRed:%d MagentaGreen:%d YellowBlue:%d\n", CyanRed, MagentaGreen, YellowBlue); + } + return(status); +} + +/** + \brief Print data from a U_PMF_IE_COLORCURVE object + \return 1 on success, 0 on error + \param contents Record from which to print data + \param blimit one byte past the end of data + EMF+ manual 2.2.3.4, Microsoft name: ColorCurveEffect Object +*/ +int U_PMF_IE_COLORCURVE_print(const char *contents, const char *blimit){ + uint32_t Adjust, Channel; + int32_t Intensity; + int status = U_PMF_IE_COLORCURVE_get(contents, &Adjust, &Channel, &Intensity, blimit); + if(status){ + printf("ColorBalanceEffect Adjust:%u Channel:%u Intensity:%d\n", Adjust, Channel, Intensity); + } + return(status); +} + +/** + \brief Print data from a U_PMF_IE_COLORLOOKUPTABLE object + \return 1 on success, 0 on error + \param contents Record from which to print data + \param blimit one byte past the end of data + EMF+ manual 2.2.3.5, Microsoft name: ColorLookupTableEffect Object +*/ +int U_PMF_IE_COLORLOOKUPTABLE_print(const char *contents, const char *blimit){ + const uint8_t *BLUT, *GLUT, *RLUT, *ALUT; + int status = U_PMF_IE_COLORLOOKUPTABLE_get(contents, &BLUT, &GLUT, &RLUT, &ALUT, blimit); + if(status){ + printf("ColorLookupTableEffect \n"); + U_PMF_UINT8_ARRAY_print(" BLUT:", BLUT, 256, "\n"); + U_PMF_UINT8_ARRAY_print(" GLUT:", GLUT, 256, "\n"); + U_PMF_UINT8_ARRAY_print(" RLUT:", RLUT, 256, "\n"); + U_PMF_UINT8_ARRAY_print(" ALUT:", ALUT, 256, "\n"); + } + return(status); +} + +/** + \brief Print data from a U_PMF_IE_COLORMATRIX object + \return 1 on success, 0 on error + \param contents Record from which to print data + \param blimit one byte past the end of data + EMF+ manual 2.2.3.6, Microsoft name: ColorMatrixEffect Object +*/ +int U_PMF_IE_COLORMATRIX_print(const char *contents, const char *blimit){ + U_PMF_IE_COLORMATRIX Matrix; + int i,j; + int status = U_PMF_IE_COLORMATRIX_get(contents, &Matrix, blimit); + if(status){ + printf("ColorMatrixEffect\n"); + for(i=0;i<5;i++){ + printf(" {"); + for(j=0;j<4;i++){ printf("%f,",Matrix.M[i][j]); } + printf("%f}",Matrix.M[i][j]); + } + printf("\n"); + } + return(status); +} + +/** + \brief Print data from a U_PMF_IE_HUESATURATIONLIGHTNESS object + \return 1 on success, 0 on error + \param contents Record from which to print data + \param blimit one byte past the end of data + EMF+ manual 2.2.3.7, Microsoft name: HueSaturationLightnessEffect Object +*/ +int U_PMF_IE_HUESATURATIONLIGHTNESS_print(const char *contents, const char *blimit){ + int32_t Hue, Saturation, Lightness; + int status = U_PMF_IE_HUESATURATIONLIGHTNESS_get(contents, &Hue, &Saturation, &Lightness, blimit); + if(status){ + printf("HueSaturationLightnessEffect Hue:%d Saturation:%d Lightness:%d\n", Hue, Saturation, Lightness); + } + return(status); +} + +/** + \brief Print data from a U_PMF_IE_LEVELS object + \return 1 on success, 0 on error + \param contents Record from which to print data + \param blimit one byte past the end of data + EMF+ manual 2.2.3.8, Microsoft name: LevelsEffect Object +*/ +int U_PMF_IE_LEVELS_print(const char *contents, const char *blimit){ + int32_t Highlight, Midtone, Shadow; + int status = U_PMF_IE_LEVELS_get(contents, &Highlight, &Midtone, &Shadow, blimit); + if(status){ + printf("LevelEffect Highlight:%d Midtone:%d Shadow:%d\n", Highlight, Midtone, Shadow); + } + return(status); +} + +/** + \brief Print data from a U_PMF_IE_REDEYECORRECTION object + \return 1 on success, 0 on error + \param contents Record from which to print data + \param blimit one byte past the end of data + EMF+ manual 2.2.3.9, Microsoft name: RedEyeCorrectionEffect Object +*/ +int U_PMF_IE_REDEYECORRECTION_print(const char *contents, const char *blimit){ + int32_t Elements; + U_RECTL *Rects; + int status = U_PMF_IE_REDEYECORRECTION_get(contents, &Elements, &Rects, blimit); + if(status){ + printf("RedEyeCorrectionEffect Elements:%u", Elements); + for(; Elements; Elements--, Rects++){ + printf(" "); + rectl_print(*Rects); + } + printf("\n"); + } + return(status); +} + +/** + \brief Print data from a U_PMF_IE_SHARPEN object + \return 1 on success, 0 on error + \param blimit one byte past the end of data + \param contents Record from which to print data + EMF+ manual 2.2.3.10, Microsoft name: SharpenEffect Object +*/ +int U_PMF_IE_SHARPEN_print(const char *contents, const char *blimit){ + U_FLOAT Radius; + int32_t Sharpen; + int status = U_PMF_IE_SHARPEN_get(contents, &Radius, &Sharpen, blimit); + if(status){ + printf("SharpenEffect Radius:%f Sharpen:%u\n", Radius, Sharpen); + } + return(status); +} + +/** + \brief Print data from a U_PMF_IE_TINT object + \return 1 on success, 0 on error + \param contents Record from which to print data + \param blimit one byte past the end of data + EMF+ manual 2.2.3.11, Microsoft name: TintEffect Object +*/ +int U_PMF_IE_TINT_print(const char *contents, const char *blimit){ + int32_t Hue, Amount; + int status = U_PMF_IE_TINT_get(contents, &Hue, &Amount, blimit); + if(status){ + printf("TintEffect Hue:%d Amount:%d\n", Hue, Amount); + } + return(status); +} + +/* ***************************************************************************************** */ +/* EMF+ records, the EMF+ record header is printed separately, these print the contents only */ +/* ***************************************************************************************** */ + + +/** + \brief Print data from a U_PMR_OFFSETCLIP record + \return size of record in bytes on success, 0 on error + \param contents Record from which to print data + EMF+ manual 2.3.1.1, Microsoft name: EmfPlusOffsetClip Record, Index 0x35 +*/ +int U_PMR_OFFSETCLIP_print(const char *contents){ + U_PMF_CMN_HDR Header; + U_FLOAT dX,dY; + int status = U_PMR_OFFSETCLIP_get(contents, &Header, &dX, &dY); + if(status){ + printf(" + dx:%f dy:%f\n",dX,dY); + } + else { + printf(" corrupt record\n"); + } + return(status); +} + +/** + \brief Print data from a U_PMR_OFFSETCLIP record + \return size of record in bytes on success, 0 on error + \param contents Record from which to print data + EMF+ manual 2.3.1.2, Microsoft name: EmfPlusResetClip Record, Index 0x31 +*/ +int U_PMR_RESETCLIP_print(const char *contents){ + return(U_PMR_NODATAREC_print(contents)); +} + +/** + \brief Print data from a U_PMR_SETCLIPPATH record + \return size of record in bytes on success, 0 on error + \param contents Record from which to print data + EMF+ manual 2.3.1.3, Microsoft name: EmfPlusSetClipPath Record, Index 0x33 +*/ +int U_PMR_SETCLIPPATH_print(const char *contents){ + int CMenum; + uint32_t PathID; + int status = U_PMR_SETCLIPPATH_get(contents, NULL, &PathID, &CMenum); + if(status){ + printf(" + PathID:%u CMenum:%d\n",PathID,CMenum); + } + else { + printf(" corrupt record\n"); + } + return(status); +} + +/** + \brief Print data from a U_PMR_SETCLIPRECT record + \return size of record in bytes on success, 0 on error + \param contents Record from which to print data + EMF+ manual 2.3.1.4, Microsoft name: EmfPlusSetClipRect Record, Index 0x32 +*/ +int U_PMR_SETCLIPRECT_print(const char *contents){ + int CMenum; + U_PMF_RECTF Rect; + int status = U_PMR_SETCLIPRECT_get(contents, NULL, &CMenum, &Rect); + if(status){ + printf(" + CMenum:%d(", CMenum); + U_PMF_COMBINEMODEENUMERATION_print(CMenum); + printf(") Rect:"); + U_PMF_RECTF_S_print(&Rect); + printf("\n"); + } + else { + printf(" corrupt record\n"); + } + return(status); +} + +/** + \brief Print data from a U_PMR_SETCLIPREGION record + \return size of record in bytes on success, 0 on error + \param contents Record from which to print data + EMF+ manual 2.3.1.5, Microsoft name: EmfPlusSetClipRegion Record, Index 0x34 +*/ +int U_PMR_SETCLIPREGION_print(const char *contents){ + int CMenum; + uint32_t PathID; + int status = U_PMR_SETCLIPREGION_get(contents, NULL, &PathID, &CMenum); + if(status){ + printf(" + PathID:%u CMenum:%d(",PathID, CMenum); + U_PMF_COMBINEMODEENUMERATION_print(CMenum); + printf(")\n"); + } + else { + printf(" corrupt record\n"); + } + return(status); +} + + +/** + \brief Print data from a U_PMR_COMMENT record + \return size of record in bytes on success, 0 on error + \param contents Record from which to print data + EMF+ manual 2.3.2.1, Microsoft name: EmfPlusComment Record, Index 0x03 +*/ +int U_PMR_COMMENT_print(const char *contents){ + U_PMF_CMN_HDR Header; + const char *Data; + unsigned int i=0; + int status = U_PMR_COMMENT_get(contents, &Header, &Data); + if(status){ + const char *blimit = contents + Header.Size; + if(IS_MEM_UNSAFE(Data, Header.DataSize, blimit)){ + printf(" corrupt record\n"); + return(0); + } + /* try to print it, but only ASCII, bail on anything that is not ASCII */ + printf(" + Data:"); + for(i=0; i< Header.DataSize; i++,Data++){ + if(!*Data)break; + if(*(unsigned const char *)Data <128){ printf("%c",*Data); } + else { break; } + } + printf("\n"); + } + else { + printf(" corrupt record\n"); + } + return(status); +} + +/** + \brief Print data from a U_PMR_ENDOFFILE record + \return size of record in bytes on success, 0 on error + \param contents Record from which to print data + EMF+ manual 2.3.3.1, Microsoft name: EmfPlusEndOfFile Record, Index 0x02 +*/ +int U_PMR_ENDOFFILE_print(const char *contents){ + return(U_PMR_NODATAREC_print(contents)); +} + +/** + \brief Print data from a U_PMR_ENDOFFILE record + \return size of record in bytes on success, 0 on error + \param contents Record from which to print data + EMF+ manual 2.3.3.2, Microsoft name: EmfPlusGetDC Record, Index 0x04 +*/ +int U_PMR_GETDC_print(const char *contents){ + return(U_PMR_NODATAREC_print(contents)); +} + +/** + \brief Print data from a U_PMR_HEADER record + \return size of record in bytes on success, 0 on error + \param contents Record from which to print data + EMF+ manual 2.3.3.3, Microsoft name: EmfPlusHeader Record, Index 0x01 +*/ +int U_PMR_HEADER_print(const char *contents){ + U_PMF_GRAPHICSVERSION Version; + int IsDual, IsVideo; + uint32_t LogicalDpiX, LogicalDpiY; + int status = U_PMR_HEADER_get(contents, NULL, &Version, &IsDual, &IsVideo, &LogicalDpiX, &LogicalDpiY); + if(status){ + /* try to print it, but only ASCII, bail on anything that is not ASCII */ + printf(" + "); + (void) U_PMF_GRAPHICSVERSION_memsafe_print((char *)&Version);; + printf(" IsDual:%c IsVideo:%d LogicalDpiX,y:{%u,%u}\n",(IsDual ? 'Y' : 'N'),IsVideo,LogicalDpiX, LogicalDpiY); + } + else { + printf(" corrupt record\n"); + } + return(status); +} + +/** + \brief Print data from a U_PMR_CLEAR record + \return size of record in bytes on success, 0 on error + \param contents Record from which to print data + EMF+ manual 2.3.4.1, Microsoft name: EmfPlusClear Record, Index 0x09 +*/ +int U_PMR_CLEAR_print(const char *contents){ + U_PMF_ARGB Color; + int status = U_PMR_CLEAR_get(contents, NULL, &Color); + if(status){ + /* try to print it, but only ASCII, bail on anything that is not ASCII */ + printf(" + Color:"); + (void) U_PMF_ARGB_print((char *) &Color); + } + else { + printf(" corrupt record\n"); + } + return(status); +} + +/** + \brief Print data from a U_PMR_DRAWARC record + \return size of record in bytes on success, 0 on error + \param contents Record from which to print data + EMF+ manual 2.3.4.2, Microsoft name: EmfPlusDrawArc Record, Index 0x12 +*/ +int U_PMR_DRAWARC_print(const char *contents){ + uint32_t PenID; + int ctype; + U_FLOAT Start, Sweep; + U_PMF_RECTF Rect; + int status = U_PMR_DRAWARC_get(contents, NULL, &PenID, &ctype, &Start, &Sweep, &Rect); + if(status){ + printf(" + PenID:%u ctype:%d Start:%f Sweep:%f Rect:", PenID,ctype,Start,Sweep); + (void) U_PMF_VARRECTF_S_print(&Rect, 1); + printf("\n"); + } + else { + printf(" corrupt record\n"); + } + return(status); +} + +/** + \brief Print data from a U_PMR_DRAWBEZIERS record + \return size of record in bytes on success, 0 on error + \param contents Record from which to print data + EMF+ manual 2.3.4.3, Microsoft name: EmfPlusDrawBeziers Record, Index 0x19 +*/ +int U_PMR_DRAWBEZIERS_print(const char *contents){ + uint32_t PenID; + int ctype, RelAbs; + uint32_t Elements; + U_PMF_POINTF *Points; + int status = U_PMR_DRAWBEZIERS_get(contents, NULL, &PenID, &ctype, &RelAbs, &Elements, &Points); + if(status){ + printf(" + PenIdx:%u ctype:%d RelAbs:%d Elements:%u\n", PenID, ctype, RelAbs, Elements); + U_PMF_VARPOINTF_S_print(Points, Elements); + free(Points); + } + else { + printf(" corrupt record\n"); + } + return(status); +} + +/** + \brief Print data from a U_PMR_DRAWCLOSEDCURVE record + \return size of record in bytes on success, 0 on error + \param contents Record from which to print data + + Curve is a cardinal spline. + References sent by MS support: + http://alvyray.com/Memos/CG/Pixar/spline77.pdf + http://msdn.microsoft.com/en-us/library/4cf6we5y(v=vs.110).aspx + + EMF+ manual 2.3.4.4, Microsoft name: EmfPlusDrawClosedCurve Record, Index 0x17 +*/ +int U_PMR_DRAWCLOSEDCURVE_print(const char *contents){ + uint32_t PenID; + int ctype, RelAbs; + U_FLOAT Tension; + uint32_t Elements; + U_PMF_POINTF *Points; + int status = U_PMR_DRAWCLOSEDCURVE_get(contents, NULL, &PenID, &ctype, &RelAbs, &Tension, &Elements, &Points); + if(status){ + printf(" + PenID:%u ctype:%d RelAbs:%d Tension:%f\n", PenID, ctype, RelAbs, Tension); + U_PMF_VARPOINTF_S_print(Points, Elements); + free(Points); + } + else { + printf(" corrupt record\n"); + } + return(status); +} + +/** + \brief Print data from a U_PMR_DRAWCURVE record + \return size of record in bytes on success, 0 on error + \param contents Record from which to print data + + Curve is a cardinal spline, using doubled terminator points to generate curves for the terminal segments. + References sent by MS support: + http://alvyray.com/Memos/CG/Pixar/spline77.pdf + http://msdn.microsoft.com/en-us/library/4cf6we5y(v=vs.110).aspx + + EMF+ manual 2.3.4.5, Microsoft name: EmfPlusDrawCurve Record, Index 0x18 +*/ +int U_PMR_DRAWCURVE_print(const char *contents){ + uint32_t PenID; + int ctype; + U_FLOAT Tension; + uint32_t Offset, NSegs, Elements; + U_PMF_POINTF *Points; + int status = U_PMR_DRAWCURVE_get(contents, NULL, &PenID, &ctype, &Tension, &Offset, &NSegs, &Elements, &Points); + if(status){ + printf(" + PenID:%u ctype:%d Tension:%f Offset:%u NSegs:%u Elements:%u\n", PenID, ctype, Tension, Offset, NSegs, Elements); + U_PMF_VARPOINTF_S_print(Points, Elements); + free(Points); + } + else { + printf(" corrupt record\n"); + } + return(status); +} + +/** + \brief Print data from a U_PMR_DRAWDRIVERSTRING record + \return size of record in bytes on success, 0 on error + \param contents Record from which to print data + EMF+ manual 2.3.4.6, Microsoft name: EmfPlusDrawDriverString Record, Index 0x36 +*/ +int U_PMR_DRAWDRIVERSTRING_print(const char *contents){ + unsigned int i; + uint32_t FontID; + int btype; + uint32_t BrushID, DSOFlags, HasMatrix, Elements; + uint16_t *Glyphs; + uint16_t *GlyphsIter; + U_PMF_POINTF *Points; + U_PMF_TRANSFORMMATRIX *Matrix; + int status = U_PMR_DRAWDRIVERSTRING_get(contents, NULL, &FontID, &btype, + &BrushID, &DSOFlags, &HasMatrix, &Elements,&Glyphs, &Points, &Matrix); + if(status){ + printf(" + FontID:%u btype:%d BrushID:%u DSOFlags:%X Elements:%u\n", FontID,btype, BrushID, DSOFlags, Elements); + + printf(" + Glyphs:"); + if(*Glyphs){ + for(GlyphsIter=Glyphs, i=0; i<Elements;i++, GlyphsIter++){ printf(" %u",*GlyphsIter); } + free(Glyphs); + } + else { + printf("(none)"); + } + printf("\n"); + + printf(" + Positions:\n"); + if(Points){ + U_PMF_VARPOINTF_S_print(Points, Elements); + free(Points); + } + else { + printf("(none)\n"); + } + + if(Matrix){ + printf(" + "); + U_PMF_TRANSFORMMATRIX2_print(Matrix); + free(Matrix); + printf("\n"); + } + } + else { + printf(" corrupt record\n"); + } + return(status); +} + +/** + \brief Print data from a U_PMR_DRAWELLIPSE record + \return size of record in bytes on success, 0 on error + \param contents Record from which to print data + EMF+ manual 2.3.4.7, Microsoft name: EmfPlusDrawEllipse Record, Index 0x0F +*/ +int U_PMR_DRAWELLIPSE_print(const char *contents){ + uint32_t PenID; + int ctype; + U_PMF_RECTF Rect; + int status = U_PMR_DRAWELLIPSE_get(contents, NULL, &PenID, &ctype, &Rect); + if(status){ + printf(" + PenID:%u ctype:%d", PenID,ctype); + (void) U_PMF_VARRECTF_S_print(&Rect, 1); + printf("\n"); + } + else { + printf(" corrupt record\n"); + } + return(status); +} + +/** + \brief Print data from a U_PMR_DRAWIMAGE record + \return size of record in bytes on success, 0 on error + \param contents Record from which to print data + EMF+ manual 2.3.4.8, Microsoft name: EmfPlusDrawImage Record, Index 0x1A +*/ +int U_PMR_DRAWIMAGE_print(const char *contents){ + uint32_t ImgID, ImgAttrID; + int ctype; + int32_t SrcUnit; + U_PMF_RECTF SrcRect; + U_PMF_RECTF DstRect; + int status = U_PMR_DRAWIMAGE_get(contents, NULL, &ImgID, &ctype, &ImgAttrID, &SrcUnit, &SrcRect, &DstRect); + if(status){ + printf(" + ImgID:%u ctype:%d ImgAttrID:%u SrcUnit:%d SrcRect:", ImgID, ctype, ImgAttrID, SrcUnit); + (void) U_PMF_RECTF_S_print(&SrcRect); + printf(" DstRect:"); + (void) U_PMF_RECTF_S_print(&DstRect); + printf("\n"); + } + else { + printf(" corrupt record\n"); + } + return(status); +} + +/** + \brief Print data from a U_PMR_DRAWIMAGEPOINTS record + \return size of record in bytes on success, 0 on error + \param contents Record from which to print data + EMF+ manual 2.3.4.9, Microsoft name: EmfPlusDrawImagePoints Record, Index 0x1B +*/ +int U_PMR_DRAWIMAGEPOINTS_print(const char *contents){ + uint32_t ImgID, ImgAttrID; + int ctype, etype, RelAbs; + int32_t SrcUnit; + U_PMF_RECTF SrcRect; + uint32_t Elements; + U_PMF_POINTF *Points; + int status = U_PMR_DRAWIMAGEPOINTS_get(contents, NULL, &ImgID, &ctype, &etype, &RelAbs, + &ImgAttrID, &SrcUnit, &SrcRect, &Elements, &Points); + if(status){ + printf(" + ImgID:%u ctype:%d etype:%d ImgAttrID:%u SrcUnit:%d Elements:%u SrcRect:", + ImgID, ctype, etype, ImgAttrID, SrcUnit, Elements); + (void) U_PMF_RECTF_S_print(&SrcRect); + printf("\n"); + U_PMF_VARPOINTF_S_print(Points, Elements); + free(Points); + } + else { + printf(" corrupt record\n"); + } + return(status); +} + + +/** + \brief Print data from a U_PMR_DRAWLINES record + \return size of record in bytes on success, 0 on error + \param contents Record from which to print data + EMF+ manual 2.3.4.10, Microsoft name: EmfPlusDrawLines Record, Index 0x0D +*/ +int U_PMR_DRAWLINES_print(const char *contents){ + uint32_t PenIdx; + int ctype, dtype, RelAbs; + uint32_t Elements; + U_PMF_POINTF *Points; + int status = U_PMR_DRAWLINES_get(contents, NULL, &PenIdx, &ctype, &dtype, &RelAbs, &Elements, &Points); + if(status){ + printf(" + PenIdx:%d ctype:%d dtype:%d RelAbs:%d\n", PenIdx,ctype,dtype,RelAbs); + U_PMF_VARPOINTF_S_print(Points, Elements); + free(Points); + } + else { + printf(" corrupt record\n"); + } + return(status); +} + +/** + \brief Print data from a U_PMR_DRAWPATH record + \return size of record in bytes on success, 0 on error + \param contents Record from which to print data + EMF+ manual 2.3.4.11, Microsoft name: EmfPlusDrawPath Record, Index 0x15 +*/ +int U_PMR_DRAWPATH_print(const char *contents){ + uint32_t PathIdx, PenIdx; + int status = U_PMR_DRAWPATH_get(contents, NULL, &PathIdx, &PenIdx); + if(status){ + printf(" + PathIdx:%d PenIdx:%d\n", PathIdx, PenIdx); + } + else { + printf(" corrupt record\n"); + } + return(status); +} + +/** + \brief Print data from a U_PMR_DRAWPIE record + \return size of record in bytes on success, 0 on error + \param contents Record from which to print data + EMF+ manual 2.3.4.12, Microsoft name: EmfPlusDrawPie Record, Index 0x0D +*/ +int U_PMR_DRAWPIE_print(const char *contents){ + uint32_t PenID; + int ctype; + U_FLOAT Start, Sweep; + U_PMF_RECTF Rect; + int status = U_PMR_DRAWPIE_get(contents, NULL, &PenID, &ctype, &Start, &Sweep, &Rect); + if(status){ + printf(" + PenID:%u ctype:%d Start:%f Sweep:%f Rect:", PenID,ctype,Start,Sweep); + (void) U_PMF_VARRECTF_S_print(&Rect, 1); + printf("\n"); + } + else { + printf(" corrupt record\n"); + } + return(status); +} + +/** + \brief Print data from a U_PMR_DRAWRECTS record + \return size of record in bytes on success, 0 on error + \param contents Record from which to print data + EMF+ manual 2.3.4.13, Microsoft name: EmfPlusDrawRects Record, Index 0x0B +*/ +int U_PMR_DRAWRECTS_print(const char *contents){ + uint32_t PenID; + int ctype; + uint32_t Elements; + U_PMF_RECTF *Rects=NULL; + U_PMF_CMN_HDR hdr; + int status = U_PMR_DRAWRECTS_get(contents, &hdr, &PenID, &ctype, &Elements, &Rects); + if(status){ + printf(" + PenID:%u ctype:%d Elements:%u Rect:", PenID,ctype,Elements); + (void) U_PMF_VARRECTF_S_print(Rects, Elements); + printf("\n"); + } + else { + printf(" corrupt record\n"); + } + if(Rects)free(Rects); + return(status); +} + +/** + \brief Print data from a U_PMR_DRAWSTRING record + \return size of record in bytes on success, 0 on error + \param contents Record from which to print data + EMF+ manual 2.3.4.14, Microsoft name: EmfPlusDrawString Record, Index 0x1C +*/ +int U_PMR_DRAWSTRING_print(const char *contents){ + char *String8=NULL; + uint32_t FontID, BrushID, FormatID, Length; + int btype; + U_PMF_RECTF Rect; + uint16_t *String16; + int status = U_PMR_DRAWSTRING_get(contents, NULL, &FontID, &btype, + &BrushID, &FormatID, &Length, &Rect, &String16); + if(status){ + printf(" + FontID:%u StringFormatID:%u btype:%d Length:%u Rect:", FontID, FormatID, btype, Length); + (void) U_PMF_RECTF_S_print(&Rect); + (void) U_PMF_VARBRUSHID_print(btype, BrushID); + if(String16){ + String8 = U_Utf16leToUtf8(String16, Length, NULL); + free(String16); + if(String8){ + printf(" String(as_UTF8):<%s>\n",String8); + free(String8); + } + } + else { + printf(" String(as_UTF8):(none)\n"); + } + } + else { + printf(" corrupt record\n"); + } + return(status); +} + +/** + \brief Print data from a U_PMR_FILLCLOSEDCURVE record + \return size of record in bytes on success, 0 on error + \param contents Record from which to print data + EMF+ manual 2.3.4.15, Microsoft name: EmfPlusFillClosedCurve Record, Index 0x16 +*/ +int U_PMR_FILLCLOSEDCURVE_print(const char *contents){ + uint32_t BrushID; + int btype, ctype, ftype, RelAbs; + U_FLOAT Tension; + uint32_t Elements; + U_PMF_POINTF *Points; + int status = U_PMR_FILLCLOSEDCURVE_get(contents, NULL, &btype, &ctype, &ftype, &RelAbs, + &BrushID, &Tension, &Elements, &Points); + if(status){ + printf(" + btype:%d ctype:%d ftype:%d RelAbs:%d Elements:%u", + btype, ctype, ftype, RelAbs, Elements); + (void) U_PMF_VARBRUSHID_print(btype, BrushID); + printf("\n"); + U_PMF_VARPOINTF_S_print(Points, Elements); + free(Points); + } + else { + printf(" corrupt record\n"); + } + return(status); +} + + +/** + \brief Print data from a U_PMR_FILLELLIPSE record + \return size of record in bytes on success, 0 on error + \param contents Record from which to print data + EMF+ manual 2.3.4.16, Microsoft name: EmfPlusFillEllipse Record, Index 0x0E +*/ +int U_PMR_FILLELLIPSE_print(const char *contents){ + int btype, ctype; + uint32_t BrushID; + U_PMF_RECTF Rect; + int status = U_PMR_FILLELLIPSE_get(contents, NULL, &btype, &ctype, &BrushID, &Rect); + if(status){ + printf(" + btype:%d ctype:%d",btype,ctype); + (void) U_PMF_VARBRUSHID_print(btype, BrushID); + (void) U_PMF_VARRECTF_S_print(&Rect, 1); + printf("\n"); + } + else { + printf(" corrupt record\n"); + } + return(status); +} + +/** + \brief Print data from a U_PMR_FILLPATH record + \return size of record in bytes on success, 0 on error + \param contents Record from which to print data + EMF+ manual 2.3.4.17, Microsoft name: EmfPlusFillPath Record, Index 0x14 +*/ +int U_PMR_FILLPATH_print(const char *contents){ + int btype; + uint32_t PathID, BrushID; + int status = U_PMR_FILLPATH_get(contents, NULL, &PathID, &btype, &BrushID); + if(status){ + printf(" + PathID:%u btype:%d",PathID, btype); + (void) U_PMF_VARBRUSHID_print(btype, BrushID); + printf("\n"); + } + else { + printf(" corrupt record\n"); + } + return(status); +} + +/** + \brief Print data from a U_PMR_FILLPIE record + \return size of record in bytes on success, 0 on error + \param contents Record from which to print data + EMF+ manual 2.3.4.18, Microsoft name: EmfPlusFillPie Record, Index 0x10 +*/ +int U_PMR_FILLPIE_print(const char *contents){ + int btype, ctype; + U_FLOAT Start, Sweep; + uint32_t BrushID; + U_PMF_RECTF Rect; + int status = U_PMR_FILLPIE_get(contents, NULL, &btype, &ctype, &BrushID, &Start, &Sweep, &Rect); + if(status){ + printf(" + btype:%d ctype:%d",btype,ctype); + (void) U_PMF_VARBRUSHID_print(btype, BrushID); + (void) U_PMF_VARRECTF_S_print(&Rect, 1); + printf("\n"); + } + else { + printf(" corrupt record\n"); + } + return(status); +} + +/** + \brief Print data from a U_PMR_FILLPOLYGON record + \return size of record in bytes on success, 0 on error + \param contents Record from which to print data + EMF+ manual 2.3.4.19, Microsoft name: EmfPlusFillPolygon Record, Index 0x0C +*/ +int U_PMR_FILLPOLYGON_print(const char *contents){ + int btype, ctype, RelAbs; + uint32_t BrushID, Elements; + U_PMF_POINTF *Points; + int status = U_PMR_FILLPOLYGON_get(contents, NULL, &btype, &ctype, &RelAbs, &BrushID, &Elements, &Points); + if(status){ + printf(" + btype:%d ctype:%d RelAbs:%d Elements:%u",btype,ctype,RelAbs,Elements); + (void) U_PMF_VARBRUSHID_print(btype, BrushID); + printf("\n"); + U_PMF_VARPOINTF_S_print(Points, Elements); + free(Points); + } + else { + printf(" corrupt record\n"); + } + return(status); +} + +/** + \brief Print data from a U_PMR_FILLRECTS record + \return size of record in bytes on success, 0 on error + \param contents Record from which to print data + EMF+ manual 2.3.4.20, Microsoft name: EmfPlusFillRects Record, Index 0x0A +*/ +int U_PMR_FILLRECTS_print(const char *contents){ + int btype, ctype; + uint32_t BrushID, Elements; + U_PMF_RECTF *Rects; + U_PMF_CMN_HDR hdr; + int status = U_PMR_FILLRECTS_get(contents, &hdr, &btype,&ctype, &BrushID, &Elements, &Rects); + if(status){ + printf(" + btype:%d ctype:%d Elements:%u",btype,ctype,Elements); + (void) U_PMF_VARBRUSHID_print(btype, BrushID); + (void) U_PMF_VARRECTF_S_print(Rects, Elements); + free(Rects); + printf("\n"); + } + else { + printf(" corrupt record\n"); + } + return(status); +} + +/** + \brief Print data from a U_PMR_FILLREGION record + \return size of record in bytes on success, 0 on error + \param contents Record from which to print data + EMF+ manual 2.3.4.21, Microsoft name: EmfPlusFillRegion Record, Index 0x13 +*/ +int U_PMR_FILLREGION_print(const char *contents){ + uint32_t RgnID, BrushID; + int btype, ctype; + int status = U_PMR_FILLREGION_get(contents, NULL, &RgnID, &btype, &ctype, &BrushID); + if(status){ + printf(" + RgnID:%u btype:%d ctype:%d", RgnID, btype, ctype); + (void) U_PMF_VARBRUSHID_print(btype, BrushID); + printf("\n"); + } + else { + printf(" corrupt record\n"); + } + return(status); +} + +/** + \brief Print data from a U_PMR_OBJECT record + \return size of record in bytes on success, 0 on error + \param contents Record from which to print data + \param blimit One byte past the last record in memory. + \param ObjCont Structure that holds accumulated object. + \param term Flag used when an abnormal termination of a series of continuation records is encountered. + EMF+ manual 2.3.5.1, Microsoft name: EmfPlusObject Record, Index 0x13 + + This is the ONLY EMF+ record type which needs an explicit blimit passed in. Since it glues + together multiple records, and calls itself recursively, the initial caller cannot determine + that all of the sizes will be OK from the first record's header. +*/ +int U_PMR_OBJECT_print(const char *contents, const char *blimit, U_OBJ_ACCUM *ObjCont, int term){ + U_PMF_CMN_HDR Header; + uint32_t ObjID; + int otype, ntype; + uint32_t TSize; + const char *Data; + int ttype,status; + +//int k; const char *cptr; for(cptr=contents, k=0; k<608;k++,cptr++){ printf("%3.3d %2.2X\n",k,*(uint8_t*)cptr); }; fflush(stdout); + + /* Continued records are a pain. Each contains the total size of the continued object in the first 4 bytes + of data. When the total hits that then then the record is complete, even though the continuation bit will + still be set on that last record. Check for this and then print the terminated continued series. + */ + + if(term){ /* mode for handling unexpected end of accumulated object */ + if(ObjCont->used == 0)return(0); /* no continued object pending */ + printf(" + START Forced Termination of Accumulating object Bytes:%u ObjID:%u DeclaredType:%d(", + ObjCont->used, ObjCont->Id, ObjCont->Type); + U_PMF_OBJECTTYPEENUMERATION_print(ObjCont->Type); + ttype = ObjCont->Type & 0x3F; + printf(")\n"); + status = 1; + } + else { + status = U_PMR_OBJECT_get(contents, &Header, &ObjID, &otype, &ntype, &TSize, &Data); + /* In a corrupt EMF+ file we might hit a new type of record before all the continuation records + expected have been found. If that happens terminate whatever we have accumulated so far, and then go on + to emit the new (unexpected) record. */ + if(IS_MEM_UNSAFE(contents, Header.Size, blimit))return(0); + if(!status){ + printf(" corrupt record\n"); + return(status); + } + if((ObjCont->used > 0) && (U_OA_append(ObjCont, NULL, 0, otype, ObjID) < 0)){ + U_PMR_OBJECT_print(contents, blimit, ObjCont, 1); + } + printf(" + ObjID:%u ObjType:%d(", ObjID, otype); + U_PMF_OBJECTTYPEENUMERATION_print(otype); + printf(") ntype:%d", ntype); + printf(" ContinueD:%c",( ObjCont->used ? 'Y' : 'N')); + printf(" ContinueB:%c",( ntype ? 'Y' : 'N')); + if(ntype){ + U_OA_append(ObjCont, Data, Header.DataSize - 4, otype, ObjID); // The total byte count is not added to the object + printf(" TotalSize:%u",TSize); + printf(" Accumulated:%u",ObjCont->used); + } + else { + U_OA_append(ObjCont, Data, Header.DataSize, otype, ObjID); // The total byte count is not added to the object + } + printf("\n"); + if(ntype && ObjCont->used < TSize)return(status); + /* preceding terminates any continued series for >= accumulated bytes */ + ttype = otype; + } + if(status){ + blimit = ObjCont->accum + ObjCont->used; /* more restrictive blimit, just to end of object */ + switch(ttype){ + case U_OT_Brush: (void) U_PMF_BRUSH_print(ObjCont->accum, blimit); break; + case U_OT_Pen: (void) U_PMF_PEN_print(ObjCont->accum, blimit); break; + case U_OT_Path: (void) U_PMF_PATH_print(ObjCont->accum, blimit); break; + case U_OT_Region: (void) U_PMF_REGION_print(ObjCont->accum, blimit); break; + case U_OT_Image: (void) U_PMF_IMAGE_print(ObjCont->accum, blimit); break; + case U_OT_Font: (void) U_PMF_FONT_print(ObjCont->accum, blimit); break; + case U_OT_StringFormat: (void) U_PMF_STRINGFORMAT_print(ObjCont->accum, blimit); break; + case U_OT_ImageAttributes: (void) U_PMF_IMAGEATTRIBUTES_print(ObjCont->accum, blimit); break; + case U_OT_CustomLineCap: (void) U_PMF_CUSTOMLINECAP_print(ObjCont->accum,"", blimit); break; + case U_OT_Invalid: + default: + printf("INVALID OBJECT TYPE!!!!\n"); + break; + } + U_OA_clear(ObjCont); + } + if(term)printf(" + END Forced Termination of Accumulating object\n"); + return(status); +} + +/** + \brief Print data from a U_PMR_SERIALIZABLEOBJECT record + \return size of record in bytes on success, 0 on error + \param contents Record from which to print data + EMF+ manual 2.3.5.2, Microsoft name: EmfPlusSerializableObject Record, Index 0x38 +*/ +int U_PMR_SERIALIZABLEOBJECT_print(const char *contents){ + uint8_t GUID[16]; + uint32_t Size; + const char *Data; + char *string=NULL; + int iee; + int status = U_PMR_SERIALIZABLEOBJECT_get(contents, NULL, &GUID[0], &Size, &Data); + if(status){ + string = U_PMF_CURLYGUID_set(&GUID[0]); + if(string){ + printf(" + GUID:%s Size:%u",string,Size); + iee = U_PMF_KNOWNCURLYGUID_set(string); /* overwrites string with short text form */ + printf("\n + Effect:"); + free(string); + switch(iee){ + case U_IEE_Unknown: printf("(undefined)\n"); break; + case U_IEE_BlurEffectGuid: U_PMF_IE_BLUR_print(Data, Data + sizeof(U_PMF_IE_BLUR)); break; + case U_IEE_BrightnessContrastEffectGuid: U_PMF_IE_BRIGHTNESSCONTRAST_print(Data, Data + sizeof(U_PMF_IE_BRIGHTNESSCONTRAST)); break; + case U_IEE_ColorBalanceEffectGuid: U_PMF_IE_COLORBALANCE_print(Data, Data + sizeof(U_PMF_IE_COLORBALANCE)); break; + case U_IEE_ColorCurveEffectGuid: U_PMF_IE_COLORCURVE_print(Data, Data + sizeof(U_PMF_IE_COLORCURVE)); break; + case U_IEE_ColorLookupTableEffectGuid: U_PMF_IE_COLORLOOKUPTABLE_print(Data, Data + sizeof(U_PMF_IE_COLORLOOKUPTABLE)); break; + case U_IEE_ColorMatrixEffectGuid: U_PMF_IE_COLORMATRIX_print(Data, Data + sizeof(U_PMF_IE_COLORMATRIX)); break; + case U_IEE_HueSaturationLightnessEffectGuid: U_PMF_IE_HUESATURATIONLIGHTNESS_print(Data, Data + sizeof(U_PMF_IE_HUESATURATIONLIGHTNESS)); break; + case U_IEE_LevelsEffectGuid: U_PMF_IE_LEVELS_print(Data, Data + sizeof(U_PMF_IE_LEVELS)); break; + case U_IEE_RedEyeCorrectionEffectGuid: U_PMF_IE_REDEYECORRECTION_print(Data, Data + sizeof(U_PMF_IE_REDEYECORRECTION)); break; + case U_IEE_SharpenEffectGuid: U_PMF_IE_SHARPEN_print(Data, Data + sizeof(U_PMF_IE_SHARPEN)); break; + case U_IEE_TintEffectGuid: U_PMF_IE_TINT_print(Data, Data + sizeof(U_PMF_IE_TINT)); break; + } + } + else { + printf(" + GUID:ERROR Size:%u\n",Size); + } + } + else { + printf(" corrupt record\n"); + } + return(status); +} + +/** + \brief Print data from a U_PMR_SETANTIALIASMODE record + \return size of record in bytes on success, 0 on error + \param contents Record from which to print data + EMF+ manual 2.3.6.1, Microsoft name: EmfPlusSetAntiAliasMode Record, Index 0x1E +*/ +int U_PMR_SETANTIALIASMODE_print(const char *contents){ + int SMenum, aatype; + int status = U_PMR_SETANTIALIASMODE_get(contents, NULL, &SMenum, &aatype); + if(status){ + printf(" + SMenum:%d AntiAlias:%c\n",SMenum,(aatype ? 'Y' : 'N')); + } + else { + printf(" corrupt record\n"); + } + return(status); +} + +/** + \brief Print data from a U_PMR_SETCOMPOSITINGMODE record + \return size of record in bytes on success, 0 on error + \param contents Record from which to print data + EMF+ manual 2.3.6.2, Microsoft name: EmfPlusSetCompositingMode Record, Index 0x23 +*/ +int U_PMR_SETCOMPOSITINGMODE_print(const char *contents){ + int CMenum; + int status = U_PMR_SETCOMPOSITINGMODE_get(contents, NULL, &CMenum); + if(status){ + printf(" + CMenum:%d\n",CMenum); + } + else { + printf(" corrupt record\n"); + } + return(status); +} + +/** + \brief Print data from a U_PMR_SETCOMPOSITINGQUALITY record + \return size of record in bytes on success, 0 on error + \param contents Record from which to print data + EMF+ manual 2.3.6.3, Microsoft name: EmfPlusSetCompositingQuality Record, Index 0x24 +*/ +int U_PMR_SETCOMPOSITINGQUALITY_print(const char *contents){ + int CQenum; + int status = U_PMR_SETCOMPOSITINGQUALITY_get(contents, NULL, &CQenum); + if(status){ + printf(" + CQenum:%d\n",CQenum); + } + else { + printf(" corrupt record\n"); + } + return(status); +} + +/** + \brief Print data from a U_PMR_SETINTERPOLATIONMODE record + \return size of record in bytes on success, 0 on error + \param contents Record from which to print data + EMF+ manual 2.3.6.4, Microsoft name: EmfPlusSetInterpolationMode Record, Index 0x21 +*/ +int U_PMR_SETINTERPOLATIONMODE_print(const char *contents){ + int IMenum; + int status = U_PMR_SETINTERPOLATIONMODE_get(contents, NULL, &IMenum); + if(status){ + printf(" + IMenum:%d\n",IMenum); + } + else { + printf(" corrupt record\n"); + } + return(status); +} + +/** + \brief Print data from a U_PMR_SETPIXELOFFSETMODE record + \return size of record in bytes on success, 0 on error + \param contents Record from which to print data + EMF+ manual 2.3.6.5, Microsoft name: EmfPlusSetPixelOffsetMode Record, Index 0x22 +*/ +int U_PMR_SETPIXELOFFSETMODE_print(const char *contents){ + int POMenum; + int status = U_PMR_SETPIXELOFFSETMODE_get(contents, NULL, &POMenum); + if(status){ + printf(" + POMenum:%d\n",POMenum); + } + else { + printf(" corrupt record\n"); + } + return(status); +} + +/** + \brief Print data from a U_PMR_SETRENDERINGORIGIN record + \return size of record in bytes on success, 0 on error + \param contents Record from which to print data + EMF+ manual 2.3.6.6, Microsoft name: EmfPlusSetRenderingOrigin Record, Index 0x1D +*/ +int U_PMR_SETRENDERINGORIGIN_print(const char *contents){ + int32_t X, Y; + int status = U_PMR_SETRENDERINGORIGIN_get(contents, NULL, &X, &Y); + if(status){ + printf(" + X:%d Y:%d\n", X, Y); + } + else { + printf(" corrupt record\n"); + } + return(status); +} + +/** + \brief Print data from a U_PMR_SETTEXTCONTRAST record + \return size of record in bytes on success, 0 on error + \param contents Record from which to print data + EMF+ manual 2.3.6.7, Microsoft name: EmfPlusSetTextContrast Record, Index 0x20 +*/ +int U_PMR_SETTEXTCONTRAST_print(const char *contents){ + int GC; + int status = U_PMR_SETTEXTCONTRAST_get(contents, NULL, &GC); + if(status){ + printf(" + GC:%d\n", GC); + } + else { + printf(" corrupt record\n"); + } + return(status); +} + +/** + \brief Print data from a U_PMR_SETTEXTRENDERINGHINT record + \return size of record in bytes on success, 0 on error + \param contents Record from which to print data + EMF+ manual 2.3.6.8, Microsoft name: EmfPlusSetTextRenderingHint Record, Index 0x1F +*/ +int U_PMR_SETTEXTRENDERINGHINT_print(const char *contents){ + int TRHenum; + int status = U_PMR_SETTEXTRENDERINGHINT_get(contents, NULL, &TRHenum); + if(status){ + printf(" + TRHenum:%d\n",TRHenum); + } + else { + printf(" corrupt record\n"); + } + return(status); +} + +/** + \brief Print data from a U_PMR_BEGINCONTAINER record + \return size of record in bytes on success, 0 on error + \param contents Record from which to print data + EMF+ manual 2.3.7.1, Microsoft name: EmfPlusBeginContainer Record, Index 0x27 +*/ +int U_PMR_BEGINCONTAINER_print(const char *contents){ + int UTenum; + U_PMF_RECTF DstRect, SrcRect; + uint32_t StackID; + int status = U_PMR_BEGINCONTAINER_get(contents, NULL, &UTenum, &DstRect, &SrcRect, &StackID); + if(status){ + printf(" + UTenum:%d",UTenum); + printf(" DstRect:"); (void) U_PMF_RECTF_S_print(&DstRect); + printf(" SrcRect:"); (void) U_PMF_RECTF_S_print(&SrcRect); + printf(" StackID:%u\n", StackID); + } + else { + printf(" corrupt record\n"); + } + return(status); +} + +/** + \brief Print data from a U_PMR_BEGINCONTAINERNOPARAMS record + \return size of record in bytes on success, 0 on error + \param contents Record from which to print data + EMF+ manual 2.3.7.2, Microsoft name: EmfPlusBeginContainerNoParams Record, Index 0x28 +*/ +int U_PMR_BEGINCONTAINERNOPARAMS_print(const char *contents){ + uint32_t StackID; + int status = U_PMR_BEGINCONTAINERNOPARAMS_get(contents, NULL, &StackID); + if(status){ + printf(" + StackID:%u\n", StackID); + } + else { + printf(" corrupt record\n"); + } + return(status); +} + +/** + \brief Print data from a U_PMR_ENDCONTAINER record + \return size of record in bytes on success, 0 on error + \param contents Record from which to print data + EMF+ manual 2.3.7.3, Microsoft name: EmfPlusEndContainer Record, Index 0x29 +*/ +int U_PMR_ENDCONTAINER_print(const char *contents){ + uint32_t StackID; + int status = U_PMR_ENDCONTAINER_get(contents, NULL, &StackID); + if(status){ + printf(" + StackID:%u\n", StackID); + } + else { + printf(" corrupt record\n"); + } + return(status); +} + +/** + \brief Print data from a U_PMR_RESTORE record + \return size of record in bytes on success, 0 on error + \param contents Record from which to print data + EMF+ manual 2.3.7.4, Microsoft name: EmfPlusRestore Record, Index 0x26 +*/ +int U_PMR_RESTORE_print(const char *contents){ + uint32_t StackID; + int status = U_PMR_RESTORE_get(contents, NULL, &StackID); + if(status){ + printf(" + StackID:%u\n", StackID); + } + else { + printf(" corrupt record\n"); + } + return(status); +} + +/** + \brief Print data from a U_PMR_SAVE record + \return size of record in bytes on success, 0 on error + \param contents Record from which to print data + EMF+ manual 2.3.7.5, Microsoft name: EmfPlusSave Record, Index 0x25 +*/ +int U_PMR_SAVE_print(const char *contents){ + uint32_t StackID; + int status = U_PMR_SAVE_get(contents, NULL, &StackID); + if(status){ + printf(" + StackID:%u\n", StackID); + } + else { + printf(" corrupt record\n"); + } + return(status); +} + +/** + \brief Print data from a U_PMR_SETTSCLIP record + \return size of record in bytes on success, 0 on error + \param contents Record from which to print data + EMF+ manual 2.3.8.1, Microsoft name: EmfPlusSetTSClip Record, Index 0x3A +*/ +int U_PMR_SETTSCLIP_print(const char *contents){ + int ctype; + uint32_t Elements; + U_PMF_RECTF *Rects; + int status = U_PMR_SETTSCLIP_get(contents, NULL, &ctype, &Elements, &Rects); + if(status){ + printf(" + ctype:%d Elements:%u",ctype,Elements); + (void) U_PMF_VARRECTF_S_print(Rects, Elements); + free(Rects); + printf("\n"); + } + else { + printf(" corrupt record\n"); + } + return(status); +} + +/** + \brief Print data from a U_PMR_SETTSGRAPHICS record + \return size of record in bytes on success, 0 on error + \param contents Record from which to print data + EMF+ manual 2.3.8.2, Microsoft name: EmfPlusSetTSGraphics Record, Index 0x39 +*/ +int U_PMR_SETTSGRAPHICS_print(const char *contents){ + int vgatype, pptype; + uint8_t AntiAliasMode, TextRenderHint, CompositingMode, CompositingQuality, FilterType, PixelOffset; + int16_t RenderOriginX, RenderOriginY; + uint16_t TextContrast; + U_PMF_TRANSFORMMATRIX WorldToDevice; + const char *Data; + int status = U_PMR_SETTSGRAPHICS_get(contents, NULL, + &vgatype, &pptype, + &AntiAliasMode, &TextRenderHint, &CompositingMode, &CompositingQuality, + &RenderOriginX, &RenderOriginY, &TextContrast, &FilterType, + &PixelOffset, &WorldToDevice, &Data); + if(status){ + const char *blimit = contents + status; + printf(" + vgatype:%d pptype:%u",vgatype,pptype); + printf(" AntiAliasMode:%u TextRenderHint:%u CompositingMode:%u CompositingQuality:%u", + AntiAliasMode, TextRenderHint, CompositingMode, CompositingQuality); + printf(" RenderOriginX:%d RenderOriginY:%d",RenderOriginX, RenderOriginY); + printf(" TextContrast:%u",TextContrast); + printf(" WorldToDevice:"); + U_PMF_TRANSFORMMATRIX2_print(&WorldToDevice); + if(pptype && !U_PMF_PALETTE_print(Data, blimit))return(0); + printf("\n"); + } + else { + printf(" corrupt record\n"); + } + return(status); +} + + +/** + \brief Print data from a U_PMR_MULTIPLYWORLDTRANSFORM record + \return size of record in bytes on success, 0 on error + \param contents Record from which to print data + EMF+ manual 2.3.9.1, Microsoft name: EmfPlusMultiplyWorldTransform Record, Index 0x2C +*/ +int U_PMR_MULTIPLYWORLDTRANSFORM_print(const char *contents){ + int xmtype; + U_PMF_TRANSFORMMATRIX Matrix; + int status = U_PMR_MULTIPLYWORLDTRANSFORM_get(contents, NULL, &xmtype, &Matrix); + if(status){ + printf(" + xmtype:%d Multiply:%s",xmtype,(xmtype ? "Post" : "Pre")); + U_PMF_TRANSFORMMATRIX2_print(&Matrix); + printf("\n"); + } + else { + printf(" corrupt record\n"); + } + return(status); +} + +/** + \brief Print data from a U_PMR_RESETWORLDTRANSFORM record + \return size of record in bytes on success, 0 on error + \param contents Record from which to print data + EMF+ manual 2.3.9.2, Microsoft name: EmfPlusResetWorldTransform Record, Index 0x2B +*/ +int U_PMR_RESETWORLDTRANSFORM_print(const char *contents){ + return(U_PMR_NODATAREC_print(contents)); +} + +/** + \brief Print data from a U_PMR_ROTATEWORLDTRANSFORM record + \return size of record in bytes on success, 0 on error + \param contents Record from which to print data + EMF+ manual 2.3.9.3, Microsoft name: EmfPlusRotateWorldTransform Record, Index 0x2F +*/ +int U_PMR_ROTATEWORLDTRANSFORM_print(const char *contents){ + int xmtype; + U_FLOAT Angle; + int status = U_PMR_ROTATEWORLDTRANSFORM_get(contents, NULL, &xmtype, &Angle); + if(status){ + printf(" + xmtype:%d Multiply:%s Angle:%f\n",xmtype,(xmtype ? "Post" : "Pre"), Angle); + } + else { + printf(" corrupt record\n"); + } + return(status); +} + +/** + \brief Print data from a U_PMR_SCALEWORLDTRANSFORM record + \return size of record in bytes on success, 0 on error + \param contents Record from which to print data + EMF+ manual 2.3.9.4, Microsoft name: EmfPlusScaleWorldTransform Record, Index 0x2E +*/ +int U_PMR_SCALEWORLDTRANSFORM_print(const char *contents){ + int xmtype; + U_FLOAT Sx, Sy; + int status = U_PMR_SCALEWORLDTRANSFORM_get(contents, NULL, &xmtype, &Sx, &Sy); + if(status){ + printf(" + xmtype:%d Multiply:%s ScaleX:%f ScaleY:%f\n",xmtype,(xmtype ? "Post" : "Pre"), Sx, Sy); + } + else { + printf(" corrupt record\n"); + } + return(status); +} + +/** + \brief Print data from a U_PMR_SETPAGETRANSFORM record + \return size of record in bytes on success, 0 on error + \param contents Record from which to print data + EMF+ manual 2.3.9.5, Microsoft name: EmfPlusSetPageTransform Record, Index 0x30 +*/ +int U_PMR_SETPAGETRANSFORM_print(const char *contents){ + int UTenum; + U_FLOAT Scale; + int status = U_PMR_SETPAGETRANSFORM_get(contents, NULL, &UTenum, &Scale); + if(status){ + printf(" + UTenum:%d Scale:%f\n",UTenum, Scale); + } + else { + printf(" corrupt record\n"); + } + return(status); +} + +/** + \brief Print data from a U_PMR_SETWORLDTRANSFORM record + \return size of record in bytes on success, 0 on error + \param contents Record from which to print data + EMF+ manual 2.3.9.6, Microsoft name: EmfPlusSetWorldTransform Record, Index 0x2A +*/ +int U_PMR_SETWORLDTRANSFORM_print(const char *contents){ + U_PMF_TRANSFORMMATRIX Matrix; + int status = U_PMR_SETWORLDTRANSFORM_get(contents, NULL, &Matrix); + if(status){ + printf(" + "); + U_PMF_TRANSFORMMATRIX2_print(&Matrix); + printf("\n"); + } + else { + printf(" corrupt record\n"); + } + return(status); +} + +/** + \brief Print data from a U_PMR_TRANSLATEWORLDTRANSFORM record + \return size of record in bytes on success, 0 on error + \param contents Record from which to print data + EMF+ manual 2.3.9.7, Microsoft name: EmfPlusTranslateWorldTransform Record, Index 0x2D +*/ +int U_PMR_TRANSLATEWORLDTRANSFORM_print(const char *contents){ + int xmtype; + U_FLOAT Dx, Dy; + int status = U_PMR_TRANSLATEWORLDTRANSFORM_get(contents, NULL, &xmtype, &Dx, &Dy); + if(status){ + printf(" + xmtype:%d Multiply:%s TranslateX:%f TranlateY:%f\n",xmtype,(xmtype ? "Post" : "Pre"), Dx, Dy); + } + else { + printf(" corrupt record\n"); + } + return(status); +} + + +/** + \brief Print data from a U_PMR_STROKEFILLPATH record + \return 1 on success, 0 on error + \param contents Record from which to print data +*/ +int U_PMR_STROKEFILLPATH_print(const char *contents){ + return(U_PMR_NODATAREC_print(contents)); +} + +/** + \brief Print data from a U_PMR_MULTIFORMATSTART record + \return 1 on success, 0 on error + \param contents Record from which to print data + EMF+ manual mentioned in 2.1.1.1, reserved, not otherwise documented, Microsoft name: EmfPlusMultiFormatStart Record, Index 0x05 +*/ +int U_PMR_MULTIFORMATSTART_print(const char *contents){ + return(U_PMR_NODATAREC_print(contents)); +} + +/** + \brief Print data from a U_PMR_MULTIFORMATSECTION record + \return 1 on success, 0 on error + \param contents Record from which to print data + EMF+ manual mentioned in 2.1.1.1, reserved, not otherwise documented, Microsoft name: EmfPlusMultiFormatSection Record, Index 0x06 +*/ +int U_PMR_MULTIFORMATSECTION_print(const char *contents){ + return(U_PMR_NODATAREC_print(contents)); +} + +/** + \brief Print data from a U_PMR_MULTIFORMATEND record + \return 1 on success, 0 on error + \param contents Record from which to print data + EMF+ manual mentioned in 2.1.1.1, reserved, not otherwise documented, Microsoft name: EmfPlusMultiFormatEnd Record, Index 0x06 +*/ +int U_PMR_MULTIFORMATEND_print(const char *contents){ + return(U_PMR_NODATAREC_print(contents)); +} + + + +#ifdef __cplusplus +} +#endif |