summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Mathog <>2012-10-25 08:08:38 +0000
committer~suv <suv-sf@users.sourceforge.net>2012-10-25 08:08:38 +0000
commit8fae5ea0ef11d8a447d0a7e93e045cc2d67b2cc7 (patch)
tree9d34f785cbdcdb7ed007523df32e6d445fc5c401
parentmerge from trunk (r11821) (diff)
downloadinkscape-8fae5ea0ef11d8a447d0a7e93e045cc2d67b2cc7.tar.gz
inkscape-8fae5ea0ef11d8a447d0a7e93e045cc2d67b2cc7.zip
changes_2012_10_22b.patch, changes_2012_10_24a.patch
EMF import (Adobe Illustrator EMF files): - workaround for issue with page scaling ('MM_ANISOTROPIC', wrong units) - fix SETWORLDTRANSFORM operation - fix libUEMF to support older/shorter EMF header forms EMF import (general): - fix import of shapes (rectangles) without borders - handle EMF bitmap modes where a subsection of the image is extracted EMF export/import: - increased size in mm of the reference device by 100X on EMF export (significant when the dpi is calculated on reading the EMF back in) - changed dpi calculation: (sum of pixels ref device)/(sum of millimeter ref device) (bzr r11668.1.34)
-rw-r--r--src/extension/internal/emf-inout.cpp356
-rw-r--r--src/extension/internal/emf-print.cpp42
-rw-r--r--src/extension/internal/uemf.c62
-rw-r--r--src/extension/internal/uemf.h7
-rw-r--r--src/extension/internal/uemf_endian.c48
-rw-r--r--src/extension/internal/uemf_print.c27
6 files changed, 372 insertions, 170 deletions
diff --git a/src/extension/internal/emf-inout.cpp b/src/extension/internal/emf-inout.cpp
index 8be4e998e..acc3443d5 100644
--- a/src/extension/internal/emf-inout.cpp
+++ b/src/extension/internal/emf-inout.cpp
@@ -390,17 +390,16 @@ typedef struct emf_callback_data {
EMF_DEVICE_CONTEXT dc[EMF_MAX_DC+1]; // FIXME: This should be dynamic..
int level;
- double xDPI, yDPI;
- uint32_t mask; // Draw properties
- int arcdir; //U_AD_COUNTERCLOCKWISE 1 or U_AD_CLOCKWISE 2
+ double ulCornerX,ulCornerY; // Upper left corner, from header rclBounds, in logical units
+ double ydir; // 1.0 if y is positive DOWN (usual case), -1.0 if y is negative DOWN
+ uint32_t mask; // Draw properties
+ int arcdir; //U_AD_COUNTERCLOCKWISE 1 or U_AD_CLOCKWISE 2
- uint32_t dwRop2; // Binary raster operation, 0 if none (use brush/pen unmolested)
- uint32_t dwRop3; // Ternary raster operation, 0 if none (use brush/pen unmolested)
+ uint32_t dwRop2; // Binary raster operation, 0 if none (use brush/pen unmolested)
+ uint32_t dwRop3; // Ternary raster operation, 0 if none (use brush/pen unmolested)
float MMX;
float MMY;
- float dwInchesX;
- float dwInchesY;
unsigned int id;
unsigned int drawtype; // one of 0 or U_EMR_FILLPATH, U_EMR_STROKEPATH, U_EMR_STROKEANDFILLPATH
@@ -629,17 +628,20 @@ uint32_t add_image(PEMF_CALLBACK_DATA d, void *pEmr, uint32_t cbBits, uint32_t
ct, // DIB color table
numCt, // DIB color table number of entries
&rgba_px, // U_RGBA pixel array (32 bits), created by this routine, caller must free.
- width, // Width of pixel array
- height, // Height of pixel array
+ width, // Width of pixel array in record
+ height, // Height of pixel array in record
colortype, // DIB BitCount Enumeration
numCt, // Color table used if not 0
- invert // If DIB rows are in opposite order from RGBA rows
+ invert, // If DIB rows are in opposite order from RGBA rows
+ 0,0, // start position in pixel array in record
+ width, // Width of extracted pixel array
+ height // Height of extracted pixel array
) &&
rgba_px)
{
toPNG( // Get the image from the RGBA px into mempng
&mempng,
- width, height,
+ width, height, // of the SRC bitmap
rgba_px);
free(rgba_px);
}
@@ -888,17 +890,23 @@ output_style(PEMF_CALLBACK_DATA d, int iType)
static double
_pix_x_to_point(PEMF_CALLBACK_DATA d, double px)
{
- double tmp = px - d->dc[d->level].winorg.x;
- tmp *= d->dc[d->level].ScaleInX ? d->dc[d->level].ScaleInX : 1.0;
+ double scale = (d->dc[d->level].ScaleInX ? d->dc[d->level].ScaleInX : 1.0);
+ double tmp = px;
+ tmp -= d->dc[d->level].winorg.x;
+ tmp *= scale;
+ tmp -= d->ulCornerX;
tmp += d->dc[d->level].vieworg.x;
return tmp;
}
static double
-_pix_y_to_point(PEMF_CALLBACK_DATA d, double px)
+_pix_y_to_point(PEMF_CALLBACK_DATA d, double py)
{
- double tmp = px - d->dc[d->level].winorg.y;
- tmp *= d->dc[d->level].ScaleInY ? d->dc[d->level].ScaleInY : 1.0;
+ double scale = (d->dc[d->level].ScaleInY ? d->dc[d->level].ScaleInY : 1.0);
+ double tmp = py;
+ tmp -= d->dc[d->level].winorg.y;
+ tmp *= scale;
+ tmp += d->ydir*d->ulCornerY;
tmp += d->dc[d->level].vieworg.y;
return tmp;
}
@@ -907,10 +915,13 @@ _pix_y_to_point(PEMF_CALLBACK_DATA d, double px)
static double
pix_to_x_point(PEMF_CALLBACK_DATA d, double px, double py)
{
+ double wpx = px * d->dc[d->level].worldTransform.eM11 + py * d->dc[d->level].worldTransform.eM21 + d->dc[d->level].worldTransform.eDx;
+ double x = _pix_x_to_point(d, wpx);
+/*
double ppx = _pix_x_to_point(d, px);
double ppy = _pix_y_to_point(d, py);
-
double x = ppx * d->dc[d->level].worldTransform.eM11 + ppy * d->dc[d->level].worldTransform.eM21 + d->dc[d->level].worldTransform.eDx;
+*/
x *= device_scale;
return x;
@@ -919,13 +930,18 @@ pix_to_x_point(PEMF_CALLBACK_DATA d, double px, double py)
static double
pix_to_y_point(PEMF_CALLBACK_DATA d, double px, double py)
{
+
+ double wpy = px * d->dc[d->level].worldTransform.eM12 + py * d->dc[d->level].worldTransform.eM22 + d->dc[d->level].worldTransform.eDy;
+ double y = _pix_y_to_point(d, wpy);
+/*
double ppx = _pix_x_to_point(d, px);
double ppy = _pix_y_to_point(d, py);
-
double y = ppx * d->dc[d->level].worldTransform.eM12 + ppy * d->dc[d->level].worldTransform.eM22 + d->dc[d->level].worldTransform.eDy;
+*/
y *= device_scale;
return y;
+
}
static double
@@ -1123,8 +1139,13 @@ select_extpen(PEMF_CALLBACK_DATA d, int index)
d->dc[d->level].style.stroke_dasharray_set = 1;
break;
}
-
case U_PS_SOLID:
+/* includes these for now, some should maybe not be in here
+ case U_PS_NULL:
+ case U_PS_INSIDEFRAME:
+ case U_PS_ALTERNATE:
+ case U_PS_STYLE_MASK:
+*/
default:
{
d->dc[d->level].style.stroke_dasharray_set = 0;
@@ -1172,51 +1193,60 @@ select_extpen(PEMF_CALLBACK_DATA d, int index)
d->dc[d->level].stroke_set = true;
- if (pEmr->elp.elpPenStyle == U_PS_NULL) {
+ if (pEmr->elp.elpPenStyle == U_PS_NULL) { // draw nothing, but fill out all the values with something
+ double r, g, b;
+ r = SP_COLOR_U_TO_F( U_RGBAGetR(d->dc[d->level].textColor));
+ g = SP_COLOR_U_TO_F( U_RGBAGetG(d->dc[d->level].textColor));
+ b = SP_COLOR_U_TO_F( U_RGBAGetB(d->dc[d->level].textColor));
+ d->dc[d->level].style.stroke.value.color.set( r, g, b );
d->dc[d->level].style.stroke_width.value = 0;
d->dc[d->level].stroke_set = false;
- } else if (pEmr->elp.elpWidth) {
- int cur_level = d->level;
- d->level = d->emf_obj[index].level;
- double pen_width = pix_to_size_point( d, pEmr->elp.elpWidth );
- d->level = cur_level;
- d->dc[d->level].style.stroke_width.value = pen_width;
- } else { // this stroke should always be rendered as 1 pixel wide, independent of zoom level (can that be done in SVG?)
- //d->dc[d->level].style.stroke_width.value = 1.0;
- int cur_level = d->level;
- d->level = d->emf_obj[index].level;
- double pen_width = pix_to_size_point( d, 1 );
- d->level = cur_level;
- d->dc[d->level].style.stroke_width.value = pen_width;
+ d->dc[d->level].stroke_mode = DRAW_PAINT;
}
+ else {
+ if (pEmr->elp.elpWidth) {
+ int cur_level = d->level;
+ d->level = d->emf_obj[index].level;
+ double pen_width = pix_to_size_point( d, pEmr->elp.elpWidth );
+ d->level = cur_level;
+ d->dc[d->level].style.stroke_width.value = pen_width;
+ } else { // this stroke should always be rendered as 1 pixel wide, independent of zoom level (can that be done in SVG?)
+ //d->dc[d->level].style.stroke_width.value = 1.0;
+ int cur_level = d->level;
+ d->level = d->emf_obj[index].level;
+ double pen_width = pix_to_size_point( d, 1 );
+ d->level = cur_level;
+ d->dc[d->level].style.stroke_width.value = pen_width;
+ }
- if( pEmr->elp.elpBrushStyle == U_BS_SOLID){
- double r, g, b;
- r = SP_COLOR_U_TO_F( U_RGBAGetR(pEmr->elp.elpColor) );
- g = SP_COLOR_U_TO_F( U_RGBAGetG(pEmr->elp.elpColor) );
- b = SP_COLOR_U_TO_F( U_RGBAGetB(pEmr->elp.elpColor) );
- d->dc[d->level].style.stroke.value.color.set( r, g, b );
- d->dc[d->level].stroke_mode = DRAW_PAINT;
- d->dc[d->level].stroke_set = true;
- }
- else if(pEmr->elp.elpBrushStyle == U_BS_HATCHED){
- d->dc[d->level].stroke_idx = add_hatch(d, pEmr->elp.elpHatch, pEmr->elp.elpColor);
- d->dc[d->level].stroke_mode = DRAW_PATTERN;
- d->dc[d->level].stroke_set = true;
- }
- else if(pEmr->elp.elpBrushStyle == U_BS_DIBPATTERN || pEmr->elp.elpBrushStyle == U_BS_DIBPATTERNPT){
- d->dc[d->level].stroke_idx = add_image(d, pEmr, pEmr->cbBits, pEmr->cbBmi, *(uint32_t *) &(pEmr->elp.elpColor), pEmr->offBits, pEmr->offBmi);
- d->dc[d->level].stroke_mode = DRAW_IMAGE;
- d->dc[d->level].stroke_set = true;
- }
- else { // U_BS_PATTERN and anything strange that falls in, stroke is solid textColor
- double r, g, b;
- r = SP_COLOR_U_TO_F( U_RGBAGetR(d->dc[d->level].textColor));
- g = SP_COLOR_U_TO_F( U_RGBAGetG(d->dc[d->level].textColor));
- b = SP_COLOR_U_TO_F( U_RGBAGetB(d->dc[d->level].textColor));
- d->dc[d->level].style.stroke.value.color.set( r, g, b );
- d->dc[d->level].stroke_mode = DRAW_PAINT;
- d->dc[d->level].stroke_set = true;
+ if( pEmr->elp.elpBrushStyle == U_BS_SOLID){
+ double r, g, b;
+ r = SP_COLOR_U_TO_F( U_RGBAGetR(pEmr->elp.elpColor) );
+ g = SP_COLOR_U_TO_F( U_RGBAGetG(pEmr->elp.elpColor) );
+ b = SP_COLOR_U_TO_F( U_RGBAGetB(pEmr->elp.elpColor) );
+ d->dc[d->level].style.stroke.value.color.set( r, g, b );
+ d->dc[d->level].stroke_mode = DRAW_PAINT;
+ d->dc[d->level].stroke_set = true;
+ }
+ else if(pEmr->elp.elpBrushStyle == U_BS_HATCHED){
+ d->dc[d->level].stroke_idx = add_hatch(d, pEmr->elp.elpHatch, pEmr->elp.elpColor);
+ d->dc[d->level].stroke_mode = DRAW_PATTERN;
+ d->dc[d->level].stroke_set = true;
+ }
+ else if(pEmr->elp.elpBrushStyle == U_BS_DIBPATTERN || pEmr->elp.elpBrushStyle == U_BS_DIBPATTERNPT){
+ d->dc[d->level].stroke_idx = add_image(d, pEmr, pEmr->cbBits, pEmr->cbBmi, *(uint32_t *) &(pEmr->elp.elpColor), pEmr->offBits, pEmr->offBmi);
+ d->dc[d->level].stroke_mode = DRAW_IMAGE;
+ d->dc[d->level].stroke_set = true;
+ }
+ else { // U_BS_PATTERN and anything strange that falls in, stroke is solid textColor
+ double r, g, b;
+ r = SP_COLOR_U_TO_F( U_RGBAGetR(d->dc[d->level].textColor));
+ g = SP_COLOR_U_TO_F( U_RGBAGetG(d->dc[d->level].textColor));
+ b = SP_COLOR_U_TO_F( U_RGBAGetB(d->dc[d->level].textColor));
+ d->dc[d->level].style.stroke.value.color.set( r, g, b );
+ d->dc[d->level].stroke_mode = DRAW_PAINT;
+ d->dc[d->level].stroke_set = true;
+ }
}
}
@@ -1352,6 +1382,24 @@ insert_object(PEMF_CALLBACK_DATA d, int index, int type, PU_ENHMETARECORD pObj)
}
}
+/* Identify probable Adobe Illustrator produced EMF files, which do strange things with the scaling.
+ The few so far observed all had this format.
+*/
+int AI_hack(PU_EMRHEADER pEmr){
+ int ret=0;
+ char *ptr;
+ ptr = (char *)pEmr;
+ PU_EMRSETMAPMODE nEmr = (PU_EMRSETMAPMODE) (ptr + pEmr->emr.nSize);
+ char *string = NULL;
+ if(pEmr->nDescription)string = U_Utf16leToUtf8((uint16_t *)((char *) pEmr + pEmr->offDescription), pEmr->nDescription, NULL);
+ if((pEmr->nDescription >= 13) &&
+ (0==strcmp("Adobe Systems",string)) &&
+ (nEmr->emr.iType == U_EMR_SETMAPMODE) &&
+ (nEmr->iMode == U_MM_ANISOTROPIC)){ ret=1; }
+ if(string)free(string);
+ return(ret);
+}
+
/**
\fn create a UTF-32LE buffer and fill it with UNICODE unknown character
\param count number of copies of the Unicode unknown character to fill with
@@ -1364,10 +1412,27 @@ uint32_t *unknown_chars(size_t count){
return res;
}
-void common_image_extraction(PEMF_CALLBACK_DATA d, void *pEmr, double l, double t, double r, double b,
+/**
+ \fn store SVG for an image given the pixmap and various coordinate information
+ \param d
+ \param pEmr
+ \param dl (double) destination left in inkscape pixels
+ \param dt (double) destination top in inkscape pixels
+ \param dr (double) destination right in inkscape pixels
+ \param db (double) destination bottom in inkscape pixels
+ \param sl (int) source left in pixels in the src image
+ \param st (int) source top in pixels in the src image
+ \param iUsage
+ \param offBits
+ \param cbBits
+ \param offBmi
+ \param cbBmi
+*/
+void common_image_extraction(PEMF_CALLBACK_DATA d, void *pEmr,
+ double dl, double dt, double dr, double db, int sl, int st, int sw, int sh,
uint32_t iUsage, uint32_t offBits, uint32_t cbBits, uint32_t offBmi, uint32_t cbBmi){
SVGOStringStream tmp_image;
- tmp_image << " y=\"" << t << "\"\n x=\"" << l <<"\"\n ";
+ tmp_image << " y=\"" << dt << "\"\n x=\"" << dl <<"\"\n ";
// The image ID is filled in much later when tmp_image is converted
@@ -1395,6 +1460,10 @@ void common_image_extraction(PEMF_CALLBACK_DATA d, void *pEmr, double l, double
&colortype,
&invert
)){
+ if(sw == 0 || sl == 0){
+ sw = width;
+ sh = height;
+ }
if(!DIB_to_RGBA(
px, // DIB pixel array
@@ -1405,13 +1474,15 @@ void common_image_extraction(PEMF_CALLBACK_DATA d, void *pEmr, double l, double
height, // Height of pixel array
colortype, // DIB BitCount Enumeration
numCt, // Color table used if not 0
- invert // If DIB rows are in opposite order from RGBA rows
+ invert, // If DIB rows are in opposite order from RGBA rows
+ sl,st, // starting point in pixel array
+ sw,sh // columns/rows to extract from the pixel array (output array size)
) &&
rgba_px)
{
toPNG( // Get the image from the RGBA px into mempng
&mempng,
- width, height,
+ sw, sh, // size of the extracted pixel array
rgba_px);
free(rgba_px);
}
@@ -1427,7 +1498,7 @@ void common_image_extraction(PEMF_CALLBACK_DATA d, void *pEmr, double l, double
tmp_image << "iVBORw0KGgoAAAANSUhEUgAAAAQAAAADCAIAAAA7ljmRAAAAA3NCSVQICAjb4U/gAAAALElEQVQImQXBQQ2AMAAAsUJQMSWI2H8qME1yMshojwrvGB8XcHKvR1XtOTc/8HENumHCsOMAAAAASUVORK5CYII=";
}
- tmp_image << "\"\n height=\"" << b-t+1 << "\"\n width=\"" << r-l+1 << "\"\n";
+ tmp_image << "\"\n height=\"" << db-dt+1 << "\"\n width=\"" << dr-dl+1 << "\"\n";
*(d->outsvg) += "\n\t <image\n";
*(d->outsvg) += tmp_image.str().c_str();
@@ -1535,29 +1606,42 @@ std::cout << "BEFORE DRAW"
tmp_outdef << " xmlns:sodipodi=\"http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd\"\n"; // needed for sodipodi:role
tmp_outdef << " version=\"1.0\"\n";
- d->xDPI = 2540;
- d->yDPI = 2540;
+ d->ulCornerX = pEmr->rclBounds.left; // Upper left corner, from header rclBounds, in logical units, usually both 0, but not always
+ d->ulCornerY = pEmr->rclBounds.top;;
- d->dc[d->level].PixelsInX = pEmr->rclFrame.right; // - pEmr->rclFrame.left;
- d->dc[d->level].PixelsInY = pEmr->rclFrame.bottom; // - pEmr->rclFrame.top;
-
- d->MMX = d->dc[d->level].PixelsInX / 100.0;
- d->MMY = d->dc[d->level].PixelsInY / 100.0;
-
- d->dc[d->level].PixelsOutX = d->MMX * PX_PER_MM;
- d->dc[d->level].PixelsOutY = d->MMY * PX_PER_MM;
+ if(pEmr->rclFrame.bottom < 0 || pEmr->rclFrame.top < 0){ d->ydir = -1.0; }
+ else { d->ydir = 1.0; }
+ /* inclusive-inclusive, so the size is 1 more than the difference */
+ d->dc[d->level].PixelsInX = pEmr->rclFrame.right - pEmr->rclFrame.left + 1;
+ d->dc[d->level].PixelsInY = pEmr->rclFrame.bottom - pEmr->rclFrame.top + 1;
/*
calculate ratio of Inkscape dpi/device dpi
- This can cause problems later due to accuracy limits in the EMF. A super high resolution
+ This can cause problems later due to accuracy limits in the EMF. A high resolution
EMF might have a final device_scale of 0.074998, and adjusting the (integer) device size
by 1 will still not get it exactly to 0.075. Later when the font size is calculated it
can end up as 29.9992 or 22.4994 instead of the intended 30 or 22.5. This is handled by
- snapping font sizes to the nearest .01.
+ snapping font sizes to the nearest .01. The best estimate is made by using both values.
*/
- if (pEmr->szlMillimeters.cx && pEmr->szlDevice.cx)
- device_scale = PX_PER_MM*pEmr->szlMillimeters.cx/pEmr->szlDevice.cx;
-
+ if (pEmr->szlMillimeters.cx && pEmr->szlDevice.cx) device_scale = PX_PER_MM *
+ (pEmr->szlMillimeters.cx + pEmr->szlMillimeters.cy)/( pEmr->szlDevice.cx + pEmr->szlDevice.cy);
+
+ /* Adobe Illustrator files set mapmode to MM_ANISOTROPIC and somehow or other this
+ converts the rclFrame values from MM_HIMETRIC to MM_HIENGLISH, with another factor of 3 thrown
+ in for good measure. Ours not to question why...
+ */
+ if(AI_hack(pEmr)){
+ d->dc[d->level].PixelsInX *= 25.4/(10.0*3.0);
+ d->dc[d->level].PixelsInY *= 25.4/(10.0*3.0);
+ device_scale *= 25.4/(10.0*3.0);
+ }
+
+ d->MMX = d->dc[d->level].PixelsInX / 100.0;
+ d->MMY = d->dc[d->level].PixelsInY / 100.0;
+
+ d->dc[d->level].PixelsOutX = d->MMX * PX_PER_MM;
+ d->dc[d->level].PixelsOutY = d->MMY * PX_PER_MM;
+
tmp_outdef <<
" width=\"" << d->MMX << "mm\"\n" <<
" height=\"" << d->MMY << "mm\">\n";
@@ -1849,7 +1933,43 @@ std::cout << "BEFORE DRAW"
}
case U_EMR_SETPIXELV: dbg_str << "<!-- U_EMR_SETPIXELV -->\n"; break;
case U_EMR_SETMAPPERFLAGS: dbg_str << "<!-- U_EMR_SETMAPPERFLAGS -->\n"; break;
- case U_EMR_SETMAPMODE: dbg_str << "<!-- U_EMR_SETMAPMODE -->\n"; break;
+ case U_EMR_SETMAPMODE:
+ {
+ dbg_str << "<!-- U_EMR_SETMAPMODE -->\n";
+ PU_EMRSETMAPMODE pEmr = (PU_EMRSETMAPMODE) lpEMFR;
+ switch (pEmr->iMode){
+ case U_MM_TEXT:
+ default:
+ d->ydir = 1.0;
+ // leave device_scale as is, device_scale maps LU pixels to inkscape pixels as set in the EMF header
+ break;
+ case U_MM_LOMETRIC: // 1 LU = 0.1 mm
+ d->ydir = -1.0;
+ device_scale = 0.1 * PX_PER_MM;
+ break;
+ case U_MM_HIMETRIC: // 1 LU = 0.01 mm
+ d->ydir = -1.0;
+ device_scale = 0.01 * PX_PER_MM;
+ break;
+ case U_MM_LOENGLISH: // 1 LU = 0.1 in
+ d->ydir = -1.0;
+ device_scale = 0.1 * PX_PER_IN;
+ break;
+ case U_MM_HIENGLISH: // 1 LU = 0.01 in
+ d->ydir = -1.0;
+ device_scale = 0.01 * PX_PER_IN;
+ break;
+ case U_MM_TWIPS: // 1 LU = 1/1440 in
+ d->ydir = -1.0;
+ device_scale = (1.0/1440.0) * PX_PER_IN;
+ break;
+ case U_MM_ISOTROPIC: // let scaleX etc. handle it, as set by SETVIEWPORTEXTEX and SETWINDOWEXTEX
+ break;
+ case U_MM_ANISOTROPIC:
+ break;
+ }
+ break;
+ }
case U_EMR_SETBKMODE: dbg_str << "<!-- U_EMR_SETBKMODE -->\n"; break;
case U_EMR_SETPOLYFILLMODE:
{
@@ -2540,20 +2660,27 @@ std::cout << "BEFORE DRAW"
dbg_str << "<!-- U_EMR_BITBLT -->\n";
PU_EMRBITBLT pEmr = (PU_EMRBITBLT) lpEMFR;
- double l = pix_to_x_point( d, pEmr->Dest.x, pEmr->Dest.y);
- double t = pix_to_y_point( d, pEmr->Dest.x, pEmr->Dest.y);
- double r = pix_to_x_point( d, pEmr->Dest.x + pEmr->cDest.x, pEmr->Dest.y + pEmr->cDest.y);
- double b = pix_to_y_point( d, pEmr->Dest.x + pEmr->cDest.x, pEmr->Dest.y + pEmr->cDest.y);
+ double dl = pix_to_x_point( d, pEmr->Dest.x, pEmr->Dest.y);
+ double dt = pix_to_y_point( d, pEmr->Dest.x, pEmr->Dest.y);
+ double dr = pix_to_x_point( d, pEmr->Dest.x + pEmr->cDest.x, pEmr->Dest.y + pEmr->cDest.y);
+ double db = pix_to_y_point( d, pEmr->Dest.x + pEmr->cDest.x, pEmr->Dest.y + pEmr->cDest.y);
+ //source position within the bitmap, in pixels
+ int sl = pEmr->Src.x + pEmr->xformSrc.eDx;
+ int st = pEmr->Src.y + pEmr->xformSrc.eDy;
+ int sw = 0; // extract all of the image
+ int sh = 0;
+ if(sl<0)sl=0;
+ if(st<0)st=0;
// Treat all nonImage bitblts as a rectangular write. Definitely not correct, but at
// least it leaves objects where the operations should have been.
if (!pEmr->cbBmiSrc) {
// should be an application of a DIBPATTERNBRUSHPT, use a solid color instead
SVGOStringStream tmp_rectangle;
- tmp_rectangle << "\n\tM " << l << " " << t << " ";
- tmp_rectangle << "\n\tL " << r << " " << t << " ";
- tmp_rectangle << "\n\tL " << r << " " << b << " ";
- tmp_rectangle << "\n\tL " << l << " " << b << " ";
+ tmp_rectangle << "\n\tM " << dl << " " << dt << " ";
+ tmp_rectangle << "\n\tL " << dr << " " << dt << " ";
+ tmp_rectangle << "\n\tL " << dr << " " << db << " ";
+ tmp_rectangle << "\n\tL " << dl << " " << db << " ";
tmp_rectangle << "\n\tz";
d->mask |= emr_mask;
@@ -2563,7 +2690,7 @@ std::cout << "BEFORE DRAW"
tmp_path << tmp_rectangle.str().c_str();
}
else {
- common_image_extraction(d,pEmr,l,t,r,b,
+ common_image_extraction(d,pEmr,dl,dt,dr,db,sl,st,sw,sh,
pEmr->iUsageSrc, pEmr->offBitsSrc, pEmr->cbBitsSrc, pEmr->offBmiSrc, pEmr->cbBmiSrc);
}
break;
@@ -2574,11 +2701,18 @@ std::cout << "BEFORE DRAW"
PU_EMRSTRETCHBLT pEmr = (PU_EMRSTRETCHBLT) lpEMFR;
// Always grab image, ignore modes.
if (pEmr->cbBmiSrc) {
- double l = pix_to_x_point( d, pEmr->Dest.x, pEmr->Dest.y);
- double t = pix_to_y_point( d, pEmr->Dest.x, pEmr->Dest.y);
- double r = pix_to_x_point( d, pEmr->Dest.x + pEmr->cDest.x, pEmr->Dest.y + pEmr->cDest.y);
- double b = pix_to_y_point( d, pEmr->Dest.x + pEmr->cDest.x, pEmr->Dest.y + pEmr->cDest.y);
- common_image_extraction(d,pEmr,l,t,r,b,
+ double dl = pix_to_x_point( d, pEmr->Dest.x, pEmr->Dest.y);
+ double dt = pix_to_y_point( d, pEmr->Dest.x, pEmr->Dest.y);
+ double dr = pix_to_x_point( d, pEmr->Dest.x + pEmr->cDest.x, pEmr->Dest.y + pEmr->cDest.y);
+ double db = pix_to_y_point( d, pEmr->Dest.x + pEmr->cDest.x, pEmr->Dest.y + pEmr->cDest.y);
+ //source position within the bitmap, in pixels
+ int sl = pEmr->Src.x + pEmr->xformSrc.eDx;
+ int st = pEmr->Src.y + pEmr->xformSrc.eDy;
+ int sw = pEmr->cSrc.x; // extract the specified amount of the image
+ int sh = pEmr->cSrc.y;
+ if(sl<0)sl=0;
+ if(st<0)st=0;
+ common_image_extraction(d,pEmr,dl,dt,dr,db,sl,st,sw,sh,
pEmr->iUsageSrc, pEmr->offBitsSrc, pEmr->cbBitsSrc, pEmr->offBmiSrc, pEmr->cbBmiSrc);
}
break;
@@ -2589,11 +2723,17 @@ std::cout << "BEFORE DRAW"
PU_EMRMASKBLT pEmr = (PU_EMRMASKBLT) lpEMFR;
// Always grab image, ignore masks and modes.
if (pEmr->cbBmiSrc) {
- double l = pix_to_x_point( d, pEmr->Dest.x, pEmr->Dest.y);
- double t = pix_to_y_point( d, pEmr->Dest.x, pEmr->Dest.y);
- double r = pix_to_x_point( d, pEmr->Dest.x + pEmr->cDest.x, pEmr->Dest.y + pEmr->cDest.y);
- double b = pix_to_y_point( d, pEmr->Dest.x + pEmr->cDest.x, pEmr->Dest.y + pEmr->cDest.y);
- common_image_extraction(d,pEmr,l,t,r,b,
+ double dl = pix_to_x_point( d, pEmr->Dest.x, pEmr->Dest.y);
+ double dt = pix_to_y_point( d, pEmr->Dest.x, pEmr->Dest.y);
+ double dr = pix_to_x_point( d, pEmr->Dest.x + pEmr->cDest.x, pEmr->Dest.y + pEmr->cDest.y);
+ double db = pix_to_y_point( d, pEmr->Dest.x + pEmr->cDest.x, pEmr->Dest.y + pEmr->cDest.y);
+ int sl = pEmr->Src.x + pEmr->xformSrc.eDx; //source position within the bitmap, in pixels
+ int st = pEmr->Src.y + pEmr->xformSrc.eDy;
+ int sw = 0; // extract all of the image
+ int sh = 0;
+ if(sl<0)sl=0;
+ if(st<0)st=0;
+ common_image_extraction(d,pEmr,dl,dt,dr,db,sl,st,sw,sh,
pEmr->iUsageSrc, pEmr->offBitsSrc, pEmr->cbBitsSrc, pEmr->offBmiSrc, pEmr->cbBmiSrc);
}
break;
@@ -2609,11 +2749,17 @@ std::cout << "BEFORE DRAW"
// user can sort out transparency later using Gimp, if need be.
PU_EMRSTRETCHDIBITS pEmr = (PU_EMRSTRETCHDIBITS) lpEMFR;
- double l = pix_to_x_point( d, pEmr->Dest.x, pEmr->Dest.y );
- double t = pix_to_y_point( d, pEmr->Dest.x, pEmr->Dest.y );
- double r = pix_to_x_point( d, pEmr->Dest.x + pEmr->cDest.x, pEmr->Dest.y + pEmr->cDest.y );
- double b = pix_to_y_point( d, pEmr->Dest.x + pEmr->cDest.x, pEmr->Dest.y + pEmr->cDest.y );
- common_image_extraction(d,pEmr,l,t,r,b,
+ double dl = pix_to_x_point( d, pEmr->Dest.x, pEmr->Dest.y );
+ double dt = pix_to_y_point( d, pEmr->Dest.x, pEmr->Dest.y );
+ double dr = pix_to_x_point( d, pEmr->Dest.x + pEmr->cDest.x, pEmr->Dest.y + pEmr->cDest.y );
+ double db = pix_to_y_point( d, pEmr->Dest.x + pEmr->cDest.x, pEmr->Dest.y + pEmr->cDest.y );
+ int sl = pEmr->Src.x; //source position within the bitmap, in pixels
+ int st = pEmr->Src.y;
+ int sw = pEmr->cSrc.x; // extract the specified amount of the image
+ int sh = pEmr->cSrc.y;
+ if(sl<0)sl=0;
+ if(st<0)st=0;
+ common_image_extraction(d,pEmr,dl,dt,dr,db,sl,st,sw,sh,
pEmr->iUsageSrc, pEmr->offBitsSrc, pEmr->cbBitsSrc, pEmr->offBmiSrc, pEmr->cbBmiSrc);
dbg_str << "<!-- U_EMR_STRETCHDIBITS -->\n";
diff --git a/src/extension/internal/emf-print.cpp b/src/extension/internal/emf-print.cpp
index e31c727fb..97600a805 100644
--- a/src/extension/internal/emf-print.cpp
+++ b/src/extension/internal/emf-print.cpp
@@ -344,10 +344,10 @@ unsigned int PrintEmf::begin (Inkscape::Extension::Print *mod, SPDocument *doc)
// dwInchesX x dwInchesY in micrometer units, dpi=90 -> 3543.3 dpm
(void) drawing_size((int) ceil(dwInchesX*25.4), (int) ceil(dwInchesY*25.4), 3.543307, &rclBounds, &rclFrame);
- // set up the device as A4 horizontal, 47.244094 dpmm (1200 dpi)
- int MMX = 216;
- int MMY = 279;
- (void) device_size(MMX, MMY, 47.244094, &szlDev, &szlMm); // Drawing: A4 horizontal, 42744 dpm (1200 dpi)
+ // set up the reference device as 100 X A4 horizontal, (1200 dpi/25.4 -> dpmm). Extra digits maintain dpi better in EMF
+ int MMX = 21600;
+ int MMY = 27900;
+ (void) device_size(MMX, MMY, 1200.0/25.4, &szlDev, &szlMm);
int PixelsX = szlDev.cx;
int PixelsY = szlDev.cy;
@@ -381,17 +381,15 @@ unsigned int PrintEmf::begin (Inkscape::Extension::Print *mod, SPDocument *doc)
}
- // Correct for dpi in EMF vs dpi in Inkscape (always 90?)
- // Also correct for the scaling in PX2WORLD, which is set to 20. Doesn't hurt for high resolution,
- // helps prevent rounding errors for low resolution EMF. Low resolution EMF is possible if there
- // are no print devices and the screen resolution is low.
+ // Correct for dpi in EMF (1200) vs dpi in Inkscape (always 90).
+ // Also correct for the scaling in PX2WORLD, which is set to 20.
- worldTransform.eM11 = ((float)PixelsX * 25.4f)/((float)MMX*90.0f*PX2WORLD);
- worldTransform.eM12 = 0.0f;
- worldTransform.eM21 = 0.0f;
- worldTransform.eM22 = ((float)PixelsY * 25.4f)/((float)MMY*90.0f*PX2WORLD);
- worldTransform.eDx = 0;
- worldTransform.eDy = 0;
+ worldTransform.eM11 = 1200./(90.0*PX2WORLD);
+ worldTransform.eM12 = 0.0;
+ worldTransform.eM21 = 0.0;
+ worldTransform.eM22 = 1200./(90.0*PX2WORLD);
+ worldTransform.eDx = 0;
+ worldTransform.eDy = 0;
rec = U_EMRMODIFYWORLDTRANSFORM_set(worldTransform, U_MWT_LEFTMULTIPLY);
if(!rec || emf_append((PU_ENHMETARECORD)rec, et, U_REC_FREE)){
@@ -785,7 +783,7 @@ int PrintEmf::create_pen(SPStyle const *style, const Geom::Affine &transform)
int linecap = 0;
int linejoin = 0;
uint32_t pen;
- uint32_t penStyle;
+ uint32_t brushStyle;
GdkPixbuf *pixbuf;
int hatchType;
U_COLORREF hatchColor;
@@ -803,7 +801,7 @@ int PrintEmf::create_pen(SPStyle const *style, const Geom::Affine &transform)
if (!et) return 0;
// set a default stroke in case we can't figure out a better way to do it
- penStyle = U_BS_SOLID;
+ brushStyle = U_BS_SOLID;
hatchColor = U_RGB(0, 0, 0);
hatchType = U_HS_HORIZONTAL;
@@ -819,7 +817,7 @@ int PrintEmf::create_pen(SPStyle const *style, const Geom::Affine &transform)
height = dheight;
brush_classify(pat,0,&pixbuf,&hatchType,&hatchColor);
if(pixbuf){
- penStyle = U_BS_DIBPATTERN;
+ brushStyle = U_BS_DIBPATTERN;
rgba_px = (char *) gdk_pixbuf_get_pixels(pixbuf); // Do NOT free this!!!
colortype = U_BCBM_COLOR32;
(void) RGBA_to_DIB(&px, &cbPx, &ct, &numCt, rgba_px, width, height, width*4, colortype, 0, 1);
@@ -830,7 +828,7 @@ int PrintEmf::create_pen(SPStyle const *style, const Geom::Affine &transform)
Bmi = bitmapinfo_set(Bmih, ct);
}
else { // pattern
- penStyle = U_BS_HATCHED;
+ brushStyle = U_BS_HATCHED;
if(hatchType == -1){ // Not a standard hatch, so force it to something
hatchType = U_HS_CROSS;
hatchColor = U_RGB(0xFF,0xC3,0xC3);
@@ -838,7 +836,7 @@ int PrintEmf::create_pen(SPStyle const *style, const Geom::Affine &transform)
}
if(FixPPTPatternAsHatch){
if(hatchType == -1){ // image or unclassified
- penStyle = U_BS_HATCHED;
+ brushStyle = U_BS_HATCHED;
hatchType = U_HS_DIAGCROSS;
hatchColor = U_RGB(0xFF,0xC3,0xC3);
}
@@ -886,7 +884,7 @@ int PrintEmf::create_pen(SPStyle const *style, const Geom::Affine &transform)
}
else if(style->stroke.isColor()){ // test last, always seems to be set, even for other types above
sp_color_get_rgb_floatv( &style->stroke.value.color, rgb );
- penStyle = U_BS_SOLID;
+ brushStyle = U_BS_SOLID;
hatchColor = U_RGB(255*rgb[0], 255*rgb[1], 255*rgb[2]);
hatchType = U_HS_SOLIDCLR;
}
@@ -934,7 +932,7 @@ int PrintEmf::create_pen(SPStyle const *style, const Geom::Affine &transform)
style->stroke_dash.dash )
{
if(FixPPTDashLine){ // will break up line into many smaller lines. Override gradient if that was set, cannot do both.
- penStyle = U_BS_SOLID;
+ brushStyle = U_BS_SOLID;
hatchType = U_HS_HORIZONTAL;
}
else {
@@ -959,7 +957,7 @@ int PrintEmf::create_pen(SPStyle const *style, const Geom::Affine &transform)
elp = extlogpen_set(
U_PS_GEOMETRIC | linestyle | linecap | linejoin,
linewidth,
- penStyle,
+ brushStyle,
hatchColor,
hatchType,
n_dash,
diff --git a/src/extension/internal/uemf.c b/src/extension/internal/uemf.c
index a39c6ad6a..df2739d07 100644
--- a/src/extension/internal/uemf.c
+++ b/src/extension/internal/uemf.c
@@ -15,7 +15,7 @@
/*
File: uemf.c
Version: 0.0.9
-Date: 04-OCT-2012
+Date: 24-OCT-2012
Author: David Mathog, Biology Division, Caltech
email: mathog@caltech.edu
Copyright: 2012 David Mathog and California Institute of Technology (Caltech)
@@ -472,7 +472,8 @@ char *U_Utf16leToUtf8(
size_t max,
size_t *len
){
- char *dst, *dst2, *ret;
+ char *dst, *dst2;
+ char *ret=NULL;
size_t srclen,dstlen,status;
if(max){ srclen = 2*max; }
else { srclen = 2*(1 +wchar16len(src)); } //include terminator, length in BYTES
@@ -482,10 +483,11 @@ char *U_Utf16leToUtf8(
iconv_t conv = iconv_open("UTF-8", "UTF-16LE");
status = iconv(conv, ICONV_CAST &src, &srclen, &dst, &dstlen);
iconv_close(conv);
- if(status == (size_t) -1)return(NULL);
- if(len)*len=strlen(dst2);
- ret=U_strdup(dst2); // make a string of exactly the right size
- free(dst2); // free the one which was probably too big
+ if(status != (size_t) -1){
+ if(len)*len=strlen(dst2);
+ ret=U_strdup(dst2); // make a string of exactly the right size
+ }
+ free(dst2); // free the one which was probably too big
return(ret);
}
@@ -1074,11 +1076,15 @@ int get_DIB_params(
\param ct DIB color table
\param numCt DIB color table number of entries
\param rgba_px U_RGBA pixel array (32 bits), created by this routine, caller must free.
- \param w Width of pixel array
- \param h Height of pixel array
+ \param w Width of pixel array in the record
+ \param h Height of pixel array in the record
\param colortype DIB BitCount Enumeration
\param use_ct Kept for symmetry with RGBA_to_DIB, should be set to numCt
\param invert If DIB rows are in opposite order from RGBA rows
+ \param sl start left position in the pixel array in the record to start extracting
+ \param st start top position in the pixel array in the record to start extracting
+ \param ew Width of pixel array to extract
+ \param eh Height of pixel array to extract
*/
int DIB_to_RGBA(
char *px,
@@ -1089,7 +1095,11 @@ int DIB_to_RGBA(
int h,
uint32_t colortype,
int use_ct,
- int invert
+ int invert,
+ int sl,
+ int st,
+ int ew,
+ int eh
){
uint32_t cbRgba_px;
int stride;
@@ -1103,6 +1113,7 @@ int DIB_to_RGBA(
int usedbytes;
U_RGBQUAD color;
int32_t index;
+ int ilow,ihigh,rok; // For figuring out OK row when not entire array is converted
// sanity checking
if(!w || !h || !colortype || !px)return(1);
@@ -1110,8 +1121,8 @@ int DIB_to_RGBA(
if(!use_ct && colortype < U_BCBM_COLOR16)return(3); //color tables mandatory for < 16 bit
if(use_ct && !numCt)return(4); //color table not adequately described
- stride = w * 4;
- cbRgba_px = stride * h;
+ stride = ew * 4;
+ cbRgba_px = stride * eh;
bs = colortype/8;
if(bs<1){
bs=1;
@@ -1121,24 +1132,30 @@ int DIB_to_RGBA(
usedbytes = w*bs;
}
pad = UP4(usedbytes) - usedbytes; // DIB rows must be aligned on 4 byte boundaries, they are padded at the end to accomplish this.;
- *rgba_px = (char *) malloc(cbRgba_px);
+ *rgba_px = (char *) malloc(cbRgba_px);
if(!rgba_px)return(4);
if(invert){
istart = h-1;
iend = -1;
iinc = -1;
+ ihigh = istart - st;
+ ilow = ihigh - eh + 1;
}
else {
istart = 0;
iend = h;
iinc = 1;
+ ilow = st;
+ ihigh = st + eh -1;
}
pxptr = px;
tmp8 = 0; // silences a compiler warning, tmp8 always sets when j=0, so never used uninitialized
for(i=istart; i!=iend; i+=iinc){
- rptr= *rgba_px + i*stride;
+ if(i>=ilow && i<=ihigh){ rok=1; }
+ else { rok=0; }
+ rptr= *rgba_px + (i-ilow)*stride;
for(j=0; j<w; j++){
if(use_ct){
switch(colortype){
@@ -1203,10 +1220,12 @@ int DIB_to_RGBA(
return(7); // This should not be possible, but might happen with memory corruption
}
}
- *rptr++ = r;
- *rptr++ = g;
- *rptr++ = b;
- *rptr++ = a;
+ if(rok && j>=sl && j<=sl+ew-1){
+ *rptr++ = r;
+ *rptr++ = g;
+ *rptr++ = b;
+ *rptr++ = a;
+ }
}
for(j=0; j<pad; j++){ pxptr++; } // DIB rows are all 4 byte aligned
}
@@ -1605,6 +1624,7 @@ int device_size(
\brief Set up fields for an EMR_HEADER for drawing by physical size in mm and dots per millimeter.
Technically rclBounds is supposed to be the extent of the drawing within the EMF, but libUEMF has no way
of knowing this since it never actually draws anything. Instead this is set to the full drawing size.
+ Coordinates are inclusive inclusive, so 297 -> 0,29699.
\return 0 for success, >=1 for failure.
\param xmm Drawing width in millimeters
\param ymm Drawing height in millimeters
@@ -1622,12 +1642,12 @@ int drawing_size(
if(xmm < 0 || ymm < 0 || dpmm < 0)return(1);
rclBounds->left = 0;
rclBounds->top = 0;
- rclBounds->right = U_ROUND((float) xmm * dpmm); // because coordinate system is 0,0 in upper left, N,M in lower right
- rclBounds->bottom = U_ROUND((float) ymm * dpmm);
+ rclBounds->right = U_ROUND((float) xmm * dpmm) - 1; // because coordinate system is 0,0 in upper left, N,M in lower right
+ rclBounds->bottom = U_ROUND((float) ymm * dpmm) - 1;
rclFrame->left = 0;
rclFrame->top = 0;
- rclFrame->right = U_ROUND((float) xmm * 100.);
- rclFrame->bottom = U_ROUND((float) ymm * 100.);
+ rclFrame->right = U_ROUND((float) xmm * 100.) - 1;
+ rclFrame->bottom = U_ROUND((float) ymm * 100.) - 1;
return(0);
}
diff --git a/src/extension/internal/uemf.h b/src/extension/internal/uemf.h
index 30ed611d6..821827a6d 100644
--- a/src/extension/internal/uemf.h
+++ b/src/extension/internal/uemf.h
@@ -14,7 +14,7 @@
/*
File: uemf.h
Version: 0.0.9
-Date: 04-OCT-2012
+Date: 24-OCT-2012
Author: David Mathog, Biology Division, Caltech
email: mathog@caltech.edu
Copyright: 2012 David Mathog and California Institute of Technology (Caltech)
@@ -2701,8 +2701,9 @@ int get_DIB_params( void *pEmr, uint32_t offBitsSrc, uint32_t offBmiSrc,
char **px, PU_RGBQUAD *ct, uint32_t *numCt,
uint32_t *width, uint32_t *height, uint32_t *colortype, uint32_t *invert );
int DIB_to_RGBA(char *px, PU_RGBQUAD ct, int numCt,
- char **rgba_px, int w, int h, uint32_t colortype, int use_ct, int invert);
-
+ char **rgba_px, int w, int h, uint32_t colortype, int use_ct, int invert,
+ int sl, int st, int ew, int eh );
+
int device_size(const int xmm, const int ymm, const float dpmm, U_SIZEL *szlDev, U_SIZEL *szlMm);
int drawing_size(const int xmm, const int yum, const float dpmm, U_RECTL *rclBounds, U_RECTL *rclFrame);
diff --git a/src/extension/internal/uemf_endian.c b/src/extension/internal/uemf_endian.c
index d1563fc82..4fae7f7d4 100644
--- a/src/extension/internal/uemf_endian.c
+++ b/src/extension/internal/uemf_endian.c
@@ -18,7 +18,7 @@
/*
File: uemf_endian.h
Version: 0.0.9
-Date: 27-SEP-2012
+Date: 19-SEP-2012
Author: David Mathog, Biology Division, Caltech
email: mathog@caltech.edu
Copyright: 2012 David Mathog and California Institute of Technology (Caltech)
@@ -642,24 +642,52 @@ void U_EMRNOTIMPLEMENTED_swap(char *record, int torev){
// U_EMRHEADER 1
void U_EMRHEADER_swap(char *record, int torev){
+ int nDesc,offDesc,nSize,cbPix,offPix;
+ PU_EMRHEADER pEmr = (PU_EMRHEADER)(record);
+ if(torev){
+ nSize = pEmr->emr.nSize;
+ }
core5_swap(record, torev);
+ if(!torev){
+ nSize = pEmr->emr.nSize;
+ }
- PU_EMRHEADER pEmr = (PU_EMRHEADER)(record);
rectl_swap(&(pEmr->rclBounds),2); // rclBounds rclFrame
U_swap4(&(pEmr->dSignature), 4); // dSignature nVersion nBytes nRecords
U_swap2(&(pEmr->nHandles), 2); // nHandlessReserved
+ if(torev){
+ nDesc = pEmr->nDescription;
+ offDesc = pEmr->offDescription;
+ }
U_swap4(&(pEmr->nDescription), 3); // nDescription offDescription nPalEntries
+ if(!torev){
+ nDesc = pEmr->nDescription;
+ offDesc = pEmr->offDescription;
+ }
// UTF16-LE Description
sizel_swap(&(pEmr->szlDevice), 2); // szlDevice szlMillimeters
- if(torev && pEmr->cbPixelFormat){
- pixelformatdescriptor_swap( (PU_PIXELFORMATDESCRIPTOR) (record + pEmr->offPixelFormat));
- }
- U_swap4(&(pEmr->cbPixelFormat), 2); // cbPixelFormat offPixelFormat
- if(!torev && pEmr->cbPixelFormat){
- pixelformatdescriptor_swap( (PU_PIXELFORMATDESCRIPTOR) (record + pEmr->offPixelFormat));
+ if((nDesc && (offDesc >= 100)) ||
+ (!offDesc && nSize >= 100)
+ ){
+ if(torev){
+ cbPix = pEmr->cbPixelFormat;
+ offPix = pEmr->offPixelFormat;
+ if(cbPix)pixelformatdescriptor_swap( (PU_PIXELFORMATDESCRIPTOR) (record + pEmr->offPixelFormat));
+ }
+ U_swap4(&(pEmr->cbPixelFormat), 2); // cbPixelFormat offPixelFormat
+ if(!torev){
+ cbPix = pEmr->cbPixelFormat;
+ offPix = pEmr->offPixelFormat;
+ if(cbPix)pixelformatdescriptor_swap( (PU_PIXELFORMATDESCRIPTOR) (record + pEmr->offPixelFormat));
+ }
+ U_swap4(&(pEmr->bOpenGL), 1); // bOpenGL
+ if((nDesc && (offDesc >= 108)) ||
+ (cbPix && (offPix >=108)) ||
+ (!offDesc && !cbPix && nSize >= 108)
+ ){
+ sizel_swap(&(pEmr->szlMicrometers), 1); // szlMicrometers
+ }
}
- U_swap4(&(pEmr->bOpenGL), 1); // bOpenGL
- sizel_swap(&(pEmr->szlMicrometers), 1); // szlMicrometers
}
// U_EMRPOLYBEZIER 2
diff --git a/src/extension/internal/uemf_print.c b/src/extension/internal/uemf_print.c
index d877c01db..3533090e0 100644
--- a/src/extension/internal/uemf_print.c
+++ b/src/extension/internal/uemf_print.c
@@ -5,7 +5,7 @@
/*
File: uemf_print.c
Version: 0.0.9
-Date: 19-SEP-2012
+Date: 19-OCT-2012
Author: David Mathog, Biology Division, Caltech
email: mathog@caltech.edu
Copyright: 2012 David Mathog and California Institute of Technology (Caltech)
@@ -860,15 +860,24 @@ void U_EMRHEADER_print(char *contents, int recnum, size_t off){
printf(" nPalEntries: %d\n", pEmr->nPalEntries );
printf(" szlDevice: {%d,%d} \n", pEmr->szlDevice.cx,pEmr->szlDevice.cy);
printf(" szlMillimeters: {%d,%d} \n", pEmr->szlMillimeters.cx,pEmr->szlMillimeters.cy);
- printf(" cbPixelFormat: %d\n", pEmr->cbPixelFormat );
- printf(" offPixelFormat: %d\n", pEmr->offPixelFormat);
- if(pEmr->cbPixelFormat){
- printf(" PFD:");
- pixelformatdescriptor_print( *(PU_PIXELFORMATDESCRIPTOR) (contents + off + pEmr->offPixelFormat));
- printf("\n");
+ if((pEmr->nDescription && (pEmr->offDescription >= 100)) ||
+ (!pEmr->offDescription && pEmr->emr.nSize >= 100)
+ ){
+ printf(" cbPixelFormat: %d\n", pEmr->cbPixelFormat );
+ printf(" offPixelFormat: %d\n", pEmr->offPixelFormat);
+ if(pEmr->cbPixelFormat){
+ printf(" PFD:");
+ pixelformatdescriptor_print( *(PU_PIXELFORMATDESCRIPTOR) (contents + off + pEmr->offPixelFormat));
+ printf("\n");
+ }
+ printf(" bOpenGL: %d\n",pEmr->bOpenGL );
+ if((pEmr->nDescription && (pEmr->offDescription >= 108)) ||
+ (pEmr->cbPixelFormat && (pEmr->offPixelFormat >=108)) ||
+ (!pEmr->offDescription && !pEmr->cbPixelFormat && pEmr->emr.nSize >= 108)
+ ){
+ printf(" szlMicrometers: {%d,%d} \n", pEmr->szlMicrometers.cx,pEmr->szlMicrometers.cy);
+ }
}
- printf(" bOpenGL: %d\n",pEmr->bOpenGL );
- printf(" szlMicrometers: {%d,%d} \n", pEmr->szlMicrometers.cx,pEmr->szlMicrometers.cy);
}
// U_EMRPOLYBEZIER 2