Hi,<br><br>I have recently experienced an interesting behavior of the 'cairo_restore()' function. It doesn't restore the cairo context saved by 'cairo_save()' if an error occurs when executing windows gdi functions.<br>
<br>When I used these two functions I assumed that they must provide a transaction like functionality: 'cairo_save()' saves the cairo context while 'cairo_restore()' would restore it even if an error would occur by executing cairo functions between. But this is not the case. If a cairo function fail to execute between, by failing one of the windows gdi function, then 'cairo_restore()' will not restore the previously saved context. <br>
I have experienced such situation for the application I'm working on it. For an unknown reason sometime some windows gdi functions (CreateCompatibleDC(), BitBlt() and other) fail to execute with error code 6 and 8. In this situation the cairo function responsible with that windows gdi function call will set the error status to CAIRO_STATUS_NO_MEMORY and the 'cairo_restore()' will not restore the cairo context. I have noticed that cairo context actually has not been damaged by the failure of the windows gdi function, yet the context is not restored.<br>
Also the cairo documentation doesn't mention that 'cairo_restore()' will not restore the context if an error occurs in a cairo function between 'cairo_save()' and 'cairo_restore()'.<br><br>I would like to propose a change in the 'cairo_restore()' implementation, such that:<br>
a) will restore the previously saved context by 'cairo_save()' even if in an error occurs<br> b) will return as result the error code generated by any cairo function executed between 'cairo_save()' and 'cairo_restore()'<br>
c) will reset the error status to CAIRO_STATUS_SUCCESS so that any next execution of 'cairo_save()' and 'cairo_restore()' will not exit because of a previous status set to an error code.<br><br>The function would be something like:<br>
<br>int<br>cairo_restore (cairo_t *cr)<br>{<br>...<br>int result = CAIRO_STATUS_SUCESS;<br>if (cr->status != CAIRO_STATUS_SUCCESS)<br>{<br> result = cr->status;<br> cr->status = CAIRO_STATUS_SUCCESS;<br> if ((cr->gstate) && (cr->gstate->target))<br>
{<br> cr->gstate->target->status = CAIRO_STATUS_SUCCESS;<br> }<br>}<br>// if (cr->status)<br>// return;<br>...<br>return result;<br>}<br><br><br>Best regards,<br>Iosif Haidu<br><br>