EMF SetMiterLimit issues
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
Inkscape |
Fix Released
|
Low
|
David Mathog |
Bug Description
There are a couple of problems with miter limits and EMF files.
1. SetMiterLimit, at least the one in mingw on XP accepts the miter limit as a float but actually saves it as 32 bit int.
This is inconsistent with Microsoft's documentation, which says it should be saved as a float. I need to find some other
graphics programs that support miter limit (neither PPT nor Xara does) to see what they do about this issue.
2. Inkscape is doing some odd scaling of the miter limit value. The miter limit is a dimensionless ratio, yet it currently goes through some scaling as if it was in PX or PT units. So that the internal value of 5 is sent to SetMiterLimit as 250. The
250 is then scaled back when read in by Inkscape (but won't be by any other program that reads the EMF).
3. When reading in the EMF the miter limit is subjected to a lower limit test: if <1 then 4. That is illogical. This may have
been an earlier attempt to work around (1), where reading in a small int as a float results in a value very close to zero.
The suggested change is to use 2 as a hard lower limit. This is large enough so that right angles are mitered and small enough so that more acute angles may not be, if that is what an artist intends. The lower limit cannot be 1 because then
right angles could never be mitered (1 < sqrt(2)), and because of issue (1), the limit must be an integer. So 2.
Suggested changes to fix/work around these issues:
in emf-win32-print.cpp create_pen method change the section starting with the next line to:
if (linejoin == PS_JOIN_MITER) {
float oldmiterlimit;
float miterlimit = style->
}
in emf-win32-inout.cpp myEnhMetaFileProc function change the section starting with the next line to:
case EMR_SETMITERLIMIT:
{
dbg_str << "<!-- EMR_SETMITERLIMIT -->\n";
//BUG in SetMiterLimit() on mingw, possibly in underlying Windows(at least on XP?)
//The function takes a float but saves a 32 bit int in the EMR_SETMITERLIMIT record.
float miterlimit = *((int32_t *) &(pEmr-
if (d->dc[
break;
Related branches
tags: | added: emf exporting win32 |
tags: | added: importing |
Changed in inkscape: | |
importance: | Undecided → Low |
assignee: | nobody → David Mathog (mathog) |
milestone: | none → 0.49 |
Changed in inkscape: | |
status: | Fix Committed → Fix Released |
Regarding issue (1) attached is rect2.emf, produced by Adobe Illustrator (11, I think) on a Mac. It too has the miter limit stored as an integer. Amazingly, for such a simple file (two rectangular paths with different miter limits) it also crashes Inkscape, but that happens some time after it hits EMR_EOF, and debug statements at the miter read section showed that
that data was correctly read. The points also seemed to be read correctly, kind of mysterious why it crashes.