Permalink
Fetching contributors…
Cannot retrieve contributors at this time
858 lines (822 sloc) 27.5 KB
#ifdef __cplusplus
extern "C" {
#endif
#ifndef DARWIN
#define _POSIX_C_SOURCE 200809L
#endif
#include "emf2svg.h"
#include "emf2svg_private.h"
#include "emf2svg_print.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef DARWIN
#include "memstream.c"
#endif
int U_emf_onerec_is_emfp(const char *contents, const char *blimit, int recnum,
size_t off, bool *ret) {
PU_ENHMETARECORD lpEMFR = (PU_ENHMETARECORD)(contents + off);
unsigned int size;
size = lpEMFR->nSize;
contents += off;
/* Check that the record size is OK, abort if not.
Pointer math might wrap, so check both sides of the range */
if (size < sizeof(U_EMR) || contents + size - 1 >= blimit ||
contents + size - 1 < contents)
return (-1);
switch (lpEMFR->iType) {
case U_EMR_COMMENT:
*ret |= U_EMRCOMMENT_is_emfplus(contents, blimit);
break;
case U_EMR_EOF:
size = 0;
break;
default:
break;
}
return (size);
}
int U_emf_onerec_analyse(const char *contents, const char *blimit, int recnum,
size_t off, drawingStates *states) {
PU_ENHMETARECORD lpEMFR = (PU_ENHMETARECORD)(contents + off);
unsigned int size;
size = lpEMFR->nSize;
contents += off;
/* Check that the record size is OK, abort if not.
Pointer math might wrap, so check both sides of the range */
if (size < sizeof(U_EMR) || contents + size - 1 >= blimit ||
contents + size - 1 < contents)
return (-1);
switch (lpEMFR->iType) {
case U_EMR_HEADER:
break;
case U_EMR_POLYBEZIER:
case U_EMR_POLYGON:
case U_EMR_POLYLINE:
case U_EMR_POLYBEZIERTO:
case U_EMR_POLYLINETO:
case U_EMR_POLYPOLYLINE:
case U_EMR_POLYPOLYGON:
case U_EMR_SETWINDOWEXTEX:
case U_EMR_LINETO:
case U_EMR_ARCTO:
case U_EMR_POLYDRAW:
case U_EMR_POLYBEZIER16:
case U_EMR_POLYGON16:
case U_EMR_POLYLINE16:
case U_EMR_POLYBEZIERTO16:
case U_EMR_POLYLINETO16:
case U_EMR_POLYPOLYLINE16:
case U_EMR_POLYPOLYGON16:
case U_EMR_POLYDRAW16:
if (states->inPath) {
states->pathDrawn = true;
}
break;
case U_EMR_EOF:
size = 0;
break;
case U_EMR_BEGINPATH:
newPathStruct(states);
states->inPath = true;
break;
case U_EMR_ENDPATH:
states->inPath = false;
states->pathDrawn = false;
break;
case U_EMR_FILLPATH:
if (states->emfStructure.pathStackLast != NULL) {
states->emfStructure.pathStackLast->pathStruct.fillOffset = off;
}
break;
case U_EMR_STROKEANDFILLPATH:
if (states->emfStructure.pathStackLast != NULL) {
states->emfStructure.pathStackLast->pathStruct.strokeFillOffset =
off;
}
break;
case U_EMR_STROKEPATH:
if (states->emfStructure.pathStackLast != NULL) {
states->emfStructure.pathStackLast->pathStruct.strokeOffset = off;
}
break;
case U_EMR_FLATTENPATH:
if (states->emfStructure.pathStackLast != NULL) {
states->emfStructure.pathStackLast->pathStruct.flattenOffset = off;
}
break;
case U_EMR_WIDENPATH:
if (states->emfStructure.pathStackLast != NULL) {
states->emfStructure.pathStackLast->pathStruct.widdenOffset = off;
}
break;
case U_EMR_SELECTCLIPPATH:
if (states->emfStructure.pathStackLast != NULL) {
states->emfStructure.pathStackLast->pathStruct.clipOffset = off;
}
break;
case U_EMR_ABORTPATH:
if (states->emfStructure.pathStackLast != NULL) {
states->emfStructure.pathStackLast->pathStruct.abortOffset = off;
}
break;
case U_EMR_SETWORLDTRANSFORM:
if (states->inPath) {
PU_EMRSETWORLDTRANSFORM pEmr = (PU_EMRSETWORLDTRANSFORM)(contents);
states->currentDeviceContext.worldTransform = pEmr->xform;
if (states->pathDrawn) {
states->emfStructure.pathStackLast->pathStruct.wtBeforeSet =
true;
states->emfStructure.pathStackLast->pathStruct.wtBeforeiMode =
0;
states->emfStructure.pathStackLast->pathStruct.wtBeforexForm =
pEmr->xform;
} else {
states->emfStructure.pathStackLast->pathStruct.wtAfterSet =
true;
states->emfStructure.pathStackLast->pathStruct.wtAfteriMode = 0;
states->emfStructure.pathStackLast->pathStruct.wtAfterxForm =
pEmr->xform;
}
}
break;
case U_EMR_MODIFYWORLDTRANSFORM:
if (states->inPath) {
PU_EMRMODIFYWORLDTRANSFORM pEmr =
(PU_EMRMODIFYWORLDTRANSFORM)(contents);
states->currentDeviceContext.worldTransform = pEmr->xform;
if (states->pathDrawn) {
states->emfStructure.pathStackLast->pathStruct.wtBeforeSet =
true;
states->emfStructure.pathStackLast->pathStruct.wtBeforeiMode =
pEmr->iMode;
states->emfStructure.pathStackLast->pathStruct.wtBeforexForm =
pEmr->xform;
} else {
states->emfStructure.pathStackLast->pathStruct.wtAfterSet =
true;
states->emfStructure.pathStackLast->pathStruct.wtAfteriMode =
pEmr->iMode;
states->emfStructure.pathStackLast->pathStruct.wtAfterxForm =
pEmr->xform;
}
}
break;
case U_EMR_SETWINDOWORGEX:
case U_EMR_SETVIEWPORTEXTEX:
case U_EMR_SETVIEWPORTORGEX:
case U_EMR_SETBRUSHORGEX:
case U_EMR_SETPIXELV:
case U_EMR_SETMAPPERFLAGS:
case U_EMR_SETMAPMODE:
case U_EMR_SETBKMODE:
case U_EMR_SETPOLYFILLMODE:
case U_EMR_SETROP2:
case U_EMR_SETSTRETCHBLTMODE:
case U_EMR_SETTEXTALIGN:
case U_EMR_SETCOLORADJUSTMENT:
case U_EMR_SETTEXTCOLOR:
case U_EMR_SETBKCOLOR:
case U_EMR_OFFSETCLIPRGN:
case U_EMR_MOVETOEX:
case U_EMR_SETMETARGN:
case U_EMR_EXCLUDECLIPRECT:
case U_EMR_INTERSECTCLIPRECT:
case U_EMR_SCALEVIEWPORTEXTEX:
case U_EMR_SCALEWINDOWEXTEX:
case U_EMR_SAVEDC:
case U_EMR_RESTOREDC:
case U_EMR_SELECTOBJECT:
case U_EMR_CREATEPEN:
case U_EMR_CREATEBRUSHINDIRECT:
case U_EMR_DELETEOBJECT:
case U_EMR_ANGLEARC:
case U_EMR_ELLIPSE:
case U_EMR_RECTANGLE:
case U_EMR_ROUNDRECT:
case U_EMR_ARC:
case U_EMR_CHORD:
case U_EMR_PIE:
case U_EMR_SELECTPALETTE:
case U_EMR_CREATEPALETTE:
case U_EMR_SETPALETTEENTRIES:
case U_EMR_RESIZEPALETTE:
case U_EMR_REALIZEPALETTE:
case U_EMR_EXTFLOODFILL:
case U_EMR_SETARCDIRECTION:
case U_EMR_SETMITERLIMIT:
case U_EMR_CLOSEFIGURE:
case U_EMR_COMMENT:
case U_EMR_FILLRGN:
case U_EMR_FRAMERGN:
case U_EMR_INVERTRGN:
case U_EMR_PAINTRGN:
case U_EMR_EXTSELECTCLIPRGN:
case U_EMR_BITBLT:
case U_EMR_STRETCHBLT:
case U_EMR_MASKBLT:
case U_EMR_PLGBLT:
case U_EMR_SETDIBITSTODEVICE:
case U_EMR_STRETCHDIBITS:
case U_EMR_EXTCREATEFONTINDIRECTW:
case U_EMR_EXTTEXTOUTA:
case U_EMR_EXTTEXTOUTW:
case U_EMR_CREATEMONOBRUSH:
case U_EMR_CREATEDIBPATTERNBRUSHPT:
case U_EMR_EXTCREATEPEN:
// case U_EMR_POLYTEXTOUTA: break;
// case U_EMR_POLYTEXTOUTW: break;
case U_EMR_SETICMMODE:
case U_EMR_CREATECOLORSPACE:
case U_EMR_SETCOLORSPACE:
case U_EMR_DELETECOLORSPACE:
// case U_EMR_GLSRECORD: break;
// case U_EMR_GLSBOUNDEDRECORD: break;
case U_EMR_PIXELFORMAT:
// case U_EMR_DRAWESCAPE: break;
// case U_EMR_EXTESCAPE: break;
// case U_EMR_UNDEF107: break;
case U_EMR_SMALLTEXTOUT:
// case U_EMR_FORCEUFIMAPPING: break;
// case U_EMR_NAMEDESCAPE: break;
// case U_EMR_COLORCORRECTPALETTE: break;
// case U_EMR_SETICMPROFILEA: break;
// case U_EMR_SETICMPROFILEW: break;
case U_EMR_ALPHABLEND:
case U_EMR_SETLAYOUT:
case U_EMR_TRANSPARENTBLT:
// case U_EMR_UNDEF117: break;
case U_EMR_GRADIENTFILL:
// case U_EMR_SETLINKEDUFIS: break;
// case U_EMR_SETTEXTJUSTIFICATION: break;
// case U_EMR_COLORMATCHTOTARGETW: break;
case U_EMR_CREATECOLORSPACEW:
default:
// nothing to do for those records
break;
// case U_EMR_UNDEF69: break;
} // end of switch
return (size);
}
int U_emf_onerec_draw(const char *contents, const char *blimit, int recnum,
size_t off, FILE *out, drawingStates *states) {
PU_ENHMETARECORD lpEMFR = (PU_ENHMETARECORD)(contents + off);
unsigned int size;
if (states->verbose) {
U_emf_onerec_print(contents, blimit, recnum, off, states);
}
#ifdef RECORD_INDEX
if (recnum && !states->inPath) {
fprintf(out, "<!-- begin record: %d -->\n", recnum);
}
#endif /* RECORD_INDEX */
size = lpEMFR->nSize;
contents += off;
/* Check that the record size is OK, abort if not.
Pointer math might wrap, so check both sides of the range */
if (size < sizeof(U_EMR) || contents + size - 1 >= blimit ||
contents + size - 1 < contents)
return (-1);
switch (lpEMFR->iType) {
case U_EMR_HEADER:
U_EMRHEADER_draw(contents, out, states);
break;
case U_EMR_POLYBEZIER:
U_EMRPOLYBEZIER_draw(contents, out, states);
break;
case U_EMR_POLYGON:
U_EMRPOLYGON_draw(contents, out, states);
break;
case U_EMR_POLYLINE:
U_EMRPOLYLINE_draw(contents, out, states);
break;
case U_EMR_POLYBEZIERTO:
U_EMRPOLYBEZIERTO_draw(contents, out, states);
break;
case U_EMR_POLYLINETO:
U_EMRPOLYLINETO_draw(contents, out, states);
break;
case U_EMR_POLYPOLYLINE:
U_EMRPOLYPOLYLINE_draw(contents, out, states);
break;
case U_EMR_POLYPOLYGON:
U_EMRPOLYPOLYGON_draw(contents, out, states);
break;
case U_EMR_SETWINDOWEXTEX:
U_EMRSETWINDOWEXTEX_draw(contents, out, states);
break;
case U_EMR_SETWINDOWORGEX:
U_EMRSETWINDOWORGEX_draw(contents, out, states);
break;
case U_EMR_SETVIEWPORTEXTEX:
U_EMRSETVIEWPORTEXTEX_draw(contents, out, states);
break;
case U_EMR_SETVIEWPORTORGEX:
U_EMRSETVIEWPORTORGEX_draw(contents, out, states);
break;
case U_EMR_SETBRUSHORGEX:
U_EMRSETBRUSHORGEX_draw(contents, out, states);
break;
case U_EMR_EOF:
U_EMREOF_draw(contents, out, states);
size = 0;
break;
case U_EMR_SETPIXELV:
U_EMRSETPIXELV_draw(contents, out, states);
break;
case U_EMR_SETMAPPERFLAGS:
U_EMRSETMAPPERFLAGS_draw(contents, out, states);
break;
case U_EMR_SETMAPMODE:
U_EMRSETMAPMODE_draw(contents, out, states);
break;
case U_EMR_SETBKMODE:
U_EMRSETBKMODE_draw(contents, out, states);
break;
case U_EMR_SETPOLYFILLMODE:
U_EMRSETPOLYFILLMODE_draw(contents, out, states);
break;
case U_EMR_SETROP2:
U_EMRSETROP2_draw(contents, out, states);
break;
case U_EMR_SETSTRETCHBLTMODE:
U_EMRSETSTRETCHBLTMODE_draw(contents, out, states);
break;
case U_EMR_SETTEXTALIGN:
U_EMRSETTEXTALIGN_draw(contents, out, states);
break;
case U_EMR_SETCOLORADJUSTMENT:
U_EMRSETCOLORADJUSTMENT_draw(contents, out, states);
break;
case U_EMR_SETTEXTCOLOR:
U_EMRSETTEXTCOLOR_draw(contents, out, states);
break;
case U_EMR_SETBKCOLOR:
U_EMRSETBKCOLOR_draw(contents, out, states);
break;
case U_EMR_OFFSETCLIPRGN:
U_EMROFFSETCLIPRGN_draw(contents, out, states);
break;
case U_EMR_MOVETOEX:
U_EMRMOVETOEX_draw(contents, out, states);
break;
case U_EMR_SETMETARGN:
U_EMRSETMETARGN_draw(contents, out, states);
break;
case U_EMR_EXCLUDECLIPRECT:
U_EMREXCLUDECLIPRECT_draw(contents, out, states);
break;
case U_EMR_INTERSECTCLIPRECT:
U_EMRINTERSECTCLIPRECT_draw(contents, out, states);
break;
case U_EMR_SCALEVIEWPORTEXTEX:
U_EMRSCALEVIEWPORTEXTEX_draw(contents, out, states);
break;
case U_EMR_SCALEWINDOWEXTEX:
U_EMRSCALEWINDOWEXTEX_draw(contents, out, states);
break;
case U_EMR_SAVEDC:
U_EMRSAVEDC_draw(contents, out, states);
break;
case U_EMR_RESTOREDC:
U_EMRRESTOREDC_draw(contents, out, states);
break;
case U_EMR_SETWORLDTRANSFORM:
U_EMRSETWORLDTRANSFORM_draw(contents, out, states);
break;
case U_EMR_MODIFYWORLDTRANSFORM:
U_EMRMODIFYWORLDTRANSFORM_draw(contents, out, states);
break;
case U_EMR_SELECTOBJECT:
U_EMRSELECTOBJECT_draw(contents, out, states);
break;
case U_EMR_CREATEPEN:
U_EMRCREATEPEN_draw(contents, out, states);
break;
case U_EMR_CREATEBRUSHINDIRECT:
U_EMRCREATEBRUSHINDIRECT_draw(contents, out, states);
break;
case U_EMR_DELETEOBJECT:
U_EMRDELETEOBJECT_draw(contents, out, states);
break;
case U_EMR_ANGLEARC:
U_EMRANGLEARC_draw(contents, out, states);
break;
case U_EMR_ELLIPSE:
U_EMRELLIPSE_draw(contents, out, states);
break;
case U_EMR_RECTANGLE:
U_EMRRECTANGLE_draw(contents, out, states);
break;
case U_EMR_ROUNDRECT:
U_EMRROUNDRECT_draw(contents, out, states);
break;
case U_EMR_ARC:
U_EMRARC_draw(contents, out, states);
break;
case U_EMR_CHORD:
U_EMRCHORD_draw(contents, out, states);
break;
case U_EMR_PIE:
U_EMRPIE_draw(contents, out, states);
break;
case U_EMR_SELECTPALETTE:
U_EMRSELECTPALETTE_draw(contents, out, states);
break;
case U_EMR_CREATEPALETTE:
U_EMRCREATEPALETTE_draw(contents, out, states);
break;
case U_EMR_SETPALETTEENTRIES:
U_EMRSETPALETTEENTRIES_draw(contents, out, states);
break;
case U_EMR_RESIZEPALETTE:
U_EMRRESIZEPALETTE_draw(contents, out, states);
break;
case U_EMR_REALIZEPALETTE:
U_EMRREALIZEPALETTE_draw(contents, out, states);
break;
case U_EMR_EXTFLOODFILL:
U_EMREXTFLOODFILL_draw(contents, out, states);
break;
case U_EMR_LINETO:
U_EMRLINETO_draw(contents, out, states);
break;
case U_EMR_ARCTO:
U_EMRARCTO_draw(contents, out, states);
break;
case U_EMR_POLYDRAW:
U_EMRPOLYDRAW_draw(contents, out, states);
break;
case U_EMR_SETARCDIRECTION:
U_EMRSETARCDIRECTION_draw(contents, out, states);
break;
case U_EMR_SETMITERLIMIT:
U_EMRSETMITERLIMIT_draw(contents, out, states);
break;
case U_EMR_BEGINPATH:
U_EMRBEGINPATH_draw(contents, out, states);
break;
case U_EMR_ENDPATH:
U_EMRENDPATH_draw(contents, out, states);
break;
case U_EMR_CLOSEFIGURE:
U_EMRCLOSEFIGURE_draw(contents, out, states);
break;
case U_EMR_FILLPATH:
U_EMRFILLPATH_draw(contents, out, states);
break;
case U_EMR_STROKEANDFILLPATH:
U_EMRSTROKEANDFILLPATH_draw(contents, out, states);
break;
case U_EMR_STROKEPATH:
U_EMRSTROKEPATH_draw(contents, out, states);
break;
case U_EMR_FLATTENPATH:
U_EMRFLATTENPATH_draw(contents, out, states);
break;
case U_EMR_WIDENPATH:
U_EMRWIDENPATH_draw(contents, out, states);
break;
case U_EMR_SELECTCLIPPATH:
U_EMRSELECTCLIPPATH_draw(contents, out, states);
break;
case U_EMR_ABORTPATH:
U_EMRABORTPATH_draw(contents, out, states);
break;
// case U_EMR_UNDEF69: U_EMRUNDEF69_draw(contents,
// out, states); break;
case U_EMR_COMMENT:
U_EMRCOMMENT_draw(contents, out, states, blimit, off);
break;
case U_EMR_FILLRGN:
U_EMRFILLRGN_draw(contents, out, states);
break;
case U_EMR_FRAMERGN:
U_EMRFRAMERGN_draw(contents, out, states);
break;
case U_EMR_INVERTRGN:
U_EMRINVERTRGN_draw(contents, out, states);
break;
case U_EMR_PAINTRGN:
U_EMRPAINTRGN_draw(contents, out, states);
break;
case U_EMR_EXTSELECTCLIPRGN:
U_EMREXTSELECTCLIPRGN_draw(contents, out, states);
break;
case U_EMR_BITBLT:
U_EMRBITBLT_draw(contents, out, states);
break;
case U_EMR_STRETCHBLT:
U_EMRSTRETCHBLT_draw(contents, out, states);
break;
case U_EMR_MASKBLT:
U_EMRMASKBLT_draw(contents, out, states);
break;
case U_EMR_PLGBLT:
U_EMRPLGBLT_draw(contents, out, states);
break;
case U_EMR_SETDIBITSTODEVICE:
U_EMRSETDIBITSTODEVICE_draw(contents, out, states);
break;
case U_EMR_STRETCHDIBITS:
U_EMRSTRETCHDIBITS_draw(contents, out, states);
break;
case U_EMR_EXTCREATEFONTINDIRECTW:
U_EMREXTCREATEFONTINDIRECTW_draw(contents, out, states);
break;
case U_EMR_EXTTEXTOUTA:
U_EMREXTTEXTOUTA_draw(contents, out, states);
break;
case U_EMR_EXTTEXTOUTW:
U_EMREXTTEXTOUTW_draw(contents, out, states);
break;
case U_EMR_POLYBEZIER16:
U_EMRPOLYBEZIER16_draw(contents, out, states);
break;
case U_EMR_POLYGON16:
U_EMRPOLYGON16_draw(contents, out, states);
break;
case U_EMR_POLYLINE16:
U_EMRPOLYLINE16_draw(contents, out, states);
break;
case U_EMR_POLYBEZIERTO16:
U_EMRPOLYBEZIERTO16_draw(contents, out, states);
break;
case U_EMR_POLYLINETO16:
U_EMRPOLYLINETO16_draw(contents, out, states);
break;
case U_EMR_POLYPOLYLINE16:
U_EMRPOLYPOLYLINE16_draw(contents, out, states);
break;
case U_EMR_POLYPOLYGON16:
U_EMRPOLYPOLYGON16_draw(contents, out, states);
break;
case U_EMR_POLYDRAW16:
U_EMRPOLYDRAW16_draw(contents, out, states);
break;
case U_EMR_CREATEMONOBRUSH:
U_EMRCREATEMONOBRUSH_draw(contents, out, states);
break;
case U_EMR_CREATEDIBPATTERNBRUSHPT:
U_EMRCREATEDIBPATTERNBRUSHPT_draw(contents, out, states);
break;
case U_EMR_EXTCREATEPEN:
U_EMREXTCREATEPEN_draw(contents, out, states);
break;
// case U_EMR_POLYTEXTOUTA: U_EMRPOLYTEXTOUTA_draw(contents, out,
// states); break;
// case U_EMR_POLYTEXTOUTW: U_EMRPOLYTEXTOUTW_draw(contents, out,
// states); break;
case U_EMR_SETICMMODE:
U_EMRSETICMMODE_draw(contents, out, states);
break;
case U_EMR_CREATECOLORSPACE:
U_EMRCREATECOLORSPACE_draw(contents, out, states);
break;
case U_EMR_SETCOLORSPACE:
U_EMRSETCOLORSPACE_draw(contents, out, states);
break;
case U_EMR_DELETECOLORSPACE:
U_EMRDELETECOLORSPACE_draw(contents, out, states);
break;
// case U_EMR_GLSRECORD: U_EMRGLSRECORD_draw(contents, out,
// states); break;
// case U_EMR_GLSBOUNDEDRECORD: U_EMRGLSBOUNDEDRECORD_draw(contents,
// out, states); break;
case U_EMR_PIXELFORMAT:
U_EMRPIXELFORMAT_draw(contents, out, states);
break;
// case U_EMR_DRAWESCAPE: U_EMRDRAWESCAPE_draw(contents, out,
// states); break;
// case U_EMR_EXTESCAPE: U_EMREXTESCAPE_draw(contents, out,
// states); break;
// case U_EMR_UNDEF107: U_EMRUNDEF107_draw(contents, out,
// states); break;
case U_EMR_SMALLTEXTOUT:
U_EMRSMALLTEXTOUT_draw(contents, out, states);
break;
// case U_EMR_FORCEUFIMAPPING: U_EMRFORCEUFIMAPPING_draw(contents,
// out, states); break;
// case U_EMR_NAMEDESCAPE: U_EMRNAMEDESCAPE_draw(contents, out,
// states); break;
// case U_EMR_COLORCORRECTPALETTE:
// U_EMRCOLORCORRECTPALETTE_draw(contents, out, states); break;
// case U_EMR_SETICMPROFILEA: U_EMRSETICMPROFILEA_draw(contents,
// out, states); break;
// case U_EMR_SETICMPROFILEW: U_EMRSETICMPROFILEW_draw(contents,
// out, states); break;
case U_EMR_ALPHABLEND:
U_EMRALPHABLEND_draw(contents, out, states);
break;
case U_EMR_SETLAYOUT:
U_EMRSETLAYOUT_draw(contents, out, states);
break;
case U_EMR_TRANSPARENTBLT:
U_EMRTRANSPARENTBLT_draw(contents, out, states);
break;
// case U_EMR_UNDEF117: U_EMRUNDEF117_draw(contents, out,
// states); break;
case U_EMR_GRADIENTFILL:
U_EMRGRADIENTFILL_draw(contents, out, states);
break;
// case U_EMR_SETLINKEDUFIS: U_EMRSETLINKEDUFIS_draw(contents,
// out, states); break;
// case U_EMR_SETTEXTJUSTIFICATION:
// U_EMRSETTEXTJUSTIFICATION_draw(contents, out, states); break;
// case U_EMR_COLORMATCHTOTARGETW:
// U_EMRCOLORMATCHTOTARGETW_draw(contents, out, states); break;
case U_EMR_CREATECOLORSPACEW:
U_EMRCREATECOLORSPACEW_draw(contents, out, states);
break;
default:
U_EMRNOTIMPLEMENTED_draw("?", contents, out, states);
break;
} // end of switch
return (size);
}
int emf2svg(char *contents, size_t length, char **out, size_t *out_length,
generatorOptions *options) {
size_t off = 0;
size_t result;
int OK = 1;
int recnum = 0;
PU_ENHMETARECORD pEmr;
char *blimit;
FILE *stream;
#if U_BYTE_SWAP
// This is a Big Endian machine, EMF data is Little Endian
U_emf_endian(contents, length, 0); // LE to BE
#endif
drawingStates *states = (drawingStates *)calloc(1, sizeof(drawingStates));
states->verbose = options->verbose;
states->emfplus = options->emfplus;
states->imgWidth = options->imgWidth;
states->imgHeight = options->imgHeight;
states->endAddress = (intptr_t)contents + (intptr_t)length;
if ((options->nameSpace != NULL) && (strlen(options->nameSpace) != 0)) {
states->nameSpace = options->nameSpace;
states->nameSpaceString =
(char *)calloc(strlen(options->nameSpace) + 2, sizeof(char));
sprintf(states->nameSpaceString, "%s%s", states->nameSpace, ":");
} else {
states->nameSpaceString = (char *)"";
}
states->svgDelimiter = options->svgDelimiter;
states->currentDeviceContext.font_name = NULL;
/* initialized to -1 because real size of states->objectTable is always
* states->objectTableSize + 1 (for easier index manipulation since
* indexes in emf files start at 1 and not 0)*/
states->objectTableSize = -1;
setTransformIdentity(states);
blimit = contents + length;
int err = 1;
stream = open_memstream(out, out_length);
if (stream == NULL) {
if (states->verbose) {
printf("Failed to allocate output stream\n");
}
FLAG_RESET;
err = 0;
OK = 0;
}
// analyze emf structure
while (OK) {
if (off >= length) { // normally should exit from while after EMREOF
// sets OK to false, this is most likely a corrupt
// EMF
if (states->verbose) {
printf("WARNING(scanning): record claims to extend beyond the "
"end of the EMF file\n");
}
OK = 0;
err = 0;
}
pEmr = (PU_ENHMETARECORD)(contents + off);
if (!recnum && (pEmr->iType != U_EMR_HEADER)) {
if (states->verbose) {
printf("WARNING(scanning): EMF file does not begin with an "
"EMR_HEADER record\n");
}
OK = 0;
err = 0;
}
if (recnum && (pEmr->iType == U_EMR_HEADER)) {
if (states->verbose) {
printf("ABORTING(scanning): EMF contains two or more "
"EMR_HEADER records\n");
}
OK = 0;
err = 0;
}
result = U_emf_onerec_analyse(contents, blimit, recnum, off, states);
if (result == (size_t)-1 || states->Error) {
if (states->verbose) {
printf(
"ABORTING(scanning): invalid record - corrupted file?\n");
}
OK = 0;
} else if (!result) {
OK = 0;
} else {
off += result;
recnum++;
}
} // end of while
FLAG_RESET;
setTransformIdentity(states);
// continu only if no previous errors
if (err == 0) {
OK = 0;
} else {
OK = 1;
}
off = 0;
recnum = 0;
while (OK) {
if (off >= length) { // normally should exit from while after EMREOF
// sets OK to false, this is most likely a corrupt
// EMF
if (states->verbose) {
printf("WARNING(converting): record claims to extend beyond "
"the end of the EMF file\n");
}
OK = 0;
err = 0;
}
pEmr = (PU_ENHMETARECORD)(contents + off);
result =
U_emf_onerec_draw(contents, blimit, recnum, off, stream, states);
if (result == (size_t)-1 || states->Error) {
if (states->verbose) {
printf(
"ABORTING(converting): invalid record - corrupted file?\n");
}
OK = 0;
err = 0;
} else if (!result) {
OK = 0;
} else {
off += result;
recnum++;
}
} // end of while
FLAG_RESET;
freeObjectTable(states);
freePathStack(states->emfStructure.pathStack);
free_path(&(states->currentPath));
free(states->objectTable);
freeDeviceContext(&(states->currentDeviceContext));
freeDeviceContextStack(states);
freeEmfImageLibrary(states);
free(states);
fflush(stream);
fclose(stream);
return err;
}
int emf2svg_is_emfplus(char *contents, size_t length, bool *is_emfp) {
size_t off = 0;
size_t result;
int OK = 1;
int recnum = 0;
PU_ENHMETARECORD pEmr;
char *blimit;
*is_emfp = false;
#if U_BYTE_SWAP
// This is a Big Endian machine, EMF data is Little Endian
U_emf_endian(contents, length, 0); // LE to BE
#endif
blimit = contents + length;
int err = 1;
// analyze emf structure
while (OK) {
if (off >= length) { // normally should exit from while after EMREOF
// sets OK to false, this is most likely a corrupt
// EMF
OK = 0;
err = 0;
}
pEmr = (PU_ENHMETARECORD)(contents + off);
if (!recnum && (pEmr->iType != U_EMR_HEADER)) {
OK = 0;
err = 0;
}
if (recnum && (pEmr->iType == U_EMR_HEADER)) {
OK = 0;
err = 0;
}
result = U_emf_onerec_is_emfp(contents, blimit, recnum, off, is_emfp);
if (result == (size_t)-1) {
OK = 0;
} else if (!result) {
OK = 0;
} else {
off += result;
recnum++;
}
} // end of while
return err;
}
#ifdef __cplusplus
}
#endif
/* vim:set shiftwidth=2 softtabstop=2 expandtab: */