<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<style type="text/css" style="display:none;"> P {margin-top:0;margin-bottom:0;} </style>
</head>
<body dir="ltr">
<div style="font-family: Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
<span style="margin:0px;font-size:12pt;color:rgb(0, 0, 0) !important;background-color:rgb(255, 255, 255)">There is a vertical banding issue when using cairo_paint_with_alpha() in windows libcairo v1.17.4. It is worse in ARGB32 than in RGBA128F. I found no issues
 on a Mac. If it matters, I used the vcpkg cairo build, as that seems to be the best way to access the latest cairo builds on windows.</span>
<div style="margin:0px;font-size:12pt;color:rgb(0, 0, 0) !important;background-color:rgb(255, 255, 255)">
<br>
</div>
<div style="margin:0px;font-size:12pt;color:rgb(0, 0, 0) !important;background-color:rgb(255, 255, 255)">
For opacity 1.0, (which internally uses cairo_paint() - there is no issue).</div>
<div style="margin:0px;font-size:12pt;color:rgb(0, 0, 0) !important;background-color:rgb(255, 255, 255)">
<br>
</div>
<div style="margin:0px;font-size:12pt;color:rgb(0, 0, 0) !important;background-color:rgb(255, 255, 255)">
For ARGB32, it is an issue in blend modes - color burn, color dodge, soft light, hue, saturation, color, luminosity. For RGBA128F, it is an issue in most blending modes.</div>
<div style="margin:0px;font-size:12pt;color:rgb(0, 0, 0) !important;background-color:rgb(255, 255, 255)">
<br>
</div>
<div style="margin:0px;font-size:12pt;color:rgb(0, 0, 0) !important;background-color:rgb(255, 255, 255)">
This seems to appear with scale and shear operators.</div>
<div style="margin:0px;font-size:12pt;color:rgb(0, 0, 0) !important;background-color:rgb(255, 255, 255)">
<br>
</div>
<div style="margin:0px;font-size:12pt;color:rgb(0, 0, 0) !important;background-color:rgb(255, 255, 255)">
>>> Sample Code >>></div>
<div style="margin:0px;font-size:12pt;color:rgb(0, 0, 0) !important;background-color:rgb(255, 255, 255)">
<br>
</div>
<div style="margin:0px;font-size:12pt;color:rgb(0, 0, 0) !important;background-color:rgb(255, 255, 255)">
// CAIRO_FORMAT_RGBA128F CAIRO_FORMAT_ARGB32
<div style="margin:0px">#define CAIRO_PIXFMT CAIRO_FORMAT_RGBA128F</div>
</div>
<div style="margin:0px;font-size:12pt;color:rgb(0, 0, 0) !important;background-color:rgb(255, 255, 255)">
<br>
</div>
<div style="margin:0px;font-size:12pt;color:rgb(0, 0, 0) !important;background-color:rgb(255, 255, 255)">
  cairo_t *target_cr=NULL;
<div style="margin:0px">        cairo_surface_t *target;</div>
<div style="margin:0px">       </div>
<div style="margin:0px">        target = cairo_image_surface_create_for_data</div>
<div style="margin:0px">            (fd.target.buf, CAIRO_PIXFMT, fd.target.w, fd.target.h, fd.target.stride);</div>
<div style="margin:0px">       </div>
<div style="margin:0px">        // TBD return some sort of out of mem error</div>
<div style="margin:0px">        if (cairo_surface_status(target)!= CAIRO_STATUS_SUCCESS)</div>
<div style="margin:0px">            return -1;</div>
<div style="margin:0px">       </div>
<div style="margin:0px">        target_cr = cairo_create(target);</div>
<div style="margin:0px">       </div>
<div style="margin:0px">        cairo_t *source_cr=NULL;</div>
<div style="margin:0px">        cairo_surface_t *source;</div>
<div style="margin:0px">       </div>
<div style="margin:0px">        source = cairo_image_surface_create_for_data</div>
<div style="margin:0px">            (fd.source.buf, CAIRO_PIXFMT, fd.source.w, fd.source.h, fd.source.stride);</div>
<div style="margin:0px">       </div>
<div style="margin:0px">        // TBD return some sort of out of mem error</div>
<div style="margin:0px">        if (cairo_surface_status(source)!= CAIRO_STATUS_SUCCESS)</div>
<div style="margin:0px">            return -1;</div>
<div style="margin:0px">       </div>
<div style="margin:0px">        source_cr = cairo_create(source);</div>
<div style="margin:0px"><br>
</div>
<div style="margin:0px">        const double fx = fd.scale.x, fy = fd.scale.y; </div>
<div style="margin:0px">        const double Tx = tan(fd.shear.x), Ty = tan(fd.shear.y); </div>
<div style="margin:0px">        const int64_t cx = fd.center.x, cy = fd.center.y, </div>
<div style="margin:0px">            dx = fd.t.x, dy = fd.t.y; </div>
<div style="margin:0px"><br>
</div>
<div style="margin:0px">        const int64_t centerx = fd.w / 2.0f, centery = fd.h / 2.0f;</div>
<div style="margin:0px"><br>
</div>
<div style="margin:0px">        cairo_matrix_t a, b;</div>
<div style="margin:0px"><br>
</div>
<div style="margin:0px">        cairo_translate(target_cr, cx, cy);        cairo_rotate(target_cr, fd.rotation);</div>
<div style="margin:0px">               cairo_translate(target_cr, -cx, -cy);</div>
<div style="margin:0px"><br>
</div>
<div style="margin:0px"><span style="margin:0px;background-color:rgb(255, 255, 255) !important"><span style="margin:0px;background-color:rgb(255, 255, 255) !important">/******Start scale and shear*******/</span></span></div>
<div style="margin:0px"><br>
</div>
<div style="margin:0px">        cairo_scale(target_cr, fx, fy);<br>
</div>
<div style="margin:0px">       </div>
<div style="margin:0px">// No issues with translation</div>
<div style="margin:0px">        cairo_translate(target_cr, dx, dy);</div>
<div style="margin:0px">       </div>
<div style="margin:0px">        cairo_matrix_init(&a, 1, 0, Tx, 1, 0, 0);<br>
</div>
<div style="margin:0px">        cairo_transform(target_cr, &a);</div>
<div style="margin:0px">       </div>
<div style="margin:0px">        cairo_matrix_init(&b, 1, Ty, 0, 1, 0, 0);<br>
</div>
<div style="margin:0px">        cairo_transform(target_cr, &b);</div>
<div style="margin:0px">       </div>
<div style="margin:0px">        cairo_translate(target_cr, -centerx, -centery);<br>
</div>
<div style="margin:0px"><br>
</div>
<div style="margin:0px">/******End scale and shear*******/</div>
<div style="margin:0px"><br>
</div>
<div style="margin:0px">        cairo_set_operator(target_cr, cairo_op[fd.mode]);</div>
<div style="margin:0px">        cairo_surface_flush(target);</div>
<div style="margin:0px">        cairo_set_source_surface(target_cr, source, (int64_t)fd.origin.x, (int64_t)fd.origin.y);</div>
<div style="margin:0px"><br>
</div>
<div style="margin:0px">        cairo_paint_with_alpha(target_cr, fd.opacity);</div>
<div style="margin:0px">        cairo_surface_flush(target);</div>
<div style="margin:0px"><br>
</div>
<div style="margin:0px">        if (source_cr)</div>
<div style="margin:0px">            cairo_destroy(source_cr);</div>
<div style="margin:0px">        if (source)</div>
<div style="margin:0px">            cairo_surface_destroy(source);</div>
<div style="margin:0px">       </div>
<div style="margin:0px">        if (target_cr)</div>
<div style="margin:0px">            cairo_destroy(target_cr);</div>
<div style="margin:0px">        if (target)</div>
            cairo_surface_destroy(target);</div>
<br>
</div>
</body>
</html>