To answer my own questions:<br><br>In order to use cairo_image_surface_create_for_data(), the caller can provide an ARGB buffer with a stride that is either 1) aligned perfectly on (width X 4), or 2) aligned with a stride computed using cairo_format_stride_for_width().&nbsp; In the case of 2, it is the end of the row that should be padded with nothingness.<br>
<br>Also, special care must be taken if the code is expected to run on multiple platforms since the ARGB buffer is required to be in native endian format.&nbsp; (imho, this is something that should be shielded from the caller, but there you go.)<br>
<br>So, to fill an ARGB buffer suitable for use in cairo_image_surface_create_for_data(), the following snippet will do:<br><br><span style="font-family: courier new,monospace;">short int&nbsp;&nbsp;&nbsp; word = 0x0001;<br>char *byte = (char *) &amp;word;<br>
width = 550;</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">height = 425;</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">stride = cairo_image_surface_create_for_data(CAIRO_FORMAT_ARGB24, width)</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">rgbbuf = calloc(stride * h, sizeof(char));</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> pos = rgbbuf;</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">for(i=0;i&lt;height;i++)</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">{<br>&nbsp; A = (some computed alpha_value);<br>
&nbsp; R = (</span><span style="font-family: courier new,monospace;">some computed </span><span style="font-family: courier new,monospace;">red_value);<br>&nbsp; B = </span><span style="font-family: courier new,monospace;">(some computed </span><span style="font-family: courier new,monospace;">blue_value);<br>
&nbsp; G = </span><span style="font-family: courier new,monospace;">(some computed </span><span style="font-family: courier new,monospace;">green_value);<br style="font-family: courier new,monospace;"></span><span style="font-family: courier new,monospace;">&nbsp; colorProb = colorP((float) PIX2USERY(&amp;grL, i));</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">&nbsp; for(j=0;j&lt;width;j++)</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">&nbsp; {&nbsp;&nbsp;&nbsp; //&nbsp;&nbsp;&nbsp; &nbsp; ENDIANTEST ? LITTLE&nbsp; : BIG</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">&nbsp; &nbsp;&nbsp;&nbsp; *pos++ = (byte[0])&nbsp; ? B &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : A;</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">&nbsp; &nbsp;&nbsp;&nbsp; *pos++ = (</span><span style="font-family: courier new,monospace;">byte[0])</span><span style="font-family: courier new,monospace;">&nbsp; ? G &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : R;</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">&nbsp; &nbsp;&nbsp;&nbsp; *pos++ = (</span><span style="font-family: courier new,monospace;">byte[0]</span><span style="font-family: courier new,monospace;">)&nbsp; ? R &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : G;</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">&nbsp; &nbsp;&nbsp;&nbsp; *pos++ = (</span><span style="font-family: courier new,monospace;">byte[0]</span><span style="font-family: courier new,monospace;">)&nbsp; ? A &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : B;</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">&nbsp; }<br></span><span style="font-family: courier new,monospace;">&nbsp; // advance to beginning of next row</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">&nbsp; pos += (stride/4 - width)*4;&nbsp;&nbsp;&nbsp; </span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">}</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">cBar = cairo_image_surface_create_for_data(rgbbuf, CAIRO_FORMAT_RGB24, COLORBW, h, stride);</span><br style="font-family: courier new,monospace;">
<br>What I also found, curiously, was that the following code sequence produced wrong results on LINUX and a crash on MAC:<br><br><span style="font-family: courier new,monospace;">colorBar = cairo_image_surface_create_for_data(rgbbuf,<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CAIRO_FORMAT_RGB24, width, h, stride);</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">free(rgbbuf);</span><br style="font-family: courier new,monospace;">

<span style="font-family: courier new,monospace;">cBar2 = cairo_image_surface_create(CAIRO_FORMAT_RGB24, w, h);</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">cr = cairo_create(cBar2);</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">cairo_set_source_rgb(cr, 1.0, 1.0, 1.0);</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">cairo_paint(cr);</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">cairo_set_source_surface (cr, colorBar, 0, 0);</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">cairo_paint (cr);</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">cairo_surface_destroy (colorBar);</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"></span><br>Playing around, it seems that the rgbbuf used to create colorBar cannot be freed until you&#39;re done with the colorBar surface itself.&nbsp; This is not stated in the documentation, so can cause serious head-scratching.&nbsp; Anyone know why the rgbbuf is required to hang around?<br>
<br>Moving the free() to after cairo_surface_destroy() removed this problem:<br><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">colorBar = cairo_image_surface_create_for_data(rgbbuf,<br>

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CAIRO_FORMAT_RGB24, width, h, stride);</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"></span><span style="font-family: courier new,monospace;">cBar2 = cairo_image_surface_create(CAIRO_FORMAT_RGB24, w, h);</span><br style="font-family: courier new,monospace;">

<span style="font-family: courier new,monospace;">cr = cairo_create(cBar2);</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">cairo_set_source_rgb(cr, 1.0, 1.0, 1.0);</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">cairo_paint(cr);</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">cairo_set_source_surface (cr, colorBar, 0, 0);</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">cairo_paint (cr);</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">cairo_surface_destroy (colorBar);</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"></span><span style="font-family: courier new,monospace;">free(rgbbuf);</span><br style="font-family: courier new,monospace;">


<span style="font-family: courier new,monospace;"><br><span style="font-family: arial,sans-serif;">And one other thing I discovered was that the PangoCairo routines are not thread-safe.&nbsp; Any idea if these are intended to be or will be in a future version?&nbsp; If so, which?<br>
<br>I think the documentation re: providing your own ARGB buffer could be made a little more robust in describing how to properly create an ARGB buffer for Cairo usage.<br><br>Thanks to those who provided pointers, they helped.<br>
<br>cheers,<br><br>richard<br><br></span></span><div class="gmail_quote">On Wed, Apr 9, 2008 at 9:39 AM, richard boaz &lt;<a href="mailto:ivor.boaz@gmail.com">ivor.boaz@gmail.com</a>&gt; wrote:<br><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
Hi,<br><br>I have a problem and a couple of questions related thereto.<br><br>The problem: I am trying to convert a programmatically generated RGB Buffer to a Cairo surface.&nbsp; Up till now, I have used GDK to create all my graphics (since I started before Cairo came to be, and required display within a GUI), but now need to convert to Cairo since I need to generate these PDF plots in the background on a server machine without a display.&nbsp; All fine and good.<br>

<br>Until I try to understand how to convert my gdk_* routines to their cairo equivalents.<br><br>In GDK, once I have created and filled my RGB buffer (3-byte color, RGB), I call:<br><br><font face="arial,sans-serif"><span style="font-family: courier new,monospace;">rgbbuf = malloc(wL * hL * 3);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // RGB Buffer - 3-byte color - RGB<br>


memset(rgbbuf, 240, wL * hL * 3);&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // make the grey background<br>
pdf(rgbbuf, wL, hL, pdfReq, &amp;gr, perB);&nbsp; // make the PDF plot<br>
<br>
</span></font><span style="font-family: courier new,monospace;">gdk_draw_rgb_image (pmap, gc, sideM, topM, wL, hL, GDK_RGB_DITHER_NONE, rgbbuf, wL*3);</span><br><br><font face="arial,sans-serif">After investigating how to do this in Cairo, I came up with this replacement:<br>

<br><span style="font-family: courier new,monospace;">rgbbuf = malloc(wL * hL * 4);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // RGB Buffer - 4-byte color - ARGB<br>memset(rgbbuf, 240, wL * hL * 4);&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // make the grey background<br>pdf(rgbbuf, wL, hL, pdfReq, &amp;gr, perB);</span></font><font face="arial,sans-serif"><span style="font-family: courier new,monospace;">&nbsp; // make the PDF plot</span></font><br>

<font face="arial,sans-serif"><span style="font-family: courier new,monospace;"><br>pdfOut = cairo_image_surface_create_for_data(rgbbuf, CAIRO_FORMAT_RGB24, wL, hL, wL*4);</span><br style="font-family: courier new,monospace;">

<span style="font-family: courier new,monospace;">cairo_set_source_surface (cr, pdfOut, sideM, topM);&nbsp; </span></font><font face="arial,sans-serif"><span style="font-family: courier new,monospace;">// cr is previously created</span></font><font face="arial,sans-serif"><span style="font-family: courier new,monospace;"></span><br style="font-family: courier new,monospace;">

<span style="font-family: courier new,monospace;">cairo_rectangle (cr, sideM, topM, wL, hL);&nbsp; </span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">cairo_fill (cr);</span><br style="font-family: courier new,monospace;">

<span style="font-family: courier new,monospace;">cairo_surface_destroy (pdfOut);</span><br style="font-family: courier new,monospace;"><br>I have modified the RGB buffer size to 4-byte colors (ARGB) and filled it according to the <span style="font-family: courier new,monospace;">cairo_format_t</span> definition for </font><font size="4"><span style="font-family: courier new,monospace;"><code>CAIRO_FORMAT_RGB24<font face="arial,sans-serif">.&nbsp; However, this does not result in a picture that is correct.<br>

<br>My suspicion is that since the row stride is being optimized by Cairo, it does not nicely align on a boundary of width*4.&nbsp; The documentation currently states that in order to obtain the proper stride, the routine<font size="2"> </font></font></code></span></font><font style="font-family: courier new,monospace;" size="2">cairo_format_stride_for_width() <font face="arial,sans-serif">should be used.&nbsp; And also says that this is available since 1.6.<br>

<br>My questions:<br></font></font><ol><li>I do not find a v1.6 of Cairo available from the download site.&nbsp; Is it really true?&nbsp; The documentation preceeds the release of the software itself?&nbsp; (wow...)&nbsp; Or am I missing something?&nbsp; <br>

</li><li>If v1.6 isn&#39;t yet available, how do I get the optimized stride defined internally by Cairo?<br></li><li>Anyway, assuming for the moment this routine existed, how would I use it properly?&nbsp; Meaning, how do I programmatically generate a RGB buffer for display?</li>

</ol>My guess at Q3 would be:<br><ol><li>obtain the row stride using the cairo routine.</li><li>fill my RGB buffer, row by row, keeping track when i&#39;ve hit the stride (computed in 1) to advance to the next proper 4-byte RGB location.</li>

</ol>This is based, however, on too many assumptions:<br><ol><li>I&#39;m assuming that to optimize, Cairo makes the stride bigger (smaller makes no sense to me) than simply width*4 bytes.</li><li>Every row is guaranteed to be the same?&nbsp; Including the last?<br>

</li><li>Where are the empty bytes placed?&nbsp; at the end of the row or at the beginning?&nbsp; <br></li><li>Is the stride always a multiple of 4?<br></li></ol>More generally, it seems that programmatically generating a RGB buffer for conversion to a Cairo surface is not obvious (to me, yet).&nbsp; Am I wrong about this?&nbsp; Is there a more straightforward way of doing this I haven&#39;t yet teased from the documentation?&nbsp; Is there a different way of accessing the individual pixels of an RGB buffer I am unaware of that would allow me to fill them up individually without having to make wrong assumptions and guesses?<br>

<br>Any information to help me out of my pickle would be greatly appreciated.<br><br>regards,<br><font color="#888888"><br>richard<br>
</font></blockquote></div><br>