diff options
author | Graeme Geldenhuys <graeme@mastermaths.co.za> | 2012-03-19 11:58:09 +0200 |
---|---|---|
committer | Graeme Geldenhuys <graeme@mastermaths.co.za> | 2012-03-19 11:58:09 +0200 |
commit | 90ae43f347fe4075f76a5f37d011d39bd4c10ddd (patch) | |
tree | a04fa64e893f21a07ed19704121e626877f4aef6 | |
parent | 88f1fc9acda900eecfcfc884a60e4958145e3fc0 (diff) | |
download | fpGUI-90ae43f347fe4075f76a5f37d011d39bd4c10ddd.tar.xz |
adds AGG docs in general.
These docs give you lots of background information on the working
of the AGG (Anti-Grain Geometry) library and how it works.
Using the knowledge you learn from this, you will be able to extend
the TAgg2D canvas for your own needs and applications.
160 files changed, 8189 insertions, 0 deletions
diff --git a/docs/aggpas/basic_renderers.agdoc.html b/docs/aggpas/basic_renderers.agdoc.html new file mode 100644 index 00000000..29fdfce5 --- /dev/null +++ b/docs/aggpas/basic_renderers.agdoc.html @@ -0,0 +1,1842 @@ +<html><head><title>Anti-Grain Geometry - Basic Renderers</title> +<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> +<link rel="stylesheet" type="text/css" +href="basic_renderers.agdoc_files/agg.css"> +</head><body><a name="PAGE_BASIC_RENDERERS"><b></b></a> + + +<table style="margin: 0px;" height="1px" width="640px" border="0" +cellpadding="0" cellspacing="0"> +<tbody><tr> +<td bgcolor="#583927"></td> +</tr> +</tbody></table> +<table style="margin: 0px;" width="640px" border="0" cellpadding="0" +cellspacing="0"> +<tbody><tr> +<td> +<table style="margin: 0px;" width="170px" border="0" cellpadding="0" +cellspacing="0"> +<tbody><tr><td><a href="http://www.antigrain.com/index.html" +class="mpmenu">Home/</a></td></tr> +<tr><td><a href="http://www.antigrain.com/doc/index.html" class="mpmenu">Table + of Content/</a></td></tr> +<tr><td><a href="" class="mpmenu"></a></td></tr> +<tr><td><a href="" class="mpmenu"></a></td></tr> +<tr><td><a href="" class="mpmenu"></a></td></tr> +<tr><td><a href="" class="mpmenu"></a></td></tr> +</tbody></table> +</td> +<td width="1px" bgcolor="#583927"></td> +<td style="text-align: right;" valign="top" width="450px"> +<table style="margin: 0px;" border="0" cellpadding="0" cellspacing="0"> +<tbody><tr> +<td><img src="basic_renderers.agdoc_files/agg_logo.gif" border="0"></td> +</tr> +<tr> +<td> +<table style="margin: 0px;" border="0" cellpadding="0" cellspacing="0"> +<tbody><tr height="15px"> +<td> <a class="topmenu" +href="http://www.antigrain.com/news/index.html">News</a> </td> +<td width="1px" bgcolor="#8e521d"></td> +<td> <a class="topmenu" +href="http://www.antigrain.com/doc/index.html">Docs</a> </td> +<td width="1px" bgcolor="#8e521d"></td> +<td> <a class="topmenu" +href="http://www.antigrain.com/download/index.html">Download</a> </td> +<td width="1px" bgcolor="#8e521d"></td> +<td> <a class="topmenu" +href="http://www.antigrain.com/maillist/index.html">Mailing List</a> </td> +<td width="1px" bgcolor="#8e521d"></td> +<td> <a class="topmenu" +href="http://www.antigrain.com/cvs/index.html">CVS</a> </td> +</tr> +</tbody></table> +</td> +</tr> +</tbody></table> +</td> +</tr> +</tbody></table> +<table style="margin: 0px;" height="1px" width="640px" bgcolor="#583927" + border="0" cellpadding="0" cellspacing="0"><tbody><tr><td></td></tr></tbody></table> + + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p> +</p></td></tr></tbody></table> + +<table width="640px"><tbody><tr><td><h1>Basic Renderers<span +class="subtitle"><br>Getting Started with Simple Console Applications</span></h1></td></tr></tbody></table> + + +<table class="toc" width="640px"><tbody><tr><td> + <div style="margin-left: 2em; padding: 3px; font-size: 14px;"><a +href="#toc0001"><b>Rendering Buffer</b></a> + <div style="margin-left: 2em; font-size: 12px;"><a +href="#toc0002">The First and the Simplest Example</a></div> + <div style="margin-left: 2em; font-size: 12px;"><a +href="#toc0003">Class rendering_buffer</a></div> + <div style="margin-left: 2em; font-size: 12px;"><a +href="#toc0004">Two Modifications of the Example</a></div></div> + <div style="margin-left: 2em; padding: 3px; font-size: 14px;"><a +href="#toc0005"><b>Pixel Format Renderers</b></a> + <div style="margin-left: 2em; font-size: 12px;"><a +href="#toc0006">Creation</a></div> + <div style="margin-left: 2em; font-size: 12px;"><a +href="#toc0007">Member Functions</a></div> + <div style="margin-left: 2em; font-size: 12px;"><a +href="#toc0008">Alpha-Mask Adaptor</a></div></div> + <div style="margin-left: 2em; padding: 3px; font-size: 14px;"><a +href="#toc0009"><b>Basic Renderers</b></a> + <div style="margin-left: 2em; font-size: 12px;"><a +href="#toc0010">Creation</a></div> + <div style="margin-left: 2em; font-size: 12px;"><a +href="#toc0011">Member Functions</a></div> + <div style="margin-left: 2em; font-size: 12px;"><a +href="#toc0012">A common example</a></div></div> + <div style="margin-left: 2em; padding: 3px; font-size: 14px;"><a +href="#toc0013"><b>Primitives and Markers Renderers</b></a> + <div style="margin-left: 2em; font-size: 12px;"><a +href="#toc0014">Primitives Renderer</a> + <div style="margin-left: 2em; font-size: 12px;"><a +href="#toc0015">Declaration</a></div> + <div style="margin-left: 2em; font-size: 12px;"><a +href="#toc0016">Creation</a></div> + <div style="margin-left: 2em; font-size: 12px;"><a +href="#toc0017">Member functions</a></div></div> + <div style="margin-left: 2em; font-size: 12px;"><a +href="#toc0018">Marker Renderer</a> + <div style="margin-left: 2em; font-size: 12px;"><a +href="#toc0019">Declaration</a></div> + <div style="margin-left: 2em; font-size: 12px;"><a +href="#toc0020">Creation</a></div> + <div style="margin-left: 2em; font-size: 12px;"><a +href="#toc0021">Member Functions</a></div></div></div> + +</td></tr></tbody></table> + +<h2>Rendering Buffer<a name="toc0001"></a></h2> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>Here + we start with creating a frame buffer in memory and writing it to a +file of +the simplest possible raster format. It's <a +href="http://netpbm.sourceforge.net/doc/ppm.html"><img +src="basic_renderers.agdoc_files/link.gif" border="0">PPM (Portable +Pixel Map)</a>. Although, it isn't natively supported by <a +href="http://www.microsoft.com/"><img +src="basic_renderers.agdoc_files/link.gif" border="0"><b>Microsoft</b></a> + Windows, +there are many viewers and converters that can work with it, +for example, <a href="http://www.irfanview.com/"><img +src="basic_renderers.agdoc_files/link.gif" border="0">IrfanView +(www.irfanview.com)</a>. +All <b>AGG</b> console examples use the P6 256 format, that is RGB, one +byte per channel. +We assume that we work with an RGB-buffer in memory organized as +follows:</p></td></tr></tbody></table> + +<table width="640px"><tbody><tr><td><center><img +src="basic_renderers.agdoc_files/pixfmt_rgb24.gif" title="" border="0"><br><i></i></center></td></tr></tbody></table> + +<h3>The First and the Simplest Example<a name="toc0002"></a></h3> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>There + is the first example, it's in <code>agg2/tutorial/t01_rendering_buffer.cpp</code></p></td></tr></tbody></table> + +<table width="640px" border="0" cellpadding="0" cellspacing="0"><tbody><tr><td><pre><span class="kw2">#include</span> <span class="op"><</span>stdio<span class="op">.</span>h<span class="op">></span> +<span class="kw2">#include</span> <span class="op"><</span>string<span class="op">.</span>h<span class="op">></span> +<span class="kw2">#include</span> <span class="str">"<a href="http://www.antigrain.com/__code/include/agg_rendering_buffer.h.html">agg_rendering_buffer.h</a>"</span> + +<span class="kw1">enum</span> +<span class="op">{</span> + frame_width <span class="op">=</span> <span class="num">320</span><span class="op">,</span> + frame_height <span class="op">=</span> <span class="num">200</span> +<span class="op">}</span><span class="op">;</span> + +<span class="rem">// Writing the buffer to a .PPM file, assuming it has </span> +<span class="rem">// RGB-structure, one byte per color component</span> +<span class="rem">//--------------------------------------------------</span> +<span class="kw1">bool</span> write_ppm<span class="op">(</span><span class="kw1">const</span> <span class="kw1">unsigned</span> <span class="kw1">char</span><span class="op">*</span> buf<span class="op">,</span> + <span class="kw1">unsigned</span> width<span class="op">,</span> + <span class="kw1">unsigned</span> height<span class="op">,</span> + <span class="kw1">const</span> <span class="kw1">char</span><span class="op">*</span> file_name<span class="op">)</span> +<span class="op">{</span> + FILE<span class="op">*</span> fd <span class="op">=</span> fopen<span class="op">(</span>file_name<span class="op">,</span> <span class="str">"wb"</span><span class="op">)</span><span class="op">;</span> + <span class="kw1">if</span><span class="op">(</span>fd<span class="op">)</span> + <span class="op">{</span> + fprintf<span class="op">(</span>fd<span class="op">,</span> <span class="str">"P6 %d %d 255 "</span><span class="op">,</span> width<span class="op">,</span> height<span class="op">)</span><span class="op">;</span> + fwrite<span class="op">(</span>buf<span class="op">,</span> <span class="num">1</span><span class="op">,</span> width <span class="op">*</span> height <span class="op">*</span> <span class="num">3</span><span class="op">,</span> fd<span class="op">)</span><span class="op">;</span> + fclose<span class="op">(</span>fd<span class="op">)</span><span class="op">;</span> + <span class="kw1">return</span> <span class="kw1">true</span><span class="op">;</span> + <span class="op">}</span> + <span class="kw1">return</span> <span class="kw1">false</span><span class="op">;</span> +<span class="op">}</span> + +<span class="rem">// Draw a black frame around the rendering buffer, assuming it has </span> +<span class="rem">// RGB-structure, one byte per color component</span> +<span class="rem">//--------------------------------------------------</span> +<span class="kw1">void</span> draw_black_frame<span class="op">(</span>agg::<a href="http://www.antigrain.com/doc/basic_renderers/basic_renderers.agdoc.html#rendering_buffer">rendering_buffer</a><span class="op">&</span> rbuf<span class="op">)</span> +<span class="op">{</span> + <span class="kw1">unsigned</span> i<span class="op">;</span> + <span class="kw1">for</span><span class="op">(</span>i <span class="op">=</span> <span class="num">0</span><span class="op">;</span> i <span class="op"><</span> rbuf<span class="op">.</span>height<span class="op">(</span><span class="op">)</span><span class="op">;</span> <span class="op">++</span>i<span class="op">)</span> + <span class="op">{</span> + <span class="kw1">unsigned</span> <span class="kw1">char</span><span class="op">*</span> p <span class="op">=</span> rbuf<span class="op">.</span>row_ptr<span class="op">(</span>i<span class="op">)</span><span class="op">;</span> + <span class="op">*</span>p<span class="op">++</span> <span class="op">=</span> <span class="num">0</span><span class="op">;</span> <span class="op">*</span>p<span class="op">++</span> <span class="op">=</span> <span class="num">0</span><span class="op">;</span> <span class="op">*</span>p<span class="op">++</span> <span class="op">=</span> <span class="num">0</span><span class="op">;</span> + p <span class="op">+=</span> <span class="op">(</span>rbuf<span class="op">.</span>width<span class="op">(</span><span class="op">)</span> <span class="op">-</span> <span class="num">2</span><span class="op">)</span> <span class="op">*</span> <span class="num">3</span><span class="op">;</span> + <span class="op">*</span>p<span class="op">++</span> <span class="op">=</span> <span class="num">0</span><span class="op">;</span> <span class="op">*</span>p<span class="op">++</span> <span class="op">=</span> <span class="num">0</span><span class="op">;</span> <span class="op">*</span>p<span class="op">++</span> <span class="op">=</span> <span class="num">0</span><span class="op">;</span> + <span class="op">}</span> + memset<span class="op">(</span>rbuf<span class="op">.</span>row_ptr<span class="op">(</span><span class="num">0</span><span class="op">)</span><span class="op">,</span> <span class="num">0</span><span class="op">,</span> rbuf<span class="op">.</span>width<span class="op">(</span><span class="op">)</span> <span class="op">*</span> <span class="num">3</span><span class="op">)</span><span class="op">;</span> + memset<span class="op">(</span>rbuf<span class="op">.</span>row_ptr<span class="op">(</span>rbuf<span class="op">.</span>height<span class="op">(</span><span class="op">)</span> <span class="op">-</span> <span class="num">1</span><span class="op">)</span><span class="op">,</span> <span class="num">0</span><span class="op">,</span> rbuf<span class="op">.</span>width<span class="op">(</span><span class="op">)</span> <span class="op">*</span> <span class="num">3</span><span class="op">)</span><span class="op">;</span> +<span class="op">}</span> + + +<span class="kw1">int</span> <span class="kw1">main</span><span class="op">(</span><span class="op">)</span> +<span class="op">{</span> + <span class="rem">// In the first example we do the following:</span> + <span class="rem">//--------------------</span> + <span class="rem">// Allocate the buffer.</span> + <span class="rem">// Clear the buffer, for now "manually"</span> + <span class="rem">// Create the rendering buffer object</span> + <span class="rem">// Do something simple, draw a diagonal line</span> + <span class="rem">// Write the buffer to agg_test.ppm</span> + <span class="rem">// Free memory</span> + + <span class="kw1">unsigned</span> <span class="kw1">char</span><span class="op">*</span> buffer <span class="op">=</span> <span class="kw1">new</span> <span class="kw1">unsigned</span> <span class="kw1">char</span><span class="op">[</span>frame_width <span class="op">*</span> frame_height <span class="op">*</span> <span class="num">3</span><span class="op">]</span><span class="op">;</span> + + memset<span class="op">(</span>buffer<span class="op">,</span> <span class="num">255</span><span class="op">,</span> frame_width <span class="op">*</span> frame_height <span class="op">*</span> <span class="num">3</span><span class="op">)</span><span class="op">;</span> + + agg::<a href="http://www.antigrain.com/doc/basic_renderers/basic_renderers.agdoc.html#rendering_buffer">rendering_buffer</a> rbuf<span class="op">(</span>buffer<span class="op">,</span> + frame_width<span class="op">,</span> + frame_height<span class="op">,</span> + frame_width <span class="op">*</span> <span class="num">3</span><span class="op">)</span><span class="op">;</span> + + <span class="kw1">unsigned</span> i<span class="op">;</span> + <span class="kw1">for</span><span class="op">(</span>i <span class="op">=</span> <span class="num">0</span><span class="op">;</span> i <span class="op"><</span> rbuf<span class="op">.</span>height<span class="op">(</span><span class="op">)</span><span class="op">/</span><span class="num">2</span><span class="op">;</span> <span class="op">++</span>i<span class="op">)</span> + <span class="op">{</span> + <span class="rem">// Get the pointer to the beginning of the i-th row (Y-coordinate)</span> + <span class="rem">// and shift it to the i-th position, that is, X-coordinate.</span> + <span class="rem">//---------------</span> + <span class="kw1">unsigned</span> <span class="kw1">char</span><span class="op">*</span> ptr <span class="op">=</span> rbuf<span class="op">.</span>row_ptr<span class="op">(</span>i<span class="op">)</span> <span class="op">+</span> i <span class="op">*</span> <span class="num">3</span><span class="op">;</span> + + <span class="rem">// PutPixel, very sophisticated, huh? :)</span> + <span class="rem">//-------------</span> + <span class="op">*</span>ptr<span class="op">++</span> <span class="op">=</span> <span class="num">127</span><span class="op">;</span> <span class="rem">// R</span> + <span class="op">*</span>ptr<span class="op">++</span> <span class="op">=</span> <span class="num">200</span><span class="op">;</span> <span class="rem">// G</span> + <span class="op">*</span>ptr<span class="op">++</span> <span class="op">=</span> <span class="num">98</span><span class="op">;</span> <span class="rem">// B</span> + <span class="op">}</span> + + draw_black_frame<span class="op">(</span>rbuf<span class="op">)</span><span class="op">;</span> + write_ppm<span class="op">(</span>buffer<span class="op">,</span> frame_width<span class="op">,</span> frame_height<span class="op">,</span> <span class="str">"agg_test.ppm"</span><span class="op">)</span><span class="op">;</span> + + <span class="kw1">delete</span> <span class="op">[</span><span class="op">]</span> buffer<span class="op">;</span> + <span class="kw1">return</span> <span class="num">0</span><span class="op">;</span> +<span class="op">}</span> +</pre></td></tr></tbody></table><font style="margin-left: 1em;"><i></i></font> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>In +this example you don't even have to link it with any <b>AGG</b> files, +you need only to +indicate the <b>AGG</b> <code>include</code> directory in the command +line of your compiler.</p></td></tr></tbody></table> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>When + you compile and run it you should see the following result. +</p></td></tr></tbody></table><table width="640px"><tbody><tr><td><center><img + src="basic_renderers.agdoc_files/rendering_buffer1.gif" title="" +border="0"><br><i></i></center></td></tr></tbody></table> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>Almost + everything here is coded “manually”. The only class we use is +<a +href="http://www.antigrain.com/doc/basic_renderers/basic_renderers.agdoc.html#rendering_buffer">rendering_buffer</a>. + This class doesn't know anything about +the pixel format in memory, it just keeps an array of pointers +to each row. It is your responsibility to allocate and deallocate +actual memory for the buffer. You can use any available mechanism +for that, a system API function, simple memory allocation, or even +an array defined statically. In the above example we allocate +<nobr><code>width * height * 3</code></nobr> bytes of memory, since we +use 3 bytes per pixel. +The rows are not aligned in memory, but they can be for better +performance or +if it is required by used API.</p></td></tr></tbody></table> + +<h3>Class rendering_buffer<a name="toc0003"></a></h3> + +<a name="rendering_buffer"><b></b></a> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>Include + file: <a +href="http://www.antigrain.com/__code/include/agg_rendering_buffer.h.html">agg_rendering_buffer.h</a></p></td></tr></tbody></table> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>The +rendering buffer class keeps pointers to each rows, and basically it's +all it does. It doesn't look like a great achievement, but try to keep +reading. +The interface and functionality of it is very simple. +It's a <code>typedef</code> of class template <a +href="http://www.antigrain.com/doc/basic_renderers/basic_renderers.agdoc.html#row_ptr_cache">row_ptr_cache</a>:</p></td></tr></tbody></table> + +<table width="640px" border="0" cellpadding="0" cellspacing="0"><tbody><tr><td><pre><span class="kw1">typedef</span> <a href="http://www.antigrain.com/doc/basic_renderers/basic_renderers.agdoc.html#row_ptr_cache">row_ptr_cache</a><span class="op"><</span><a href="http://www.antigrain.com/__code/include/agg_basics.h.html#int8u">int8u</a><span class="op">></span> <a href="http://www.antigrain.com/doc/basic_renderers/basic_renderers.agdoc.html#rendering_buffer">rendering_buffer</a><span class="op">;</span> +</pre></td></tr></tbody></table><font style="margin-left: 1em;"><i></i></font> + +<a name="row_ptr_cache"><b></b></a> +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>The +interface and the functionality of class <a +href="http://www.antigrain.com/doc/basic_renderers/basic_renderers.agdoc.html#row_ptr_cache">row_ptr_cache</a> + is:</p></td></tr></tbody></table> + +<table width="640px" border="0" cellpadding="0" cellspacing="0"><tbody><tr><td><pre><span class="kw1">template</span><span class="op"><</span><span class="kw1">class</span> T<span class="op">></span> <span class="kw1">class</span> <a href="http://www.antigrain.com/doc/basic_renderers/basic_renderers.agdoc.html#row_ptr_cache">row_ptr_cache</a> +<span class="op">{</span> +<span class="kw1">public</span>: + <a href="http://www.antigrain.com/doc/basic_renderers/basic_renderers.agdoc.html#row_ptr_cache">row_ptr_cache</a><span class="op">(</span><span class="op">)</span><span class="op">;</span> + + <a href="http://www.antigrain.com/doc/basic_renderers/basic_renderers.agdoc.html#row_ptr_cache">row_ptr_cache</a><span class="op">(</span>T<span class="op">*</span> buf<span class="op">,</span> <span class="kw1">unsigned</span> width<span class="op">,</span> <span class="kw1">unsigned</span> height<span class="op">,</span> <span class="kw1">int</span> stride<span class="op">)</span><span class="op">;</span> + + <span class="kw1">void</span> attach<span class="op">(</span>T<span class="op">*</span> buf<span class="op">,</span> <span class="kw1">unsigned</span> width<span class="op">,</span> <span class="kw1">unsigned</span> height<span class="op">,</span> <span class="kw1">int</span> stride<span class="op">)</span><span class="op">;</span> + + T<span class="op">*</span> buf<span class="op">(</span><span class="op">)</span><span class="op">;</span> + <span class="kw1">const</span> T<span class="op">*</span> buf<span class="op">(</span><span class="op">)</span> <span class="kw1">const</span><span class="op">;</span> + <span class="kw1">unsigned</span> width<span class="op">(</span><span class="op">)</span> <span class="kw1">const</span><span class="op">;</span> + <span class="kw1">unsigned</span> height<span class="op">(</span><span class="op">)</span> <span class="kw1">const</span><span class="op">;</span> + <span class="kw1">int</span> stride<span class="op">(</span><span class="op">)</span> <span class="kw1">const</span><span class="op">;</span> + <span class="kw1">unsigned</span> stride_abs<span class="op">(</span><span class="op">)</span> <span class="kw1">const</span><span class="op">;</span> + + T<span class="op">*</span> row_ptr<span class="op">(</span><span class="kw1">int</span><span class="op">,</span> <span class="kw1">int</span> y<span class="op">,</span> <span class="kw1">unsigned</span><span class="op">)</span> + T<span class="op">*</span> row_ptr<span class="op">(</span><span class="kw1">int</span> y<span class="op">)</span><span class="op">;</span> + <span class="kw1">const</span> T<span class="op">*</span> row_ptr<span class="op">(</span><span class="kw1">int</span> y<span class="op">)</span> <span class="kw1">const</span><span class="op">;</span> + row_data row <span class="op">(</span><span class="kw1">int</span> y<span class="op">)</span> <span class="kw1">const</span><span class="op">;</span> + T <span class="kw1">const</span><span class="op">*</span> <span class="kw1">const</span><span class="op">*</span> rows<span class="op">(</span><span class="op">)</span> <span class="kw1">const</span><span class="op">;</span> + + <span class="kw1">template</span><span class="op"><</span><span class="kw1">class</span> RenBuf<span class="op">></span> <span class="kw1">void</span> copy_from<span class="op">(</span><span class="kw1">const</span> RenBuf<span class="op">&</span> src<span class="op">)</span><span class="op">;</span> + + <span class="kw1">void</span> clear<span class="op">(</span>T value<span class="op">)</span> +<span class="op">}</span><span class="op">;</span> +</pre></td></tr></tbody></table><font style="margin-left: 1em;"><i></i></font> +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>The +source code: <a +href="http://www.antigrain.com/__code/include/agg_rendering_buffer.h.html#row_ptr_cache">row_ptr_cache</a> +</p></td></tr></tbody></table><table style="margin: 0px;" height="1px" +width="640px" bgcolor="#583927" border="0" cellpadding="0" +cellspacing="0"><tbody><tr><td></td></tr></tbody></table> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>The +class doesn't have any assertion or verification code, so that, your +responsibility is to properly attach an actual memory buffer to the +object +before using it. It can be done in the constructor as well as with the +<code>attach()</code> function. The arguments of them are:</p></td></tr></tbody></table> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p></p><ul + type="disc"> +<li><b>buf</b> — A pointer to the memory buffer.</li> +<li><b>width</b> — Width of the image in <b>pixels</b>. The rendering +buffer + doesn't know anything about pixel format and about the size + of one pixel in memory. This value is simply stored in its data + member <code>m_width</code> and returned by <code>width()</code> +function.</li> +<li><b>height</b> — The height of the buffer in <b>pixels</b> (the +number of rows).</li> +<li><b>stride</b> — The “stride” (big step) of the rows measured in +objects of type <code>T</code>. + Class <a +href="http://www.antigrain.com/doc/basic_renderers/basic_renderers.agdoc.html#rendering_buffer">rendering_buffer</a> + is “<code>typedefed</code>” as <code><a +href="http://www.antigrain.com/doc/basic_renderers/basic_renderers.agdoc.html#row_ptr_cache">row_ptr_cache</a><<a + href="http://www.antigrain.com/__code/include/agg_basics.h.html#int8u">int8u</a>></code>, + so, + this value is in bytes. <b>Stride</b> determines the physical width +of + one row in memory. If this value is negative the direction of + the <b>Y</b> axis is inverted, that is, <code>Y==0</code> will point +to the last + row of the buffer, <code>Y==height-1</code> — to the first one. The +absolute value + of <b>stride</b> is important too, because it allows you to work with + buffers + whose rows are aligned in memory (like in Windows BMP, for example). + Besides, this parameter allows you to work with any rectangular area + + inside the buffer as with the whole buffer.</li></ul><p></p></td></tr></tbody></table> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>Function + <code>attach()</code> changes the buffer or its parameters. It takes +care of +reallocating the memory for the row-pointers buffer, so that, you can +call it +anytime. It will reallocate the memory if (and only if) new <code>height</code> + is +is larger than any previously attached.</p></td></tr></tbody></table> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>The +cost of creation is just initializing of the variables (set to 0), +the cost of <code>attach()</code> is allocating of <code>sizeof(ptr) * +height</code> bytes +of memory and initializing of the pointers to the rows.</p></td></tr></tbody></table> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>The +most frequently used function is <code>row_ptr(y)</code> that simply +returns a pointer +to the beginning of the <nobr><code>y</code><sup>th</sup></nobr> row, +considering the direction of +the <nobr><b>Y</b>-axis</nobr>.</p></td></tr></tbody></table> + +<table class="warning" width="640px"><tbody><tr><td><b>IMPORTANT!</b><br> +The rendering buffer does not perform any clipping or bound checking, +it's the responsibility of higher level classes. +</td></tr></tbody></table> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>The +accessors, +<code>buf()</code>, <code>width()</code>, <code>height()</code>, <code>stride()</code>, + <code>stride_abs()</code> +should be obvious.</p></td></tr></tbody></table> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>Function + <code>copy_from()</code> copies the content of another buffer to “this” +one. The function is safe, if the <b>width</b> or <b>height</b> is +different +it will copy the maximal possible area. Basically, it's used to copy +rendering buffers of equal size.</p></td></tr></tbody></table> + +<h3>Two Modifications of the Example<a name="toc0004"></a></h3> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>First, + negate the <b>stride</b> when creating the rendering buffer object:</p></td></tr></tbody></table> + +<table width="640px" border="0" cellpadding="0" cellspacing="0"><tbody><tr><td><pre> agg::<a href="http://www.antigrain.com/doc/basic_renderers/basic_renderers.agdoc.html#rendering_buffer">rendering_buffer</a> rbuf<span class="op">(</span>buffer<span class="op">,</span> + frame_width<span class="op">,</span> + frame_height<span class="op">,</span> + <span class="op">-</span>frame_width <span class="op">*</span> <span class="num">3</span><span class="op">)</span><span class="op">;</span> +</pre></td></tr></tbody></table><font style="margin-left: 1em;"><i></i></font> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>The +result is:</p></td></tr></tbody></table> + +<table width="640px"><tbody><tr><td><center><img +src="basic_renderers.agdoc_files/rendering_buffer2.gif" title="" +border="0"><br><i></i></center></td></tr></tbody></table> +<table style="margin: 0px;" height="1px" width="640px" bgcolor="#583927" + border="0" cellpadding="0" cellspacing="0"><tbody><tr><td></td></tr></tbody></table> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>Second, + let's try to attach to some part of the allocated buffer. This +modification +actually attaches to the same buffer twice, first, to the whole frame, +then to +its part, with 20 pixel margin.</p></td></tr></tbody></table> + +<table width="640px" border="0" cellpadding="0" cellspacing="0"><tbody><tr><td><pre><span class="kw1">int</span> <span class="kw1">main</span><span class="op">(</span><span class="op">)</span> +<span class="op">{</span> + <span class="kw1">unsigned</span> <span class="kw1">char</span><span class="op">*</span> buffer <span class="op">=</span> <span class="kw1">new</span> <span class="kw1">unsigned</span> <span class="kw1">char</span><span class="op">[</span>frame_width <span class="op">*</span> frame_height <span class="op">*</span> <span class="num">3</span><span class="op">]</span><span class="op">;</span> + + memset<span class="op">(</span>buffer<span class="op">,</span> <span class="num">255</span><span class="op">,</span> frame_width <span class="op">*</span> frame_height <span class="op">*</span> <span class="num">3</span><span class="op">)</span><span class="op">;</span> + + agg::<a href="http://www.antigrain.com/doc/basic_renderers/basic_renderers.agdoc.html#rendering_buffer">rendering_buffer</a> rbuf<span class="op">(</span>buffer<span class="op">,</span> + frame_width<span class="op">,</span> + frame_height<span class="op">,</span> + frame_width <span class="op">*</span> <span class="num">3</span><span class="op">)</span><span class="op">;</span> + + <span class="rem">// Draw the outer black frame</span> + <span class="rem">//------------------------</span> + draw_black_frame<span class="op">(</span>rbuf<span class="op">)</span><span class="op">;</span> + + <span class="rem">// Attach to the part of the buffer, </span> + <span class="rem">// with 20 pixel margins at each side.</span> + rbuf<span class="op">.</span>attach<span class="op">(</span>buffer <span class="op">+</span> + frame_width <span class="op">*</span> <span class="num">3</span> <span class="op">*</span> <span class="num">20</span> <span class="op">+</span> <span class="rem">// initial Y-offset</span> + <span class="num">3</span> <span class="op">*</span> <span class="num">20</span><span class="op">,</span> <span class="rem">// initial X-offset</span> + frame_width <span class="op">-</span> <span class="num">40</span><span class="op">,</span> + frame_height <span class="op">-</span> <span class="num">40</span><span class="op">,</span> + frame_width <span class="op">*</span> <span class="num">3</span> <span class="rem">// Note that the stride</span> + <span class="rem">// remains the same</span> + <span class="op">)</span><span class="op">;</span> + + <span class="rem">// Draw a diagonal line</span> + <span class="rem">//------------------------</span> + <span class="kw1">unsigned</span> i<span class="op">;</span> + <span class="kw1">for</span><span class="op">(</span>i <span class="op">=</span> <span class="num">0</span><span class="op">;</span> i <span class="op"><</span> rbuf<span class="op">.</span>height<span class="op">(</span><span class="op">)</span><span class="op">/</span><span class="num">2</span><span class="op">;</span> <span class="op">++</span>i<span class="op">)</span> + <span class="op">{</span> + <span class="rem">// Get the pointer to the beginning of the i-th row (Y-coordinate)</span> + <span class="rem">// and shift it to the i-th position, that is, X-coordinate.</span> + <span class="rem">//---------------</span> + <span class="kw1">unsigned</span> <span class="kw1">char</span><span class="op">*</span> ptr <span class="op">=</span> rbuf<span class="op">.</span>row_ptr<span class="op">(</span>i<span class="op">)</span> <span class="op">+</span> i <span class="op">*</span> <span class="num">3</span><span class="op">;</span> + + <span class="rem">// PutPixel, very sophisticated, huh? :)</span> + <span class="rem">//-------------</span> + <span class="op">*</span>ptr<span class="op">++</span> <span class="op">=</span> <span class="num">127</span><span class="op">;</span> <span class="rem">// R</span> + <span class="op">*</span>ptr<span class="op">++</span> <span class="op">=</span> <span class="num">200</span><span class="op">;</span> <span class="rem">// G</span> + <span class="op">*</span>ptr<span class="op">++</span> <span class="op">=</span> <span class="num">98</span><span class="op">;</span> <span class="rem">// B</span> + <span class="op">}</span> + + <span class="rem">// Draw the inner black frame</span> + <span class="rem">//------------------------</span> + draw_black_frame<span class="op">(</span>rbuf<span class="op">)</span><span class="op">;</span> + + <span class="rem">// Write to a file</span> + <span class="rem">//------------------------</span> + write_ppm<span class="op">(</span>buffer<span class="op">,</span> frame_width<span class="op">,</span> frame_height<span class="op">,</span> <span class="str">"agg_test.ppm"</span><span class="op">)</span><span class="op">;</span> + + <span class="kw1">delete</span> <span class="op">[</span><span class="op">]</span> buffer<span class="op">;</span> + <span class="kw1">return</span> <span class="num">0</span><span class="op">;</span> +<span class="op">}</span> +</pre></td></tr></tbody></table><font style="margin-left: 1em;"><i></i></font> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>The +result:</p></td></tr></tbody></table> + +<table width="640px"><tbody><tr><td><center><img +src="basic_renderers.agdoc_files/rendering_buffer3.gif" title="" +border="0"><br><i></i></center></td></tr></tbody></table> +<table style="margin: 0px;" height="1px" width="640px" bgcolor="#583927" + border="0" cellpadding="0" cellspacing="0"><tbody><tr><td></td></tr></tbody></table> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>And +the last modification is: +</p></td></tr></tbody></table><table width="640px" border="0" +cellpadding="0" cellspacing="0"><tbody><tr><td><pre> <span class="rem">// Attach to the part of the buffer, </span> + <span class="rem">// with 20 pixel margins at each side and negative 'stride'</span> + rbuf<span class="op">.</span>attach<span class="op">(</span>buffer <span class="op">+</span> + frame_width <span class="op">*</span> <span class="num">3</span> <span class="op">*</span> <span class="num">20</span> <span class="op">+</span> <span class="rem">// initial Y-offset</span> + <span class="num">3</span> <span class="op">*</span> <span class="num">20</span><span class="op">,</span> <span class="rem">// initial X-offset</span> + frame_width <span class="op">-</span> <span class="num">40</span><span class="op">,</span> + frame_height <span class="op">-</span> <span class="num">40</span><span class="op">,</span> + <span class="op">-</span>frame_width <span class="op">*</span> <span class="num">3</span> <span class="rem">// Negate the stride</span> + <span class="op">)</span><span class="op">;</span> +</pre></td></tr></tbody></table><font style="margin-left: 1em;"><i></i></font> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>The +result:</p></td></tr></tbody></table> + +<table width="640px"><tbody><tr><td><center><img +src="basic_renderers.agdoc_files/rendering_buffer4.gif" title="" +border="0"><br><i></i></center></td></tr></tbody></table> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>In +the last example we just negated the stride value, +keeping the pointer to the beginning of the buffer as it was in +the previous example. +</p></td></tr></tbody></table><table class="note" width="640px"><tbody><tr><td><b>NOTE</b><br> +Function <code>write_ppm()</code> writes the pixel map to a file. +Hereafter it will +be omited in this text, but duplicated when necessary in source code in +the <code>agg2/tutorial</code> directory. +</td></tr></tbody></table> + + +<br><h2>Pixel Format Renderers<a name="toc0005"></a></h2> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>First, + we create another, more civil example, which is in +<code>agg2/tutorial/t02_pixel_formats</code>: +</p></td></tr></tbody></table><table width="640px" border="0" +cellpadding="0" cellspacing="0"><tbody><tr><td><pre><span class="kw2">#include</span> <span class="op"><</span>stdio<span class="op">.</span>h<span class="op">></span> +<span class="kw2">#include</span> <span class="op"><</span>string<span class="op">.</span>h<span class="op">></span> +<span class="kw2">#include</span> <span class="str">"agg_pixfmt_rgb24.h"</span> + +<span class="kw1">enum</span> +<span class="op">{</span> + frame_width <span class="op">=</span> <span class="num">320</span><span class="op">,</span> + frame_height <span class="op">=</span> <span class="num">200</span> +<span class="op">}</span><span class="op">;</span> + +<span class="rem">// [...write_ppm is skipped...]</span> + +<span class="rem">// Draw a black frame around the rendering buffer</span> +<span class="rem">//--------------------------------------------------</span> +<span class="kw1">template</span><span class="op"><</span><span class="kw1">class</span> Ren<span class="op">></span> +<span class="kw1">void</span> draw_black_frame<span class="op">(</span>Ren<span class="op">&</span> ren<span class="op">)</span> +<span class="op">{</span> + <span class="kw1">unsigned</span> i<span class="op">;</span> + agg::<a href="http://www.antigrain.com/__code/include/agg_color_rgba.h.html#rgba8">rgba8</a> c<span class="op">(</span><span class="num">0</span><span class="op">,</span><span class="num">0</span><span class="op">,</span><span class="num">0</span><span class="op">)</span><span class="op">;</span> + <span class="kw1">for</span><span class="op">(</span>i <span class="op">=</span> <span class="num">0</span><span class="op">;</span> i <span class="op"><</span> ren<span class="op">.</span>height<span class="op">(</span><span class="op">)</span><span class="op">;</span> <span class="op">++</span>i<span class="op">)</span> + <span class="op">{</span> + ren<span class="op">.</span>copy_pixel<span class="op">(</span><span class="num">0</span><span class="op">,</span> i<span class="op">,</span> c<span class="op">)</span><span class="op">;</span> + ren<span class="op">.</span>copy_pixel<span class="op">(</span>ren<span class="op">.</span>width<span class="op">(</span><span class="op">)</span> <span class="op">-</span> <span class="num">1</span><span class="op">,</span> i<span class="op">,</span> c<span class="op">)</span><span class="op">;</span> + <span class="op">}</span> + <span class="kw1">for</span><span class="op">(</span>i <span class="op">=</span> <span class="num">0</span><span class="op">;</span> i <span class="op"><</span> ren<span class="op">.</span>width<span class="op">(</span><span class="op">)</span><span class="op">;</span> <span class="op">++</span>i<span class="op">)</span> + <span class="op">{</span> + ren<span class="op">.</span>copy_pixel<span class="op">(</span>i<span class="op">,</span> <span class="num">0</span><span class="op">,</span> c<span class="op">)</span><span class="op">;</span> + ren<span class="op">.</span>copy_pixel<span class="op">(</span>i<span class="op">,</span> ren<span class="op">.</span>height<span class="op">(</span><span class="op">)</span> <span class="op">-</span> <span class="num">1</span><span class="op">,</span> c<span class="op">)</span><span class="op">;</span> + <span class="op">}</span> +<span class="op">}</span> + + +<span class="kw1">int</span> <span class="kw1">main</span><span class="op">(</span><span class="op">)</span> +<span class="op">{</span> + <span class="rem">//--------------------</span> + <span class="rem">// Allocate the buffer.</span> + <span class="rem">// Clear the buffer, for now "manually"</span> + <span class="rem">// Create the rendering buffer object</span> + <span class="rem">// Create the Pixel Format renderer</span> + <span class="rem">// Do something simple, draw a diagonal line</span> + <span class="rem">// Write the buffer to agg_test.ppm</span> + <span class="rem">// Free memory</span> + + <span class="kw1">unsigned</span> <span class="kw1">char</span><span class="op">*</span> buffer <span class="op">=</span> <span class="kw1">new</span> <span class="kw1">unsigned</span> <span class="kw1">char</span><span class="op">[</span>frame_width <span class="op">*</span> frame_height <span class="op">*</span> <span class="num">3</span><span class="op">]</span><span class="op">;</span> + + memset<span class="op">(</span>buffer<span class="op">,</span> <span class="num">255</span><span class="op">,</span> frame_width <span class="op">*</span> frame_height <span class="op">*</span> <span class="num">3</span><span class="op">)</span><span class="op">;</span> + + agg::<a href="http://www.antigrain.com/doc/basic_renderers/basic_renderers.agdoc.html#rendering_buffer">rendering_buffer</a> rbuf<span class="op">(</span>buffer<span class="op">,</span> + frame_width<span class="op">,</span> + frame_height<span class="op">,</span> + frame_width <span class="op">*</span> <span class="num">3</span><span class="op">)</span><span class="op">;</span> + + agg::<a href="http://www.antigrain.com/__code/include/agg_pixfmt_rgb.h.html#pixfmt_rgb24">pixfmt_rgb24</a> pixf<span class="op">(</span>rbuf<span class="op">)</span><span class="op">;</span> + + <span class="kw1">unsigned</span> i<span class="op">;</span> + <span class="kw1">for</span><span class="op">(</span>i <span class="op">=</span> <span class="num">0</span><span class="op">;</span> i <span class="op"><</span> pixf<span class="op">.</span>height<span class="op">(</span><span class="op">)</span><span class="op">/</span><span class="num">2</span><span class="op">;</span> <span class="op">++</span>i<span class="op">)</span> + <span class="op">{</span> + pixf<span class="op">.</span>copy_pixel<span class="op">(</span>i<span class="op">,</span> i<span class="op">,</span> agg::<a href="http://www.antigrain.com/__code/include/agg_color_rgba.h.html#rgba8">rgba8</a><span class="op">(</span><span class="num">127</span><span class="op">,</span> <span class="num">200</span><span class="op">,</span> <span class="num">98</span><span class="op">)</span><span class="op">)</span><span class="op">;</span> + <span class="op">}</span> + + draw_black_frame<span class="op">(</span>pixf<span class="op">)</span><span class="op">;</span> + write_ppm<span class="op">(</span>buffer<span class="op">,</span> frame_width<span class="op">,</span> frame_height<span class="op">,</span> <span class="str">"agg_test.ppm"</span><span class="op">)</span><span class="op">;</span> + + <span class="kw1">delete</span> <span class="op">[</span><span class="op">]</span> buffer<span class="op">;</span> + <span class="kw1">return</span> <span class="num">0</span><span class="op">;</span> +<span class="op">}</span> +</pre></td></tr></tbody></table><font style="margin-left: 1em;"><i></i></font> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>This + example doesn't look very different from the previous one, but the +difference in its essence is great. Look at the declaration: +</p></td></tr></tbody></table><table width="640px" border="0" +cellpadding="0" cellspacing="0"><tbody><tr><td><pre>agg::<a href="http://www.antigrain.com/__code/include/agg_pixfmt_rgb.h.html#pixfmt_rgb24">pixfmt_rgb24</a> pixf<span class="op">(</span>rbuf<span class="op">)</span><span class="op">;</span></pre></td></tr></tbody></table><font + style="margin-left: 1em;"><i></i></font> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>Here + we create a low-level pixel rendering object and attach it to the +rendering buffer.</p></td></tr></tbody></table> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>It +defined as: +</p></td></tr></tbody></table><table width="640px" border="0" +cellpadding="0" cellspacing="0"><tbody><tr><td><pre><span class="kw1">typedef</span> pixel_formats_rgb24<span class="op"><</span>order_rgb24<span class="op">></span> <a href="http://www.antigrain.com/__code/include/agg_pixfmt_rgb.h.html#pixfmt_rgb24">pixfmt_rgb24</a><span class="op">;</span></pre></td></tr></tbody></table><font + style="margin-left: 1em;"><i></i></font> + +<a name="pixfmt"><b></b></a> +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>Class + template pixel_formats_rgb24 has full knowledge about this +particular pixel format in memory. The only template parameter +can be order_rgb24 or order_bgr24 that determines the order of color +channels.</p></td></tr></tbody></table> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>Unlike + <a +href="http://www.antigrain.com/doc/basic_renderers/basic_renderers.agdoc.html#rendering_buffer">rendering_buffer</a>, + these classes operate with integer pixel +coordinates because they know how to calculate the offset for +<nobr>particular <b>X</b></nobr>. One can say that it would be easier to + keep the +width of the pixel inside the <a +href="http://www.antigrain.com/doc/basic_renderers/basic_renderers.agdoc.html#rendering_buffer">rendering_buffer</a>, + but in practice it would be +a restriction. Don't forget that the width of one pixel in memory can be + +less than one byte, for example, when rendering high resolution +B&W images for printers. Thus, there is just a separation of the +functionality, <a +href="http://www.antigrain.com/doc/basic_renderers/basic_renderers.agdoc.html#rendering_buffer">rendering_buffer</a> + just accelerates access to rows, +pixel format renderers have knowledge of how to interpret the rows.</p></td></tr></tbody></table> + + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>Currently, + in <b>AGG</b> there are the following files that implement different +pixel formats:</p></td></tr></tbody></table> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p></p><ul + type="disc"> +<li>agg_pixfmt_gray8.h, one byte per pixel grayscale buffer. This pixel +format allows + you to work with one color component of the rgb24 or rgba32 pixel +format. + It has the template parameters <code>Step</code> and <code>Offset</code> + and for the convenience + defines the following types:</li> +<ul type="disc"> +<li><code>typedef pixfmt_gray8_base<1, 0> <a +href="http://www.antigrain.com/__code/include/agg_pixfmt_gray.h.html#pixfmt_gray8">pixfmt_gray8</a>;</code></li> +<li><code>typedef pixfmt_gray8_base<3, 0> pixfmt_gray8_rgb24r;</code></li> +<li><code>typedef pixfmt_gray8_base<3, 1> pixfmt_gray8_rgb24g;</code></li> +<li><code>typedef pixfmt_gray8_base<3, 2> pixfmt_gray8_rgb24b;</code></li> +<li><code>typedef pixfmt_gray8_base<3, 2> pixfmt_gray8_bgr24r;</code></li> +<li><code>typedef pixfmt_gray8_base<3, 1> pixfmt_gray8_bgr24g;</code></li> +<li><code>typedef pixfmt_gray8_base<3, 0> pixfmt_gray8_bgr24b;</code></li> +<li><code>typedef pixfmt_gray8_base<4, 0> pixfmt_gray8_rgba32r;</code></li> +<li><code>typedef pixfmt_gray8_base<4, 1> pixfmt_gray8_rgba32g;</code></li> +<li><code>typedef pixfmt_gray8_base<4, 2> pixfmt_gray8_rgba32b;</code></li> +<li><code>typedef pixfmt_gray8_base<4, 3> pixfmt_gray8_rgba32a;</code></li> +<li><code>typedef pixfmt_gray8_base<4, 1> pixfmt_gray8_argb32r;</code></li> +<li><code>typedef pixfmt_gray8_base<4, 2> pixfmt_gray8_argb32g;</code></li> +<li><code>typedef pixfmt_gray8_base<4, 3> pixfmt_gray8_argb32b;</code></li> +<li><code>typedef pixfmt_gray8_base<4, 0> pixfmt_gray8_argb32a;</code></li> +<li><code>typedef pixfmt_gray8_base<4, 2> pixfmt_gray8_bgra32r;</code></li> +<li><code>typedef pixfmt_gray8_base<4, 1> pixfmt_gray8_bgra32g;</code></li> +<li><code>typedef pixfmt_gray8_base<4, 0> pixfmt_gray8_bgra32b;</code></li> +<li><code>typedef pixfmt_gray8_base<4, 3> pixfmt_gray8_bgra32a;</code></li> +<li><code>typedef pixfmt_gray8_base<4, 3> pixfmt_gray8_abgr32r;</code></li> +<li><code>typedef pixfmt_gray8_base<4, 2> pixfmt_gray8_abgr32g;</code></li> +<li><code>typedef pixfmt_gray8_base<4, 1> pixfmt_gray8_abgr32b;</code></li> +<li><code>typedef pixfmt_gray8_base<4, 0> pixfmt_gray8_abgr32a;</code></li></ul> +<li>agg_pixfmt_rgb24.h, three bytes per pixel, with RGB or BGR component + orders. + Defines the following pixel format types:</li> +<ul type="disc"> +<li><code>typedef pixel_formats_rgb24<order_rgb24> <a +href="http://www.antigrain.com/__code/include/agg_pixfmt_rgb.h.html#pixfmt_rgb24">pixfmt_rgb24</a>;</code></li> +<li><code>typedef pixel_formats_rgb24<order_bgr24> <a +href="http://www.antigrain.com/__code/include/agg_pixfmt_rgb.h.html#pixfmt_bgr24">pixfmt_bgr24</a>;</code></li></ul> +<li>agg_pixfmt_rgb555.h, 15 bits per pixel, 5 bits per channel. The +elder bit is unused.</li> +<li>agg_pixfmt_rgb565.h, 16 bits per pixel, 5 bits for Red, 6 bits for +Green, and 5 bits for Blue.</li> +<li>agg_pixfmt_rgba32.h, four bytes per pixel, RGB plus Alpha with +different component + orders:</li> +<ul type="disc"> +<li><code>typedef pixel_formats_rgba32<order_rgba32> <a +href="http://www.antigrain.com/__code/include/agg_pixfmt_rgba.h.html#pixfmt_rgba32">pixfmt_rgba32</a>;</code></li> +<li><code>typedef pixel_formats_rgba32<order_argb32> <a +href="http://www.antigrain.com/__code/include/agg_pixfmt_rgba.h.html#pixfmt_argb32">pixfmt_argb32</a>;</code></li> +<li><code>typedef pixel_formats_rgba32<order_abgr32> <a +href="http://www.antigrain.com/__code/include/agg_pixfmt_rgba.h.html#pixfmt_abgr32">pixfmt_abgr32</a>;</code></li> +<li><code>typedef pixel_formats_rgba32<order_bgra32> <a +href="http://www.antigrain.com/__code/include/agg_pixfmt_rgba.h.html#pixfmt_bgra32">pixfmt_bgra32</a>;</code></li></ul></ul><p></p></td></tr></tbody></table> + + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>The +pixel format classes define their native color space and the color type, + +for example: +</p></td></tr></tbody></table><table width="640px" border="0" +cellpadding="0" cellspacing="0"><tbody><tr><td><pre><span class="kw1">typedef</span> <a href="http://www.antigrain.com/__code/include/agg_color_rgba.h.html#rgba8">rgba8</a> color_type<span class="op">;</span></pre></td></tr></tbody></table><font + style="margin-left: 1em;"><i></i></font> +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>For <code>pixfmt_gray8_nnn</code> + it's <a +href="http://www.antigrain.com/__code/include/agg_color_gray.h.html#gray8">gray8</a>. + This mechanism allows you to write +your own pixel and color formats, for example, HSV, CMYK, and so on. +The rest of the library will work with new pixel formats in exactly +same way as with currently implemented ones. +</p></td></tr></tbody></table><table class="note" width="640px"><tbody><tr><td><b>NOTE</b><br> +It's very important not to confuse the color type that the pixel format +renderer works with and the <b>native</b> color space that the buffer +represents. For example, you can pretend that you work with the CMYK +color +space using the RGB buffer (you just write a simple conversion function +that +creates an <a +href="http://www.antigrain.com/__code/include/agg_color_rgba.h.html#rgba8">rgba8</a> + object from some CMYK structure). But it will be only +an imitation and you will have color losses, because there are some +colors in CMYK that cannot be displayed with RGB and vice versa. +To use the capabilities of some color space completely one has to write +a pixel format renderer for that particular color space and to work +in that color space without any intermediate conversions. +</td></tr></tbody></table> + +<h3>Creation<a name="toc0006"></a></h3> + +<table class="warning" width="640px"><tbody><tr><td><b>IMPORTANT!</b><br> +The pixel format classes do not perform any clipping operations, which +means that +working directly with these classes is generally unsafe. Clipping is the + +functionality of higher level classes. The reason of this design is +simple — +it must be as easy as possible to write your own pixel format classes. +There +can be many of them while the clipping code remains exactly the same. +</td></tr></tbody></table> + +<table width="640px" border="0" cellpadding="0" cellspacing="0"><tbody><tr><td><pre>pixel_formats_rgb24<span class="op">(</span><a href="http://www.antigrain.com/doc/basic_renderers/basic_renderers.agdoc.html#rendering_buffer">rendering_buffer</a><span class="op">&</span> rb<span class="op">)</span><span class="op">;</span></pre></td></tr></tbody></table><font + style="margin-left: 1em;"><i></i></font> +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>The +constructor of the pixel format renderers expects a reference to the +created and fully initialized <a +href="http://www.antigrain.com/doc/basic_renderers/basic_renderers.agdoc.html#rendering_buffer">rendering_buffer</a>. + The cost of creation +is minimal, basically it's initializing of one pointer.</p></td></tr></tbody></table> + +<h3>Member Functions<a name="toc0007"></a></h3> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>The +pixel format renderers must expose the following functionality +(interface).</p></td></tr></tbody></table> + +<table width="640px" border="0" cellpadding="0" cellspacing="0"><tbody><tr><td><pre><span class="kw1">unsigned</span> width<span class="op">(</span><span class="op">)</span> <span class="kw1">const</span> <span class="op">{</span> <span class="kw1">return</span> m_rbuf<span class="op">-</span><span class="op">></span>width<span class="op">(</span><span class="op">)</span><span class="op">;</span> <span class="op">}</span> +<span class="kw1">unsigned</span> height<span class="op">(</span><span class="op">)</span> <span class="kw1">const</span> <span class="op">{</span> <span class="kw1">return</span> m_rbuf<span class="op">-</span><span class="op">></span>height<span class="op">(</span><span class="op">)</span><span class="op">;</span> <span class="op">}</span></pre></td></tr></tbody></table><font + style="margin-left: 1em;"><i></i></font> +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>Returns + width and height of the buffer in pixels. +<br><br></p></td></tr></tbody></table> + +<table width="640px" border="0" cellpadding="0" cellspacing="0"><tbody><tr><td><pre>color_type pixel<span class="op">(</span><span class="kw1">int</span> x<span class="op">,</span> <span class="kw1">int</span> y<span class="op">)</span><span class="op">;</span></pre></td></tr></tbody></table><font + style="margin-left: 1em;"><i></i></font> +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>Returns + the color value of the pixel with coordinates <code>(x,y)</code>. +<br><br></p></td></tr></tbody></table> + +<table width="640px" border="0" cellpadding="0" cellspacing="0"><tbody><tr><td><pre><span class="kw1">void</span> copy_pixel<span class="op">(</span><span class="kw1">int</span> x<span class="op">,</span> <span class="kw1">int</span> y<span class="op">,</span> <span class="kw1">const</span> color_type<span class="op">&</span> c<span class="op">)</span><span class="op">;</span></pre></td></tr></tbody></table><font + style="margin-left: 1em;"><i></i></font> +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>Copies + a pixel of color <code>c</code> to the buffer as it is. In the RGB +pixel formats it doesn't consider the alpha channel existing in the <a +href="http://www.antigrain.com/__code/include/agg_color_rgba.h.html#rgba8">rgba8</a> +type, in RGBA — it simply copies the alpha value to the buffer together +with R, G, and B. +<br><br></p></td></tr></tbody></table> + +<table width="640px" border="0" cellpadding="0" cellspacing="0"><tbody><tr><td><pre><span class="kw1">void</span> blend_pixel<span class="op">(</span><span class="kw1">int</span> x<span class="op">,</span> <span class="kw1">int</span> y<span class="op">,</span> <span class="kw1">const</span> color_type<span class="op">&</span> c<span class="op">,</span> <a href="http://www.antigrain.com/__code/include/agg_basics.h.html#int8u">int8u</a> cover<span class="op">)</span><span class="op">;</span></pre></td></tr></tbody></table><font + style="margin-left: 1em;"><i></i></font> +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>Blends + a pixel of color <code>c</code> with the one in the buffer. +Now it's time to explain the concept of blending. Blending is a key +feature for <b><nobr>Anti-Aliasing</nobr></b>. In the RGBA color space +we use the <a +href="http://www.antigrain.com/__code/include/agg_color_rgba.h.html#rgba8">rgba8</a> + structure to represent +colors. The structure already has data member <code><a +href="http://www.antigrain.com/__code/include/agg_basics.h.html#int8u">int8u</a> + a;</code> that is the alpha +channel. But in this function we also see argument <code>cover</code> +that deterines +the coverage value for the pixel, i.e, the part of the pixel that is +“covered” by the polygon. In fact, you can interpret it as a second +"Alpha" +("Beta"?). There are two reasons to do so. First of all, the color type +doesn't have to contain the alpha value. The second, even if the +color type has the Alpha field, its type doesn't have to be compatible +with the ones used in <b><nobr>Anti-Aliasing</nobr></b> algorithms. +Suppose you work with a “Hi-End” +RGBA color space represented as four floats in range [0…1]. Its alpha +value is also of type float — one byte is too bad for general blending +in this case, but quite enough for <b><nobr>Anti-Aliasing</nobr></b>. So + that, the <code>cover</code> value is +just a unified secondary alpha used specifically for <b><nobr>Anti-Aliasing</nobr></b> + purposes. +Globally, it's defined as <a +href="http://www.antigrain.com/__code/include/agg_basics.h.html#cover_type">cover_type</a>, + but in the described rasterizers +there explicit <a +href="http://www.antigrain.com/__code/include/agg_basics.h.html#int8u">int8u</a> + type is used. It's done intentionally, because +if there's a necessity to increase the capacity of <a +href="http://www.antigrain.com/__code/include/agg_basics.h.html#cover_type">cover_type</a>, +all the existing pixel format rasterizres become incompatible with +the <a +href="http://www.antigrain.com/__code/include/agg_basics.h.html#cover_type">cover_type</a>. + They will be <b>actually</b> incompatible, in fact, 8-bit +coverage values plus 8-bit alpha is the maximum that fits 32-bit +intermediate results when blending colors. In case of 16-bit values +we will have to use 64-bit integers, which is very expensive on 32-bit +platforms. +<br><br></p></td></tr></tbody></table> + +<table width="640px" border="0" cellpadding="0" cellspacing="0"><tbody><tr><td><pre><span class="kw1">void</span> copy_hline<span class="op">(</span><span class="kw1">int</span> x<span class="op">,</span> <span class="kw1">int</span> y<span class="op">,</span> <span class="kw1">unsigned</span> len<span class="op">,</span> <span class="kw1">const</span> color_type<span class="op">&</span> c<span class="op">)</span><span class="op">;</span></pre></td></tr></tbody></table><font + style="margin-left: 1em;"><i></i></font> +<table width="640px" border="0" cellpadding="0" cellspacing="0"><tbody><tr><td><pre><span class="kw1">void</span> copy_vline<span class="op">(</span><span class="kw1">int</span> x<span class="op">,</span> <span class="kw1">int</span> y<span class="op">,</span> <span class="kw1">unsigned</span> len<span class="op">,</span> <span class="kw1">const</span> color_type<span class="op">&</span> c<span class="op">)</span><span class="op">;</span></pre></td></tr></tbody></table><font + style="margin-left: 1em;"><i></i></font> +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>Draw + a horizontal or a vertical line of certain color. +<br><br></p></td></tr></tbody></table> + +<table width="640px" border="0" cellpadding="0" cellspacing="0"><tbody><tr><td><pre><span class="kw1">void</span> blend_hline<span class="op">(</span><span class="kw1">int</span> x<span class="op">,</span> <span class="kw1">int</span> y<span class="op">,</span> <span class="kw1">unsigned</span> len<span class="op">,</span> <span class="kw1">const</span> color_type<span class="op">&</span> c<span class="op">,</span> <a href="http://www.antigrain.com/__code/include/agg_basics.h.html#int8u">int8u</a> cover<span class="op">)</span><span class="op">;</span></pre></td></tr></tbody></table><font + style="margin-left: 1em;"><i></i></font> +<table width="640px" border="0" cellpadding="0" cellspacing="0"><tbody><tr><td><pre><span class="kw1">void</span> blend_vline<span class="op">(</span><span class="kw1">int</span> x<span class="op">,</span> <span class="kw1">int</span> y<span class="op">,</span> <span class="kw1">unsigned</span> len<span class="op">,</span> <span class="kw1">const</span> color_type<span class="op">&</span> c<span class="op">,</span> <a href="http://www.antigrain.com/__code/include/agg_basics.h.html#int8u">int8u</a> cover<span class="op">)</span><span class="op">;</span></pre></td></tr></tbody></table><font + style="margin-left: 1em;"><i></i></font> +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>Blend + a horizontal or a vertical line of certain color. The reason to +separate +“copy” and “blend” versions is the performance. Of course, there can be +one +extra <code>if/else</code> statement (and there is, in the “blend” +versions), but still, +it becomes critical when using <code>hline/vline</code> to draw many of +small markers, +like in different scatter plot applications. +<br><br></p></td></tr></tbody></table> + +<table width="640px" border="0" cellpadding="0" cellspacing="0"><tbody><tr><td><pre><span class="kw1">void</span> blend_solid_hspan<span class="op">(</span><span class="kw1">int</span> x<span class="op">,</span> <span class="kw1">int</span> y<span class="op">,</span> <span class="kw1">unsigned</span> len<span class="op">,</span> + <span class="kw1">const</span> color_type<span class="op">&</span> c<span class="op">,</span> <span class="kw1">const</span> <a href="http://www.antigrain.com/__code/include/agg_basics.h.html#int8u">int8u</a><span class="op">*</span> covers<span class="op">)</span><span class="op">;</span></pre></td></tr></tbody></table><font + style="margin-left: 1em;"><i></i></font> +<table width="640px" border="0" cellpadding="0" cellspacing="0"><tbody><tr><td><pre><span class="kw1">void</span> blend_solid_vspan<span class="op">(</span><span class="kw1">int</span> x<span class="op">,</span> <span class="kw1">int</span> y<span class="op">,</span> <span class="kw1">unsigned</span> len<span class="op">,</span> + <span class="kw1">const</span> color_type<span class="op">&</span> c<span class="op">,</span> <span class="kw1">const</span> <a href="http://www.antigrain.com/__code/include/agg_basics.h.html#int8u">int8u</a><span class="op">*</span> covers<span class="op">)</span><span class="op">;</span></pre></td></tr></tbody></table><font + style="margin-left: 1em;"><i></i></font> +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>Blend + a horizontal or a vertical solid-color span. Span is almost the same as + +<code>hline/vline</code>, but there's an array of the coverage values. +These +functions are used when rendering solid Anti-Aliased polygons. +<br><br></p></td></tr></tbody></table> + + +<table width="640px" border="0" cellpadding="0" cellspacing="0"><tbody><tr><td><pre><span class="kw1">void</span> blend_color_hspan<span class="op">(</span><span class="kw1">int</span> x<span class="op">,</span> <span class="kw1">int</span> y<span class="op">,</span> <span class="kw1">unsigned</span> len<span class="op">,</span> + <span class="kw1">const</span> color_type<span class="op">*</span> colors<span class="op">,</span> <span class="kw1">const</span> <a href="http://www.antigrain.com/__code/include/agg_basics.h.html#int8u">int8u</a><span class="op">*</span> covers<span class="op">)</span><span class="op">;</span></pre></td></tr></tbody></table><font + style="margin-left: 1em;"><i></i></font> +<table width="640px" border="0" cellpadding="0" cellspacing="0"><tbody><tr><td><pre><span class="kw1">void</span> blend_color_vspan<span class="op">(</span><span class="kw1">int</span> x<span class="op">,</span> <span class="kw1">int</span> y<span class="op">,</span> <span class="kw1">unsigned</span> len<span class="op">,</span> + <span class="kw1">const</span> color_type<span class="op">*</span> colors<span class="op">,</span> <span class="kw1">const</span> <a href="http://www.antigrain.com/__code/include/agg_basics.h.html#int8u">int8u</a><span class="op">*</span> covers<span class="op">)</span><span class="op">;</span></pre></td></tr></tbody></table><font + style="margin-left: 1em;"><i></i></font> +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>Blend + a horizontal or a vertical color span. The functions are used +with different span generators, such as gradients, images, patterns, +Gouraud interpolation, etc. They accept an array of colors whose type +must be compatible with the used pixel format. For example, all +existing RGB pixel formats are compatible with the <a +href="http://www.antigrain.com/__code/include/agg_color_rgba.h.html#rgba8">rgba8</a> + type. +Argument <b>covers</b> is an array of the coverage values as in the +<code>blend_solid_hspan</code>. It's optional and can be 0. +<br><br></p></td></tr></tbody></table> + + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>Another + example is drawing of the solar spectrum. Class <a +href="http://www.antigrain.com/__code/include/agg_color_rgba.h.html#rgba">rgba</a>, + that keeps four +components as doubles, has static method <code>from_wavelength</code> +and the respective +constructor, class <a +href="http://www.antigrain.com/__code/include/agg_color_rgba.h.html#rgba8">rgba8</a> + can be constructed from <a +href="http://www.antigrain.com/__code/include/agg_color_rgba.h.html#rgba">rgba</a> + (it's a common policy +in <b>AGG</b> that any color type can be constructed from the <a +href="http://www.antigrain.com/__code/include/agg_color_rgba.h.html#rgba">rgba</a> + type). We will use it.</p></td></tr></tbody></table> + +<table width="640px" border="0" cellpadding="0" cellspacing="0"><tbody><tr><td><pre><span class="kw2">#include</span> <span class="op"><</span>stdio<span class="op">.</span>h<span class="op">></span> +<span class="kw2">#include</span> <span class="op"><</span>string<span class="op">.</span>h<span class="op">></span> +<span class="kw2">#include</span> <span class="str">"agg_pixfmt_rgb24.h"</span> + +<span class="kw1">enum</span> +<span class="op">{</span> + frame_width <span class="op">=</span> <span class="num">320</span><span class="op">,</span> + frame_height <span class="op">=</span> <span class="num">200</span> +<span class="op">}</span><span class="op">;</span> + +<span class="rem">// [...write_ppm is skipped...]</span> + +<span class="kw1">int</span> <span class="kw1">main</span><span class="op">(</span><span class="op">)</span> +<span class="op">{</span> + <span class="rem">//--------------------</span> + <span class="rem">// Allocate the buffer.</span> + <span class="rem">// Clear the buffer, for now "manually"</span> + <span class="rem">// Create the rendering buffer object</span> + <span class="rem">// Create the Pixel Format renderer</span> + <span class="rem">// Create one line (span) of type <a href="http://www.antigrain.com/__code/include/agg_color_rgba.h.html#rgba8">rgba8</a>.</span> + <span class="rem">// Fill the buffer using blend_color_span</span> + <span class="rem">// Write the buffer to agg_test.ppm</span> + <span class="rem">// Free memory</span> + + <span class="kw1">unsigned</span> <span class="kw1">char</span><span class="op">*</span> buffer <span class="op">=</span> <span class="kw1">new</span> <span class="kw1">unsigned</span> <span class="kw1">char</span><span class="op">[</span>frame_width <span class="op">*</span> frame_height <span class="op">*</span> <span class="num">3</span><span class="op">]</span><span class="op">;</span> + + memset<span class="op">(</span>buffer<span class="op">,</span> <span class="num">255</span><span class="op">,</span> frame_width <span class="op">*</span> frame_height <span class="op">*</span> <span class="num">3</span><span class="op">)</span><span class="op">;</span> + + agg::<a href="http://www.antigrain.com/doc/basic_renderers/basic_renderers.agdoc.html#rendering_buffer">rendering_buffer</a> rbuf<span class="op">(</span>buffer<span class="op">,</span> + frame_width<span class="op">,</span> + frame_height<span class="op">,</span> + frame_width <span class="op">*</span> <span class="num">3</span><span class="op">)</span><span class="op">;</span> + + agg::<a href="http://www.antigrain.com/__code/include/agg_pixfmt_rgb.h.html#pixfmt_rgb24">pixfmt_rgb24</a> pixf<span class="op">(</span>rbuf<span class="op">)</span><span class="op">;</span> + + agg::<a href="http://www.antigrain.com/__code/include/agg_color_rgba.h.html#rgba8">rgba8</a> span<span class="op">[</span>frame_width<span class="op">]</span><span class="op">;</span> + + <span class="kw1">unsigned</span> i<span class="op">;</span> + <span class="kw1">for</span><span class="op">(</span>i <span class="op">=</span> <span class="num">0</span><span class="op">;</span> i <span class="op"><</span> frame_width<span class="op">;</span> <span class="op">++</span>i<span class="op">)</span> + <span class="op">{</span> + agg::<a href="http://www.antigrain.com/__code/include/agg_color_rgba.h.html#rgba">rgba</a> c<span class="op">(</span><span class="num">380</span><span class="op">.</span><span class="num">0</span> <span class="op">+</span> <span class="num">400</span><span class="op">.</span><span class="num">0</span> <span class="op">*</span> i <span class="op">/</span> frame_width<span class="op">,</span> <span class="num">0</span><span class="op">.</span><span class="num">8</span><span class="op">)</span><span class="op">;</span> + span<span class="op">[</span>i<span class="op">]</span> <span class="op">=</span> agg::<a href="http://www.antigrain.com/__code/include/agg_color_rgba.h.html#rgba8">rgba8</a><span class="op">(</span>c<span class="op">)</span><span class="op">;</span> + <span class="op">}</span> + + <span class="kw1">for</span><span class="op">(</span>i <span class="op">=</span> <span class="num">0</span><span class="op">;</span> i <span class="op"><</span> frame_height<span class="op">;</span> <span class="op">++</span>i<span class="op">)</span> + <span class="op">{</span> + pixf<span class="op">.</span>blend_color_hspan<span class="op">(</span><span class="num">0</span><span class="op">,</span> i<span class="op">,</span> frame_width<span class="op">,</span> span<span class="op">,</span> <span class="num">0</span><span class="op">)</span><span class="op">;</span> + <span class="op">}</span> + + + write_ppm<span class="op">(</span>buffer<span class="op">,</span> frame_width<span class="op">,</span> frame_height<span class="op">,</span> <span class="str">"agg_test.ppm"</span><span class="op">)</span><span class="op">;</span> + + <span class="kw1">delete</span> <span class="op">[</span><span class="op">]</span> buffer<span class="op">;</span> + <span class="kw1">return</span> <span class="num">0</span><span class="op">;</span> +<span class="op">}</span> +</pre></td></tr></tbody></table><font style="margin-left: 1em;"><i></i></font> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>Here + is the result:</p></td></tr></tbody></table> + +<table width="640px"><tbody><tr><td><center><img +src="basic_renderers.agdoc_files/spectrum.png" title="" border="0"><br><i></i></center></td></tr></tbody></table> + + +<h3>Alpha-Mask Adaptor<a name="toc0008"></a></h3> + +<a name="pixfmt_amask_adaptor"><b></b></a> +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>Alpha-mask + is a separate buffer that is usually used to +perform clipping to an arbitrary shape at the low level. +There is a special adapter class that passes all calls to pixel format +renderes +through the alpha-mask filter. Usually alpha-mask is a gray scale buffer + +(one byte per pixel) of the same size as the main rendering buffer. Each +pixel in the alpha-mask deternines an additional pixel coverage value +that +is mixed with the main one. Functions like <code>copy_hline()</code>, +that do not +have a coverage value argument translate the calls to the respective +functions with this argument. For example, <code>copy_hline()</code> +takes the +horizontal span from the alpha mask buffer and then calls +<code>blend_solid_hspan()</code>.</p></td></tr></tbody></table> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>Include + files:</p></td></tr></tbody></table> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p><code>#include + "<a +href="http://www.antigrain.com/__code/include/agg_pixfmt_amask_adaptor.h.html">agg_pixfmt_amask_adaptor.h</a>"<br> +#include "<a +href="http://www.antigrain.com/__code/include/agg_alpha_mask_u8.h.html">agg_alpha_mask_u8.h</a>"<br></code></p></td></tr></tbody></table> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>Below + is an example of how to declare the pixel format renderer with the +alpha-mask adaptor.</p></td></tr></tbody></table> + +<table width="640px" border="0" cellpadding="0" cellspacing="0"><tbody><tr><td><pre><span class="kw2">#include</span> <span class="str">"agg_pixfmt_rgb24.h"</span> +<span class="kw2">#include</span> <span class="str">"<a href="http://www.antigrain.com/__code/include/agg_pixfmt_amask_adaptor.h.html">agg_pixfmt_amask_adaptor.h</a>"</span> +<span class="kw2">#include</span> <span class="str">"<a href="http://www.antigrain.com/__code/include/agg_alpha_mask_u8.h.html">agg_alpha_mask_u8.h</a>"</span> + +<span class="rem">//. . .</span> + + <span class="rem">// Allocate the alpha-mask buffer, create the rendering buffer object</span> + <span class="rem">// and create the alpha-mask object.</span> + <span class="rem">//--------------------------------</span> + agg::<a href="http://www.antigrain.com/__code/include/agg_basics.h.html#int8u">int8u</a><span class="op">*</span> amask_buf <span class="op">=</span> <span class="kw1">new</span> agg::<a href="http://www.antigrain.com/__code/include/agg_basics.h.html#int8u">int8u</a><span class="op">[</span>frame_width <span class="op">*</span> frame_height<span class="op">]</span><span class="op">;</span> + agg::<a href="http://www.antigrain.com/doc/basic_renderers/basic_renderers.agdoc.html#rendering_buffer">rendering_buffer</a> amask_rbuf<span class="op">(</span>amask_buf<span class="op">,</span> + frame_width<span class="op">,</span> + frame_height<span class="op">,</span> + frame_width<span class="op">)</span><span class="op">;</span> + agg::<a href="http://www.antigrain.com/__code/include/agg_alpha_mask_u8.h.html#amask_no_clip_gray8">amask_no_clip_gray8</a> amask<span class="op">(</span>amask_rbuf<span class="op">)</span><span class="op">;</span> + + <span class="rem">// Create the alpha-mask adaptor attached to the alpha-mask object</span> + <span class="rem">// and the pixel format renderer. Here pixf is a previously</span> + <span class="rem">// created pixel format renderer of type agg::<a href="http://www.antigrain.com/__code/include/agg_pixfmt_rgb.h.html#pixfmt_rgb24">pixfmt_rgb24</a>.</span> + agg::<a href="http://www.antigrain.com/doc/basic_renderers/basic_renderers.agdoc.html#pixfmt_amask_adaptor">pixfmt_amask_adaptor</a><span class="op"><</span>agg::<a href="http://www.antigrain.com/__code/include/agg_pixfmt_rgb.h.html#pixfmt_rgb24">pixfmt_rgb24</a><span class="op">,</span> + agg::<a href="http://www.antigrain.com/__code/include/agg_alpha_mask_u8.h.html#amask_no_clip_gray8">amask_no_clip_gray8</a><span class="op">></span> pixf_amask<span class="op">(</span>pixf<span class="op">,</span> amask<span class="op">)</span><span class="op">;</span> + <span class="rem">//. . .</span> +</pre></td></tr></tbody></table><font style="margin-left: 1em;"><i></i></font> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>Note + that here we use <a +href="http://www.antigrain.com/__code/include/agg_alpha_mask_u8.h.html#amask_no_clip_gray8">amask_no_clip_gray8</a> + that doesn't perform clipping. +It's because we use the main and the alpha-mask buffers of exactly same +size, +so, if there are no memory violations in the main rendering buffer, +there +will be no memory violations in the alpha mask buffer either. Clipping +is performed at the higher level. If your alpha-mask buffer is less than + +the main one you will have to use <a +href="http://www.antigrain.com/__code/include/agg_alpha_mask_u8.h.html#alpha_mask_gray8">alpha_mask_gray8</a> + instead.</p></td></tr></tbody></table> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>Below + is a complete example.</p></td></tr></tbody></table> + +<table width="640px" border="0" cellpadding="0" cellspacing="0"><tbody><tr><td><pre><span class="kw2">#include</span> <span class="op"><</span>stdio<span class="op">.</span>h<span class="op">></span> +<span class="kw2">#include</span> <span class="op"><</span>string<span class="op">.</span>h<span class="op">></span> +<span class="kw2">#include</span> <span class="str">"agg_pixfmt_rgb24.h"</span> +<span class="kw2">#include</span> <span class="str">"<a href="http://www.antigrain.com/__code/include/agg_pixfmt_amask_adaptor.h.html">agg_pixfmt_amask_adaptor.h</a>"</span> +<span class="kw2">#include</span> <span class="str">"<a href="http://www.antigrain.com/__code/include/agg_alpha_mask_u8.h.html">agg_alpha_mask_u8.h</a>"</span> + +<span class="kw1">enum</span> +<span class="op">{</span> + frame_width <span class="op">=</span> <span class="num">320</span><span class="op">,</span> + frame_height <span class="op">=</span> <span class="num">200</span> +<span class="op">}</span><span class="op">;</span> + +<span class="rem">// [...write_ppm is skipped...]</span> + +<span class="kw1">int</span> <span class="kw1">main</span><span class="op">(</span><span class="op">)</span> +<span class="op">{</span> + <span class="rem">// Allocate the main rendering buffer and clear it, for now "manually",</span> + <span class="rem">// and create the <a href="http://www.antigrain.com/doc/basic_renderers/basic_renderers.agdoc.html#rendering_buffer">rendering_buffer</a> object and the pixel format renderer</span> + <span class="rem">//--------------------------------</span> + agg::<a href="http://www.antigrain.com/__code/include/agg_basics.h.html#int8u">int8u</a><span class="op">*</span> buffer <span class="op">=</span> <span class="kw1">new</span> agg::<a href="http://www.antigrain.com/__code/include/agg_basics.h.html#int8u">int8u</a><span class="op">[</span>frame_width <span class="op">*</span> frame_height <span class="op">*</span> <span class="num">3</span><span class="op">]</span><span class="op">;</span> + memset<span class="op">(</span>buffer<span class="op">,</span> <span class="num">255</span><span class="op">,</span> frame_width <span class="op">*</span> frame_height <span class="op">*</span> <span class="num">3</span><span class="op">)</span><span class="op">;</span> + agg::<a href="http://www.antigrain.com/doc/basic_renderers/basic_renderers.agdoc.html#rendering_buffer">rendering_buffer</a> rbuf<span class="op">(</span>buffer<span class="op">,</span> + frame_width<span class="op">,</span> + frame_height<span class="op">,</span> + frame_width <span class="op">*</span> <span class="num">3</span><span class="op">)</span><span class="op">;</span> + agg::<a href="http://www.antigrain.com/__code/include/agg_pixfmt_rgb.h.html#pixfmt_rgb24">pixfmt_rgb24</a> pixf<span class="op">(</span>rbuf<span class="op">)</span><span class="op">;</span> + + + <span class="rem">// Allocate the alpha-mask buffer, create the rendering buffer object</span> + <span class="rem">// and create the alpha-mask object.</span> + <span class="rem">//--------------------------------</span> + agg::<a href="http://www.antigrain.com/__code/include/agg_basics.h.html#int8u">int8u</a><span class="op">*</span> amask_buf <span class="op">=</span> <span class="kw1">new</span> agg::<a href="http://www.antigrain.com/__code/include/agg_basics.h.html#int8u">int8u</a><span class="op">[</span>frame_width <span class="op">*</span> frame_height<span class="op">]</span><span class="op">;</span> + agg::<a href="http://www.antigrain.com/doc/basic_renderers/basic_renderers.agdoc.html#rendering_buffer">rendering_buffer</a> amask_rbuf<span class="op">(</span>amask_buf<span class="op">,</span> + frame_width<span class="op">,</span> + frame_height<span class="op">,</span> + frame_width<span class="op">)</span><span class="op">;</span> + agg::<a href="http://www.antigrain.com/__code/include/agg_alpha_mask_u8.h.html#amask_no_clip_gray8">amask_no_clip_gray8</a> amask<span class="op">(</span>amask_rbuf<span class="op">)</span><span class="op">;</span> + + <span class="rem">// Create the alpha-mask adaptor attached to the alpha-mask object</span> + <span class="rem">// and the pixel format renderer</span> + agg::<a href="http://www.antigrain.com/doc/basic_renderers/basic_renderers.agdoc.html#pixfmt_amask_adaptor">pixfmt_amask_adaptor</a><span class="op"><</span>agg::<a href="http://www.antigrain.com/__code/include/agg_pixfmt_rgb.h.html#pixfmt_rgb24">pixfmt_rgb24</a><span class="op">,</span> + agg::<a href="http://www.antigrain.com/__code/include/agg_alpha_mask_u8.h.html#amask_no_clip_gray8">amask_no_clip_gray8</a><span class="op">></span> pixf_amask<span class="op">(</span>pixf<span class="op">,</span> amask<span class="op">)</span><span class="op">;</span> + + + <span class="rem">// Draw something in the alpha-mask buffer. </span> + <span class="rem">// In this case we fill the buffer with a simple verical gradient</span> + <span class="kw1">unsigned</span> i<span class="op">;</span> + <span class="kw1">for</span><span class="op">(</span>i <span class="op">=</span> <span class="num">0</span><span class="op">;</span> i <span class="op"><</span> frame_height<span class="op">;</span> <span class="op">++</span>i<span class="op">)</span> + <span class="op">{</span> + <span class="kw1">unsigned</span> val <span class="op">=</span> <span class="num">255</span> <span class="op">*</span> i <span class="op">/</span> frame_height<span class="op">;</span> + memset<span class="op">(</span>amask_rbuf<span class="op">.</span>row_ptr<span class="op">(</span>i<span class="op">)</span><span class="op">,</span> val<span class="op">,</span> frame_width<span class="op">)</span><span class="op">;</span> + <span class="op">}</span> + + + <span class="rem">// Draw the spectrum, write a .ppm and free memory</span> + <span class="rem">//----------------------</span> + agg::<a href="http://www.antigrain.com/__code/include/agg_color_rgba.h.html#rgba8">rgba8</a> span<span class="op">[</span>frame_width<span class="op">]</span><span class="op">;</span> + + <span class="kw1">for</span><span class="op">(</span>i <span class="op">=</span> <span class="num">0</span><span class="op">;</span> i <span class="op"><</span> frame_width<span class="op">;</span> <span class="op">++</span>i<span class="op">)</span> + <span class="op">{</span> + agg::<a href="http://www.antigrain.com/__code/include/agg_color_rgba.h.html#rgba">rgba</a> c<span class="op">(</span><span class="num">380</span><span class="op">.</span><span class="num">0</span> <span class="op">+</span> <span class="num">400</span><span class="op">.</span><span class="num">0</span> <span class="op">*</span> i <span class="op">/</span> frame_width<span class="op">,</span> <span class="num">0</span><span class="op">.</span><span class="num">8</span><span class="op">)</span><span class="op">;</span> + span<span class="op">[</span>i<span class="op">]</span> <span class="op">=</span> agg::<a href="http://www.antigrain.com/__code/include/agg_color_rgba.h.html#rgba8">rgba8</a><span class="op">(</span>c<span class="op">)</span><span class="op">;</span> + <span class="op">}</span> + + <span class="kw1">for</span><span class="op">(</span>i <span class="op">=</span> <span class="num">0</span><span class="op">;</span> i <span class="op"><</span> frame_height<span class="op">;</span> <span class="op">++</span>i<span class="op">)</span> + <span class="op">{</span> + pixf_amask<span class="op">.</span>blend_color_hspan<span class="op">(</span><span class="num">0</span><span class="op">,</span> i<span class="op">,</span> frame_width<span class="op">,</span> span<span class="op">,</span> <span class="num">0</span><span class="op">)</span><span class="op">;</span> + <span class="op">}</span> + + write_ppm<span class="op">(</span>buffer<span class="op">,</span> frame_width<span class="op">,</span> frame_height<span class="op">,</span> <span class="str">"agg_test.ppm"</span><span class="op">)</span><span class="op">;</span> + + <span class="kw1">delete</span> <span class="op">[</span><span class="op">]</span> amask_buf<span class="op">;</span> + <span class="kw1">delete</span> <span class="op">[</span><span class="op">]</span> buffer<span class="op">;</span> + <span class="kw1">return</span> <span class="num">0</span><span class="op">;</span> +<span class="op">}</span> +</pre></td></tr></tbody></table><font style="margin-left: 1em;"><i></i></font> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>And +the result:</p></td></tr></tbody></table> + +<table width="640px"><tbody><tr><td><center><img +src="basic_renderers.agdoc_files/spectrum_amask1.png" title="" +border="0"><br><i></i></center></td></tr></tbody></table> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>Note + that we cleared the main buffer with the white color. Now change +</p></td></tr></tbody></table><table width="640px" border="0" +cellpadding="0" cellspacing="0"><tbody><tr><td><pre> memset<span class="op">(</span>buffer<span class="op">,</span> <span class="num">255</span><span class="op">,</span> frame_width <span class="op">*</span> frame_height <span class="op">*</span> <span class="num">3</span><span class="op">)</span><span class="op">;</span> +</pre></td></tr></tbody></table><font style="margin-left: 1em;"><i></i></font> +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>to +</p></td></tr></tbody></table><table width="640px" border="0" +cellpadding="0" cellspacing="0"><tbody><tr><td><pre> memset<span class="op">(</span>buffer<span class="op">,</span> <span class="num">0</span><span class="op">,</span> frame_width <span class="op">*</span> frame_height <span class="op">*</span> <span class="num">3</span><span class="op">)</span><span class="op">;</span> +</pre></td></tr></tbody></table><font style="margin-left: 1em;"><i></i></font> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>The +result:</p></td></tr></tbody></table> + +<table width="640px"><tbody><tr><td><center><img +src="basic_renderers.agdoc_files/spectrum_amask2.png" title="" +border="0"><br><i></i></center></td></tr></tbody></table> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>In +other words, the alpha-mask works as a separete alpha-channel +mixed with rendered primitives. +The fact that it contains 8-bit values allows you to clip +all drawing to arbitrary shapes with perfect <b><nobr>Anti-Aliasing</nobr></b>.</p></td></tr></tbody></table> + + +<br><h2>Basic Renderers<a name="toc0009"></a></h2> + +<a name="renderer_base"><b></b></a> <a name="renderer_mclip"><b></b></a> +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>There + are two basic renderers with almost the same functionality: +<a +href="http://www.antigrain.com/doc/basic_renderers/basic_renderers.agdoc.html#renderer_base">renderer_base</a> + and <a +href="http://www.antigrain.com/doc/basic_renderers/basic_renderers.agdoc.html#renderer_mclip">renderer_mclip</a>. + The first one is used most often +and it performs low level clipping. Clipping in general is a +complex task. In <b>AGG</b> there can be at least two levels of +clipping, +the low (pixel) level, and the high (vectorial) level. These classes +perform the pixel level clipping to protect the buffer from +<nobr>out-of-bound</nobr> memory access. Class <a +href="http://www.antigrain.com/doc/basic_renderers/basic_renderers.agdoc.html#renderer_mclip">renderer_mclip</a> + performs +clipping to multi-rectangle clipping areas, but its performance +depends on the number of clipping rectangles.</p></td></tr></tbody></table> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p><a +href="http://www.antigrain.com/doc/basic_renderers/basic_renderers.agdoc.html#renderer_base">renderer_base</a> + and <a +href="http://www.antigrain.com/doc/basic_renderers/basic_renderers.agdoc.html#renderer_mclip">renderer_mclip</a> + are class templates parametrized +with a pixel format renderer:</p></td></tr></tbody></table> + +<table width="640px" border="0" cellpadding="0" cellspacing="0"><tbody><tr><td><pre><span class="kw1">template</span><span class="op"><</span><span class="kw1">class</span> PixelFormat<span class="op">></span> <span class="kw1">class</span> <a href="http://www.antigrain.com/doc/basic_renderers/basic_renderers.agdoc.html#renderer_base">renderer_base</a> +<span class="op">{</span> +<span class="kw1">public</span>: + <span class="kw1">typedef</span> PixelFormat pixfmt_type<span class="op">;</span> + <span class="kw1">typedef</span> <span class="kw1">typename</span> pixfmt_type::color_type color_type<span class="op">;</span> + + <span class="op">.</span> <span class="op">.</span> <span class="op">.</span> +<span class="op">}</span><span class="op">;</span></pre></td></tr></tbody></table><font + style="margin-left: 1em;"><i></i></font> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>See +sources <a +href="http://www.antigrain.com/__code/include/agg_renderer_base.h.html#renderer_base">renderer_base</a> + <a +href="http://www.antigrain.com/__code/include/agg_renderer_mclip.h.html#renderer_mclip">renderer_mclip</a></p></td></tr></tbody></table> + +<h3>Creation<a name="toc0010"></a></h3> + +<table width="640px" border="0" cellpadding="0" cellspacing="0"><tbody><tr><td><pre><a href="http://www.antigrain.com/doc/basic_renderers/basic_renderers.agdoc.html#renderer_base">renderer_base</a><span class="op">(</span>pixfmt_type<span class="op">&</span> ren<span class="op">)</span><span class="op">;</span> +<a href="http://www.antigrain.com/doc/basic_renderers/basic_renderers.agdoc.html#renderer_mclip">renderer_mclip</a><span class="op">(</span>pixfmt_type<span class="op">&</span> ren<span class="op">)</span><span class="op">;</span></pre></td></tr></tbody></table><font + style="margin-left: 1em;"><i></i></font> +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>Both + classes accept a reference to the pixel format renderer. +<a +href="http://www.antigrain.com/doc/basic_renderers/basic_renderers.agdoc.html#renderer_mclip">renderer_mclip</a> + uses <a +href="http://www.antigrain.com/doc/basic_renderers/basic_renderers.agdoc.html#renderer_base">renderer_base</a><PixelFormat> + inside itself to +perform implemented clipping to a single rectangle region. +Note that you can use <a +href="http://www.antigrain.com/doc/basic_renderers/basic_renderers.agdoc.html#pixfmt_amask_adaptor">pixfmt_amask_adaptor</a> + as <code>PixelFormat</code> +template parameter.</p></td></tr></tbody></table> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>The +cost of creation is minimal, it's just initializing of the class +member variables. But <a +href="http://www.antigrain.com/doc/basic_renderers/basic_renderers.agdoc.html#renderer_mclip">renderer_mclip</a> + allocates memory when you +add new clipping rectangles and deallocates it when destroying. +It uses the pod_deque class that allocates blocks of memory of equal +size and never reallocates it. When you reset clipping, the memory +is not deallocated, it's reused. The <a +href="http://www.antigrain.com/doc/basic_renderers/basic_renderers.agdoc.html#renderer_mclip">renderer_mclip</a> + deallocates +memory only when destroying. This technique is widely used in <b>AGG</b> + +and prevents from deep memory fragmentation.</p></td></tr></tbody></table> + + +<h3>Member Functions<a name="toc0011"></a></h3> + +<table width="640px" border="0" cellpadding="0" cellspacing="0"><tbody><tr><td><pre><span class="kw1">const</span> pixfmt_type<span class="op">&</span> ren<span class="op">(</span><span class="op">)</span> <span class="kw1">const</span><span class="op">;</span> +pixfmt_type<span class="op">&</span> ren<span class="op">(</span><span class="op">)</span><span class="op">;</span></pre></td></tr></tbody></table><font + style="margin-left: 1em;"><i></i></font> +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>Returns + a reference to the pixel format renderer. +<br><br></p></td></tr></tbody></table> + +<table width="640px" border="0" cellpadding="0" cellspacing="0"><tbody><tr><td><pre><span class="kw1">unsigned</span> width<span class="op">(</span><span class="op">)</span> <span class="kw1">const</span><span class="op">;</span> +<span class="kw1">unsigned</span> height<span class="op">(</span><span class="op">)</span> <span class="kw1">const</span><span class="op">;</span></pre></td></tr></tbody></table><font + style="margin-left: 1em;"><i></i></font> +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>Returns + width and height of the rendering buffer. +<br><br></p></td></tr></tbody></table> + +<table width="640px" border="0" cellpadding="0" cellspacing="0"><tbody><tr><td><pre><span class="kw1">void</span> reset_clipping<span class="op">(</span><span class="kw1">bool</span> visibility<span class="op">)</span><span class="op">;</span></pre></td></tr></tbody></table><font + style="margin-left: 1em;"><i></i></font> +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>The +function resets the clipping. If the <code>visibility</code> is <code>true</code> + the +clipping box is set to <code>(0, 0, width()-1, height()-1)</code>, if <code>false</code>, +it sets an invisible box, i.e., <code>(1,1,0,0)</code>. In <a +href="http://www.antigrain.com/doc/basic_renderers/basic_renderers.agdoc.html#renderer_mclip">renderer_mclip</a> + this +function also removes all the clipping areas that were previously +added. +</p></td></tr></tbody></table><table class="warning" width="640px"><tbody><tr><td><b>IMPORTANT!</b><br> +If you attach another memory buffer to the <a +href="http://www.antigrain.com/doc/basic_renderers/basic_renderers.agdoc.html#rendering_buffer">rendering_buffer</a>, + connected +with this particular basic renderer, you <b>must</b> call +<code>reset_clipping</code>, otherwise, the clipping box will be not +valid. +It's because there's no any “feedback” from +the rendering buffer to the renderers, in other words, <a +href="http://www.antigrain.com/doc/basic_renderers/basic_renderers.agdoc.html#renderer_base">renderer_base</a> + +and <a +href="http://www.antigrain.com/doc/basic_renderers/basic_renderers.agdoc.html#renderer_mclip">renderer_mclip</a> + don't know anything if the rendering buffer is +changed. Having some mechanism of events or delegates would be +an overkill in this case.</td></tr></tbody></table> +<table width="640px"><tbody><tr><td style="text-align: justify;"><p><br></p></td></tr></tbody></table> + +<table width="640px" border="0" cellpadding="0" cellspacing="0"><tbody><tr><td><pre><span class="kw1">bool</span> clip_box<span class="op">(</span><span class="kw1">int</span> x1<span class="op">,</span> <span class="kw1">int</span> y1<span class="op">,</span> <span class="kw1">int</span> x2<span class="op">,</span> <span class="kw1">int</span> y2<span class="op">)</span><span class="op">;</span></pre></td></tr></tbody></table><font + style="margin-left: 1em;"><i></i></font> +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>Set +new clipping box. Only <a +href="http://www.antigrain.com/doc/basic_renderers/basic_renderers.agdoc.html#renderer_base">renderer_base</a> + has this function. +The clipping box <b>includes</b> the boundaries, so that, the maximal +one is <code>(0, 0, width()-1, height()-1)</code>. The clipping box +is clipped to the maximal value before setting, so that, it's +safe to set a box bigger than <code>(0, 0, width()-1, height()-1)</code>. +<br><br></p></td></tr></tbody></table> + +<table width="640px" border="0" cellpadding="0" cellspacing="0"><tbody><tr><td><pre><span class="kw1">void</span> add_clip_box<span class="op">(</span><span class="kw1">int</span> x1<span class="op">,</span> <span class="kw1">int</span> y1<span class="op">,</span> <span class="kw1">int</span> x2<span class="op">,</span> <span class="kw1">int</span> y2<span class="op">)</span><span class="op">;</span></pre></td></tr></tbody></table><font + style="margin-left: 1em;"><i></i></font> +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>Add +new clipping box. Only <a +href="http://www.antigrain.com/doc/basic_renderers/basic_renderers.agdoc.html#renderer_mclip">renderer_mclip</a> + has this function. +You can add any number of rectangular regions, but they must not +overlap. In case of overlapping areas, some elements can be drawn +twice or more. The clipping boxes are being clipped by the bounding +box <code>(0, 0, width()-1, height()-1)</code> before adding, which is +done +for the sake of efficiency. It also means that calling +<code>reset_clipping(false)</code> for the <a +href="http://www.antigrain.com/doc/basic_renderers/basic_renderers.agdoc.html#renderer_mclip">renderer_mclip</a> + doesn't make +any sense because all adding regions will be clipped by an +invisible area and will not be actually added. The visible areas +also includes the boundaries of the boxes, that is, +<code>add_clip_box(100,100,100,100)</code> will add a clipping region +of 1 pixel size. +<br><br></p></td></tr></tbody></table> + +<table width="640px" border="0" cellpadding="0" cellspacing="0"><tbody><tr><td><pre><span class="kw1">void</span> clip_box_naked<span class="op">(</span><span class="kw1">int</span> x1<span class="op">,</span> <span class="kw1">int</span> y1<span class="op">,</span> <span class="kw1">int</span> x2<span class="op">,</span> <span class="kw1">int</span> y2<span class="op">)</span><span class="op">;</span></pre></td></tr></tbody></table><font + style="margin-left: 1em;"><i></i></font> +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>Only + <a +href="http://www.antigrain.com/doc/basic_renderers/basic_renderers.agdoc.html#renderer_base">renderer_base</a> + has this function. Set new clipping box without +clipping to the rendering buffer size. This function is unsafe +and used in the <a +href="http://www.antigrain.com/doc/basic_renderers/basic_renderers.agdoc.html#renderer_mclip">renderer_mclip</a> + for fast switching between +partial regions when rendering. The purpose of this function +is just to avoid extra overhead. +<br><br></p></td></tr></tbody></table> + +<table width="640px" border="0" cellpadding="0" cellspacing="0"><tbody><tr><td><pre><span class="kw1">bool</span> inbox<span class="op">(</span><span class="kw1">int</span> x<span class="op">,</span> <span class="kw1">int</span> y<span class="op">)</span> <span class="kw1">const</span><span class="op">;</span></pre></td></tr></tbody></table><font + style="margin-left: 1em;"><i></i></font> +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>Check + if point <code>(x, y)</code> is inside of the clipping box. +Only <a +href="http://www.antigrain.com/doc/basic_renderers/basic_renderers.agdoc.html#renderer_base">renderer_base</a> + has this function. +<br><br></p></td></tr></tbody></table> + +<table width="640px" border="0" cellpadding="0" cellspacing="0"><tbody><tr><td><pre><span class="kw1">void</span> first_clip_box<span class="op">(</span><span class="op">)</span><span class="op">;</span> +<span class="kw1">bool</span> next_clip_box<span class="op">(</span><span class="op">)</span><span class="op">;</span></pre></td></tr></tbody></table><font + style="margin-left: 1em;"><i></i></font> +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>These + two functions are used to enumerate all the clipping regions +of the renderer. In the <a +href="http://www.antigrain.com/doc/basic_renderers/basic_renderers.agdoc.html#renderer_base">renderer_base</a> + class they are empty, +<code>next_clip_box()</code> always return false. +<br><br></p></td></tr></tbody></table> + +<table width="640px" border="0" cellpadding="0" cellspacing="0"><tbody><tr><td><pre><span class="kw1">const</span> rect<span class="op">&</span> clip_box<span class="op">(</span><span class="op">)</span> <span class="kw1">const</span><span class="op">;</span> +<span class="kw1">int</span> xmin<span class="op">(</span><span class="op">)</span> <span class="kw1">const</span><span class="op">;</span> +<span class="kw1">int</span> ymin<span class="op">(</span><span class="op">)</span> <span class="kw1">const</span><span class="op">;</span> +<span class="kw1">int</span> xmax<span class="op">(</span><span class="op">)</span> <span class="kw1">const</span><span class="op">;</span> +<span class="kw1">int</span> ymax<span class="op">(</span><span class="op">)</span> <span class="kw1">const</span><span class="op">;</span></pre></td></tr></tbody></table><font + style="margin-left: 1em;"><i></i></font> +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>Returns + the clipping box as a rectangle and as separate integer +values. In <a +href="http://www.antigrain.com/doc/basic_renderers/basic_renderers.agdoc.html#renderer_mclip">renderer_mclip</a> + the functions always return +<code>(0, 0, width()-1, height()-1)</code>. +<br><br></p></td></tr></tbody></table> + +<table width="640px" border="0" cellpadding="0" cellspacing="0"><tbody><tr><td><pre><span class="kw1">const</span> rect<span class="op">&</span> bounding_clip_box<span class="op">(</span><span class="op">)</span> <span class="kw1">const</span><span class="op">;</span> +<span class="kw1">int</span> bounding_xmin<span class="op">(</span><span class="op">)</span> <span class="kw1">const</span><span class="op">;</span> +<span class="kw1">int</span> bounding_ymin<span class="op">(</span><span class="op">)</span> <span class="kw1">const</span><span class="op">;</span> +<span class="kw1">int</span> bounding_xmax<span class="op">(</span><span class="op">)</span> <span class="kw1">const</span><span class="op">;</span> +<span class="kw1">int</span> bounding_ymax<span class="op">(</span><span class="op">)</span> <span class="kw1">const</span><span class="op">;</span></pre></td></tr></tbody></table><font + style="margin-left: 1em;"><i></i></font> +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>Returns + the bounding clipping box as a rectangle and as separate +integer values. In <a +href="http://www.antigrain.com/doc/basic_renderers/basic_renderers.agdoc.html#renderer_base">renderer_base</a> + the functions always return +the same values as the respective ones from the previous group. +In <a +href="http://www.antigrain.com/doc/basic_renderers/basic_renderers.agdoc.html#renderer_mclip">renderer_mclip</a> + they return the bounding box calculated +on the basis of added regions. +<br><br></p></td></tr></tbody></table> + +<table width="640px" border="0" cellpadding="0" cellspacing="0"><tbody><tr><td><pre><span class="kw1">void</span> clear<span class="op">(</span><span class="kw1">const</span> color_type<span class="op">&</span> c<span class="op">)</span><span class="op">;</span></pre></td></tr></tbody></table><font + style="margin-left: 1em;"><i></i></font> +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>Clears + the buffer with the given color without clipping. +<br><br></p></td></tr></tbody></table> + +<table width="640px" border="0" cellpadding="0" cellspacing="0"><tbody><tr><td><pre><span class="kw1">void</span> copy_pixel<span class="op">(</span><span class="kw1">int</span> x<span class="op">,</span> <span class="kw1">int</span> y<span class="op">,</span> <span class="kw1">const</span> color_type<span class="op">&</span> c<span class="op">)</span><span class="op">;</span></pre></td></tr></tbody></table><font + style="margin-left: 1em;"><i></i></font> +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>Set a + pixel with clipping. +<br><br></p></td></tr></tbody></table> + +<table width="640px" border="0" cellpadding="0" cellspacing="0"><tbody><tr><td><pre><span class="kw1">void</span> blend_pixel<span class="op">(</span><span class="kw1">int</span> x<span class="op">,</span> <span class="kw1">int</span> y<span class="op">,</span> <span class="kw1">const</span> color_type<span class="op">&</span> c<span class="op">,</span> <a href="http://www.antigrain.com/__code/include/agg_basics.h.html#cover_type">cover_type</a> cover<span class="op">)</span><span class="op">;</span></pre></td></tr></tbody></table><font + style="margin-left: 1em;"><i></i></font> +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>Blend + a pixel with clipping. The behavior is the same as in the pixel +format renderers (<a +href="http://www.antigrain.com/doc/basic_renderers/basic_renderers.agdoc.html#pixfmt">pixfmt</a>). +<br><br></p></td></tr></tbody></table> + +<table width="640px" border="0" cellpadding="0" cellspacing="0"><tbody><tr><td><pre>color_type pixel<span class="op">(</span><span class="kw1">int</span> x<span class="op">,</span> <span class="kw1">int</span> y<span class="op">)</span> <span class="kw1">const</span><span class="op">;</span></pre></td></tr></tbody></table><font + style="margin-left: 1em;"><i></i></font> +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>Returns + the value of the pixel with coordinates <code>(x, y)</code>. If the +point +is clipped, the function returns <code>color_type::no_color()</code>. +For <a +href="http://www.antigrain.com/__code/include/agg_color_rgba.h.html#rgba8">rgba8</a> +it's <code>(0,0,0,0)</code>. +<br><br></p></td></tr></tbody></table> + +<table width="640px" border="0" cellpadding="0" cellspacing="0"><tbody><tr><td><pre><span class="kw1">void</span> copy_hline<span class="op">(</span><span class="kw1">int</span> x1<span class="op">,</span> <span class="kw1">int</span> y<span class="op">,</span> <span class="kw1">int</span> x2<span class="op">,</span> <span class="kw1">const</span> color_type<span class="op">&</span> c<span class="op">)</span><span class="op">;</span> +<span class="kw1">void</span> copy_vline<span class="op">(</span><span class="kw1">int</span> x<span class="op">,</span> <span class="kw1">int</span> y1<span class="op">,</span> <span class="kw1">int</span> y2<span class="op">,</span> <span class="kw1">const</span> color_type<span class="op">&</span> c<span class="op">)</span><span class="op">;</span> + +<span class="kw1">void</span> blend_hline<span class="op">(</span><span class="kw1">int</span> x1<span class="op">,</span> <span class="kw1">int</span> y<span class="op">,</span> <span class="kw1">int</span> x2<span class="op">,</span> + <span class="kw1">const</span> color_type<span class="op">&</span> c<span class="op">,</span> <a href="http://www.antigrain.com/__code/include/agg_basics.h.html#cover_type">cover_type</a> cover<span class="op">)</span><span class="op">;</span> + +<span class="kw1">void</span> blend_vline<span class="op">(</span><span class="kw1">int</span> x<span class="op">,</span> <span class="kw1">int</span> y1<span class="op">,</span> <span class="kw1">int</span> y2<span class="op">,</span> + <span class="kw1">const</span> color_type<span class="op">&</span> c<span class="op">,</span> <a href="http://www.antigrain.com/__code/include/agg_basics.h.html#cover_type">cover_type</a> cover<span class="op">)</span><span class="op">;</span></pre></td></tr></tbody></table><font + style="margin-left: 1em;"><i></i></font> +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>Draw + (copy) or blend horizontal or vertical line of pixels. +The behaviour is the same as in pixel format renders +(<a +href="http://www.antigrain.com/doc/basic_renderers/basic_renderers.agdoc.html#pixfmt">pixfmt</a>), + but here you use coordinates of the begin and end +of the lines instead of <code>(x, y, length)</code>. +<br><br></p></td></tr></tbody></table> + +<table width="640px" border="0" cellpadding="0" cellspacing="0"><tbody><tr><td><pre><span class="kw1">void</span> copy_bar<span class="op">(</span><span class="kw1">int</span> x1<span class="op">,</span> <span class="kw1">int</span> y1<span class="op">,</span> <span class="kw1">int</span> x2<span class="op">,</span> <span class="kw1">int</span> y2<span class="op">,</span> <span class="kw1">const</span> color_type<span class="op">&</span> c<span class="op">)</span><span class="op">;</span> +<span class="kw1">void</span> blend_bar<span class="op">(</span><span class="kw1">int</span> x1<span class="op">,</span> <span class="kw1">int</span> y1<span class="op">,</span> <span class="kw1">int</span> x2<span class="op">,</span> <span class="kw1">int</span> y2<span class="op">,</span> + <span class="kw1">const</span> color_type<span class="op">&</span> c<span class="op">,</span> <a href="http://www.antigrain.com/__code/include/agg_basics.h.html#cover_type">cover_type</a> cover<span class="op">)</span><span class="op">;</span></pre></td></tr></tbody></table><font + style="margin-left: 1em;"><i></i></font> +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>Draw + (copy) or blend a solid bar (rectangle). +<br><br></p></td></tr></tbody></table> + +<table width="640px" border="0" cellpadding="0" cellspacing="0"><tbody><tr><td><pre><span class="kw1">void</span> blend_solid_hspan<span class="op">(</span><span class="kw1">int</span> x<span class="op">,</span> <span class="kw1">int</span> y<span class="op">,</span> <span class="kw1">int</span> len<span class="op">,</span> + <span class="kw1">const</span> color_type<span class="op">&</span> c<span class="op">,</span> <span class="kw1">const</span> <a href="http://www.antigrain.com/__code/include/agg_basics.h.html#cover_type">cover_type</a><span class="op">*</span> covers<span class="op">)</span><span class="op">;</span> + +<span class="kw1">void</span> blend_solid_vspan<span class="op">(</span><span class="kw1">int</span> x<span class="op">,</span> <span class="kw1">int</span> y<span class="op">,</span> <span class="kw1">int</span> len<span class="op">,</span> + <span class="kw1">const</span> color_type<span class="op">&</span> c<span class="op">,</span> <span class="kw1">const</span> <a href="http://www.antigrain.com/__code/include/agg_basics.h.html#cover_type">cover_type</a><span class="op">*</span> covers<span class="op">)</span><span class="op">;</span></pre></td></tr></tbody></table><font + style="margin-left: 1em;"><i></i></font> +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>Blend + a horizontal or a vertical solid-color span. +These functions are used when rendering solid Anti-Aliased polygons. +<br><br></p></td></tr></tbody></table> + + +<table width="640px" border="0" cellpadding="0" cellspacing="0"><tbody><tr><td><pre><span class="kw1">void</span> blend_color_hspan<span class="op">(</span><span class="kw1">int</span> x<span class="op">,</span> <span class="kw1">int</span> y<span class="op">,</span> <span class="kw1">int</span> len<span class="op">,</span> + <span class="kw1">const</span> color_type<span class="op">*</span> colors<span class="op">,</span> <span class="kw1">const</span> <a href="http://www.antigrain.com/__code/include/agg_basics.h.html#cover_type">cover_type</a><span class="op">*</span> covers<span class="op">)</span><span class="op">;</span> + +<span class="kw1">void</span> blend_color_vspan<span class="op">(</span><span class="kw1">int</span> x<span class="op">,</span> <span class="kw1">int</span> y<span class="op">,</span> <span class="kw1">int</span> len<span class="op">,</span> + <span class="kw1">const</span> color_type<span class="op">*</span> colors<span class="op">,</span> <span class="kw1">const</span> <a href="http://www.antigrain.com/__code/include/agg_basics.h.html#cover_type">cover_type</a><span class="op">*</span> covers<span class="op">)</span><span class="op">;</span></pre></td></tr></tbody></table><font + style="margin-left: 1em;"><i></i></font> +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>Blend + a horizontal or a vertical color span. The functions are used with +different span generators, such as gradients, images, patterns, +Gouraud interpolation, etc. They accept an array of colors whose +type must be compatible with the used pixel format. +<br><br></p></td></tr></tbody></table> + +<table width="640px" border="0" cellpadding="0" cellspacing="0"><tbody><tr><td><pre><span class="kw1">void</span> blend_color_hspan_no_clip<span class="op">(</span><span class="kw1">int</span> x<span class="op">,</span> <span class="kw1">int</span> y<span class="op">,</span> <span class="kw1">int</span> len<span class="op">,</span> + <span class="kw1">const</span> color_type<span class="op">*</span> colors<span class="op">,</span> + <span class="kw1">const</span> <a href="http://www.antigrain.com/__code/include/agg_basics.h.html#cover_type">cover_type</a><span class="op">*</span> covers<span class="op">)</span><span class="op">;</span> + +<span class="kw1">void</span> blend_color_vspan_no_clip<span class="op">(</span><span class="kw1">int</span> x<span class="op">,</span> <span class="kw1">int</span> y<span class="op">,</span> <span class="kw1">int</span> len<span class="op">,</span> + <span class="kw1">const</span> color_type<span class="op">*</span> colors<span class="op">,</span> + <span class="kw1">const</span> <a href="http://www.antigrain.com/__code/include/agg_basics.h.html#cover_type">cover_type</a><span class="op">*</span> covers<span class="op">)</span><span class="op">;</span></pre></td></tr></tbody></table><font + style="margin-left: 1em;"><i></i></font> +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>The +same as above, but without clipping. These functions are +used in the scanline renderers. The reason to do so is the performance. +Tne scanline consists of a number of spans and it's a little bit +more efficient to perform clipping when we have information about +the whole scanline rather than to clip every span, especially in +<a +href="http://www.antigrain.com/doc/basic_renderers/basic_renderers.agdoc.html#renderer_mclip">renderer_mclip</a>. +<br><br></p></td></tr></tbody></table> + +<table width="640px" border="0" cellpadding="0" cellspacing="0"><tbody><tr><td><pre><span class="kw1">void</span> copy_from<span class="op">(</span><span class="kw1">const</span> <a href="http://www.antigrain.com/doc/basic_renderers/basic_renderers.agdoc.html#rendering_buffer">rendering_buffer</a><span class="op">&</span> from<span class="op">,</span> + <span class="kw1">const</span> rect<span class="op">*</span> rc<span class="op">=</span><span class="num">0</span><span class="op">,</span> + <span class="kw1">int</span> x_to<span class="op">=</span><span class="num">0</span><span class="op">,</span> + <span class="kw1">int</span> y_to<span class="op">=</span><span class="num">0</span><span class="op">)</span><span class="op">;</span></pre></td></tr></tbody></table><font + style="margin-left: 1em;"><i></i></font> +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>Copy + a rectangular area of the buffer <code>from</code> to <code>this</code> + one +considering clipping. +It's assumed that the rendering buffer <code>from</code> has the same +pixel format as the destination <code>(this)</code> one. <code>rc</code> + is an +optional rectangle in the <code>from</code> buffer, <code>x_to</code> +and <code>y_to</code> — +the coordinates of the <code>rc->x1, rc->y1</code> mapped to the +destination +buffer. +<br><br></p></td></tr></tbody></table> + + + +<h3>A common example<a name="toc0012"></a></h3> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>The +code below is a very common example of declaring and using +of the rendring buffer and low level renderers.</p></td></tr></tbody></table> + +<table width="640px" border="0" cellpadding="0" cellspacing="0"><tbody><tr><td><pre> <span class="rem">// Typedefs of the low level renderers to simplify the declarations.</span> + <span class="rem">// Here you can use any other pixel format renderer and</span> + <span class="rem">// agg::<a href="http://www.antigrain.com/doc/basic_renderers/basic_renderers.agdoc.html#renderer_mclip">renderer_mclip</a> if necessary.</span> + <span class="rem">//--------------------------</span> + <span class="kw1">typedef</span> agg::<a href="http://www.antigrain.com/__code/include/agg_pixfmt_rgb.h.html#pixfmt_rgb24">pixfmt_rgb24</a> pixfmt_type<span class="op">;</span> + <span class="kw1">typedef</span> agg::<a href="http://www.antigrain.com/doc/basic_renderers/basic_renderers.agdoc.html#renderer_base">renderer_base</a><span class="op"><</span>agg::<a href="http://www.antigrain.com/__code/include/agg_pixfmt_rgb.h.html#pixfmt_rgb24">pixfmt_rgb24</a><span class="op">></span> renbase_type<span class="op">;</span> + <span class="kw1">enum</span> <span class="op">{</span> bytes_per_pixel <span class="op">=</span> <span class="num">3</span> <span class="op">}</span><span class="op">;</span> + + <span class="kw1">unsigned</span> <span class="kw1">char</span><span class="op">*</span> buffer <span class="op">=</span> <span class="kw1">new</span> <span class="kw1">unsigned</span> <span class="kw1">char</span><span class="op">[</span>frame_width <span class="op">*</span> + frame_height <span class="op">*</span> + bytes_per_pixel<span class="op">]</span><span class="op">;</span> + agg::<a href="http://www.antigrain.com/doc/basic_renderers/basic_renderers.agdoc.html#rendering_buffer">rendering_buffer</a> rbuf<span class="op">(</span>buffer<span class="op">,</span> + frame_width<span class="op">,</span> + frame_height<span class="op">,</span> + frame_width <span class="op">*</span> bytes_per_pixel<span class="op">)</span><span class="op">;</span> + + pixfmt_type pixf<span class="op">(</span>rbuf<span class="op">)</span><span class="op">;</span> + renbase_type rbase<span class="op">(</span>pixf<span class="op">)</span><span class="op">;</span> + + rbase<span class="op">.</span>clear<span class="op">(</span>clear_color<span class="op">)</span><span class="op">;</span> + + <span class="rem">//. . .</span> +</pre></td></tr></tbody></table><font style="margin-left: 1em;"><i></i></font> +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>At +last we can clear the buffer with certain color instead of +“manual” calling of <code>memset()</code> :-). +Also note that unlike these examples, the <code>stride</code> value is +not +obligatory equal to <code>frame_width * bytes_per_pixel</code>. Most +often +there will be some alignment requiremants, for example, the width +of Windows bitmaps must be a multiple of 4 bytes.</p></td></tr></tbody></table> + + + + + + + + + +<br><h2>Primitives and Markers Renderers<a name="toc0013"></a></h2> + + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>The +primitives and marker renderers were added to <b>AGG</b> to provide you a + +mecahnism of fast drawing regular, aliased objects, such as lines, +rectangles, and ellipses. The marker renderer can draw some shapes +commonly used in different scatter plots. If you are not going to use +it just skip this section.</p></td></tr></tbody></table> + +<h3>Primitives Renderer<a name="toc0014"></a></h3> + +<a name="renderer_primitives"><b></b></a> +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>The +header file: <a +href="http://www.antigrain.com/__code/include/agg_renderer_primitives.h.html">agg_renderer_primitives.h</a></p></td></tr></tbody></table> + +<h4>Declaration<a name="toc0015"></a></h4> +<table width="640px" border="0" cellpadding="0" cellspacing="0"><tbody><tr><td><pre><span class="kw1">template</span><span class="op"><</span><span class="kw1">class</span> BaseRenderer<span class="op">></span> <span class="kw1">class</span> <a href="http://www.antigrain.com/doc/basic_renderers/basic_renderers.agdoc.html#renderer_primitives">renderer_primitives</a> +<span class="op">{</span> +<span class="kw1">public</span>: + <span class="kw1">typedef</span> BaseRenderer base_ren_type<span class="op">;</span> + <span class="kw1">typedef</span> <span class="kw1">typename</span> base_ren_type::color_type color_type<span class="op">;</span> + <span class="rem">//. . .</span> +<span class="op">}</span><span class="op">;</span> +</pre></td></tr></tbody></table><font style="margin-left: 1em;"><i></i></font> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>Here + class RendererBase can be of type <a +href="http://www.antigrain.com/doc/basic_renderers/basic_renderers.agdoc.html#renderer_base">renderer_base</a> + or <a +href="http://www.antigrain.com/doc/basic_renderers/basic_renderers.agdoc.html#renderer_mclip">renderer_mclip</a>.</p></td></tr></tbody></table> + +<h4>Creation<a name="toc0016"></a></h4> + +<table width="640px" border="0" cellpadding="0" cellspacing="0"><tbody><tr><td><pre><a href="http://www.antigrain.com/doc/basic_renderers/basic_renderers.agdoc.html#renderer_primitives">renderer_primitives</a><span class="op">(</span>base_ren_type<span class="op">&</span> ren<span class="op">)</span> : + m_ren<span class="op">(</span><span class="op">&</span>ren<span class="op">)</span><span class="op">,</span> + m_fill_color<span class="op">(</span><span class="op">)</span><span class="op">,</span> + m_line_color<span class="op">(</span><span class="op">)</span><span class="op">,</span> + m_curr_x<span class="op">(</span><span class="num">0</span><span class="op">)</span><span class="op">,</span> + m_curr_y<span class="op">(</span><span class="num">0</span><span class="op">)</span> +<span class="op">{</span><span class="op">}</span> +</pre></td></tr></tbody></table><font style="margin-left: 1em;"><i></i></font> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>The +cost of creation is minimal, it's only initialization of the pointer +to the base renderer object, two colors and initial coordinates that are + +used in <code>move_to</code> and <code>line_to</code> functions.</p></td></tr></tbody></table> + +<h4>Member functions<a name="toc0017"></a></h4> + +<table width="640px" border="0" cellpadding="0" cellspacing="0"><tbody><tr><td><pre><span class="kw1">static</span> <span class="kw1">int</span> coord<span class="op">(</span><span class="kw1">double</span> c<span class="op">)</span><span class="op">;</span></pre></td></tr></tbody></table><font + style="margin-left: 1em;"><i></i></font> +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>Converts + a coordinate of the <code>double</code> type to integer one with +subpixel accuracy. It just multiplies the value to 256 (by default) +and returns the integer part. +<br><br></p></td></tr></tbody></table> + +<table width="640px" border="0" cellpadding="0" cellspacing="0"><tbody><tr><td><pre><span class="kw1">void</span> fill_color<span class="op">(</span><span class="kw1">const</span> color_type<span class="op">&</span> c<span class="op">)</span><span class="op">;</span> +<span class="kw1">void</span> line_color<span class="op">(</span><span class="kw1">const</span> color_type<span class="op">&</span> c<span class="op">)</span><span class="op">;</span> +<span class="kw1">const</span> color_type<span class="op">&</span> fill_color<span class="op">(</span><span class="op">)</span> <span class="kw1">const</span><span class="op">;</span> +<span class="kw1">const</span> color_type<span class="op">&</span> line_color<span class="op">(</span><span class="op">)</span> <span class="kw1">const</span><span class="op">;</span></pre></td></tr></tbody></table><font + style="margin-left: 1em;"><i></i></font> +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>Set +and get the fill and line colors. The colors may have +the alpha value that will take effect, i.e., the primitives +will be alpha-blended. +<br><br></p></td></tr></tbody></table> + +<table width="640px" border="0" cellpadding="0" cellspacing="0"><tbody><tr><td><pre><span class="kw1">void</span> rectangle<span class="op">(</span><span class="kw1">int</span> x1<span class="op">,</span> <span class="kw1">int</span> y1<span class="op">,</span> <span class="kw1">int</span> x2<span class="op">,</span> <span class="kw1">int</span> y2<span class="op">)</span><span class="op">;</span></pre></td></tr></tbody></table><font + style="margin-left: 1em;"><i></i></font> +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>Draw + a rectangle without filling with the line color. +There are regular, pixel coordinates are used. +The width of the border is always 1 pixel and cannot +be changed. +<br><br></p></td></tr></tbody></table> + +<table width="640px" border="0" cellpadding="0" cellspacing="0"><tbody><tr><td><pre><span class="kw1">void</span> solid_rectangle<span class="op">(</span><span class="kw1">int</span> x1<span class="op">,</span> <span class="kw1">int</span> y1<span class="op">,</span> <span class="kw1">int</span> x2<span class="op">,</span> <span class="kw1">int</span> y2<span class="op">)</span><span class="op">;</span></pre></td></tr></tbody></table><font + style="margin-left: 1em;"><i></i></font> +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>Draw + a filled rectangle without border with the fill color. +The coordinates are in pixels. +<br><br></p></td></tr></tbody></table> + +<table width="640px" border="0" cellpadding="0" cellspacing="0"><tbody><tr><td><pre><span class="kw1">void</span> outlined_rectangle<span class="op">(</span><span class="kw1">int</span> x1<span class="op">,</span> <span class="kw1">int</span> y1<span class="op">,</span> <span class="kw1">int</span> x2<span class="op">,</span> <span class="kw1">int</span> y2<span class="op">)</span><span class="op">;</span></pre></td></tr></tbody></table><font + style="margin-left: 1em;"><i></i></font> +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>Draw + a filled rectangle with a border. There are both colors +line and fill are used. +<br><br></p></td></tr></tbody></table> + +<table width="640px" border="0" cellpadding="0" cellspacing="0"><tbody><tr><td><pre><span class="kw1">void</span> <a href="http://www.antigrain.com/__code/include/agg_ellipse.h.html#ellipse">ellipse</a><span class="op">(</span><span class="kw1">int</span> x<span class="op">,</span> <span class="kw1">int</span> y<span class="op">,</span> <span class="kw1">int</span> rx<span class="op">,</span> <span class="kw1">int</span> ry<span class="op">)</span><span class="op">;</span> +<span class="kw1">void</span> solid_ellipse<span class="op">(</span><span class="kw1">int</span> x<span class="op">,</span> <span class="kw1">int</span> y<span class="op">,</span> <span class="kw1">int</span> rx<span class="op">,</span> <span class="kw1">int</span> ry<span class="op">)</span><span class="op">;</span> +<span class="kw1">void</span> outlined_ellipse<span class="op">(</span><span class="kw1">int</span> x<span class="op">,</span> <span class="kw1">int</span> y<span class="op">,</span> <span class="kw1">int</span> rx<span class="op">,</span> <span class="kw1">int</span> ry<span class="op">)</span><span class="op">;</span> +</pre></td></tr></tbody></table><font style="margin-left: 1em;"><i></i></font> +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>Draw + ellipses, non-filled, filled and filled with a border. +The coordinates are integer, in pixels. <code>rx</code> and <code>ry</code> + — +radii in pixels. +<br><br></p></td></tr></tbody></table> + +<table width="640px" border="0" cellpadding="0" cellspacing="0"><tbody><tr><td><pre><span class="kw1">void</span> line<span class="op">(</span><span class="kw1">int</span> x1<span class="op">,</span> <span class="kw1">int</span> y1<span class="op">,</span> <span class="kw1">int</span> x2<span class="op">,</span> <span class="kw1">int</span> y2<span class="op">,</span> <span class="kw1">bool</span> last<span class="op">=</span><span class="kw1">false</span><span class="op">)</span><span class="op">;</span></pre></td></tr></tbody></table><font + style="margin-left: 1em;"><i></i></font> +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>Draw + a bresenham line with <b>Subpixel Accuracy</b>. The coordinates are in +integer format of 24.8, that is, in the 1/256 pixel units. +Flag <code>last</code> defines whether or not to draw the last pixel, +which is important when drawing consecutive line segments with +alpha-blending. There no pixels should be drawn more than once. +<br><br></p></td></tr></tbody></table> + +<table width="640px" border="0" cellpadding="0" cellspacing="0"><tbody><tr><td><pre><span class="kw1">void</span> move_to<span class="op">(</span><span class="kw1">int</span> x<span class="op">,</span> <span class="kw1">int</span> y<span class="op">)</span><span class="op">;</span> +<span class="kw1">void</span> line_to<span class="op">(</span><span class="kw1">int</span> x<span class="op">,</span> <span class="kw1">int</span> y<span class="op">,</span> <span class="kw1">bool</span> last<span class="op">=</span><span class="kw1">false</span><span class="op">)</span><span class="op">;</span> +</pre></td></tr></tbody></table><font style="margin-left: 1em;"><i></i></font> +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>The +version of <code>line()</code>. +<br><br></p></td></tr></tbody></table> + +<table width="640px" border="0" cellpadding="0" cellspacing="0"><tbody><tr><td><pre><span class="kw1">const</span> base_ren_type<span class="op">&</span> ren<span class="op">(</span><span class="op">)</span> <span class="kw1">const</span> <span class="op">{</span> <span class="kw1">return</span> <span class="op">*</span>m_ren<span class="op">;</span> <span class="op">}</span> +base_ren_type<span class="op">&</span> ren<span class="op">(</span><span class="op">)</span> <span class="op">{</span> <span class="kw1">return</span> <span class="op">*</span>m_ren<span class="op">;</span> <span class="op">}</span> +</pre></td></tr></tbody></table><font style="margin-left: 1em;"><i></i></font> +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>Returns + a reference to the base renderer object. +<br><br></p></td></tr></tbody></table> + +<table width="640px" border="0" cellpadding="0" cellspacing="0"><tbody><tr><td><pre><span class="kw1">const</span> <a href="http://www.antigrain.com/doc/basic_renderers/basic_renderers.agdoc.html#rendering_buffer">rendering_buffer</a><span class="op">&</span> rbuf<span class="op">(</span><span class="op">)</span> <span class="kw1">const</span> <span class="op">{</span> <span class="kw1">return</span> m_ren<span class="op">-</span><span class="op">></span>rbuf<span class="op">(</span><span class="op">)</span><span class="op">;</span> <span class="op">}</span> +<a href="http://www.antigrain.com/doc/basic_renderers/basic_renderers.agdoc.html#rendering_buffer">rendering_buffer</a><span class="op">&</span> rbuf<span class="op">(</span><span class="op">)</span> <span class="op">{</span> <span class="kw1">return</span> m_ren<span class="op">-</span><span class="op">></span>rbuf<span class="op">(</span><span class="op">)</span><span class="op">;</span> <span class="op">}</span> +</pre></td></tr></tbody></table><font style="margin-left: 1em;"><i></i></font> +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>Returns + a reference to the rendering buffer attached to the base renderer.</p></td></tr></tbody></table> + + + +<h3>Marker Renderer<a name="toc0018"></a></h3> + +<a name="renderer_markers"><b></b></a> +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>The +header file: <a +href="http://www.antigrain.com/__code/include/agg_renderer_markers.h.html">agg_renderer_markers.h</a></p></td></tr></tbody></table> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>The +marker renderer can draw or alpha-blend the following simple shapes:</p></td></tr></tbody></table> + +<table width="640px" border="0" cellpadding="0" cellspacing="0"><tbody><tr><td><pre><span class="kw1">enum</span> <a href="http://www.antigrain.com/__code/include/agg_renderer_markers.h.html#marker_e">marker_e</a> +<span class="op">{</span> + marker_square<span class="op">,</span> + marker_diamond<span class="op">,</span> + marker_circle<span class="op">,</span> + marker_crossed_circle<span class="op">,</span> + marker_semiellipse_left<span class="op">,</span> + marker_semiellipse_right<span class="op">,</span> + marker_semiellipse_up<span class="op">,</span> + marker_semiellipse_down<span class="op">,</span> + marker_triangle_left<span class="op">,</span> + marker_triangle_right<span class="op">,</span> + marker_triangle_up<span class="op">,</span> + marker_triangle_down<span class="op">,</span> + marker_four_rays<span class="op">,</span> + marker_cross<span class="op">,</span> + marker_x<span class="op">,</span> + marker_dash<span class="op">,</span> + marker_dot<span class="op">,</span> + marker_pixel +<span class="op">}</span><span class="op">;</span> +</pre></td></tr></tbody></table><font style="margin-left: 1em;"><i></i></font><table + width="640px"><tbody><tr><td style="text-align: justify;"><p> </p></td></tr></tbody></table> + +<h4>Declaration<a name="toc0019"></a></h4> + +<table width="640px" border="0" cellpadding="0" cellspacing="0"><tbody><tr><td><pre><span class="kw1">template</span><span class="op"><</span><span class="kw1">class</span> BaseRenderer<span class="op">></span> <span class="kw1">class</span> <a href="http://www.antigrain.com/doc/basic_renderers/basic_renderers.agdoc.html#renderer_markers">renderer_markers</a> : +<span class="kw1">public</span> <a href="http://www.antigrain.com/doc/basic_renderers/basic_renderers.agdoc.html#renderer_primitives">renderer_primitives</a><span class="op"><</span>BaseRenderer<span class="op">></span> +<span class="op">{</span> +<span class="kw1">public</span>: + <span class="kw1">typedef</span> <a href="http://www.antigrain.com/doc/basic_renderers/basic_renderers.agdoc.html#renderer_primitives">renderer_primitives</a><span class="op"><</span>BaseRenderer<span class="op">></span> base_type<span class="op">;</span> + <span class="kw1">typedef</span> BaseRenderer base_ren_type<span class="op">;</span> + <span class="kw1">typedef</span> <span class="kw1">typename</span> base_ren_type::color_type color_type<span class="op">;</span> +<span class="rem">// . . .</span> +<span class="op">}</span><span class="op">;</span> +</pre></td></tr></tbody></table><font style="margin-left: 1em;"><i></i></font><table + width="640px"><tbody><tr><td style="text-align: justify;"><p> </p></td></tr></tbody></table> + +<h4>Creation<a name="toc0020"></a></h4> + +<table width="640px" border="0" cellpadding="0" cellspacing="0"><tbody><tr><td><pre><a href="http://www.antigrain.com/doc/basic_renderers/basic_renderers.agdoc.html#renderer_markers">renderer_markers</a><span class="op">(</span>base_ren_type<span class="op">&</span> rbuf<span class="op">)</span> : + base_type<span class="op">(</span>rbuf<span class="op">)</span> +<span class="op">{</span><span class="op">}</span> +</pre></td></tr></tbody></table><font style="margin-left: 1em;"><i></i></font> +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>As +you can see, the creation is as simple as the <a +href="http://www.antigrain.com/doc/basic_renderers/basic_renderers.agdoc.html#renderer_primitives">renderer_primitives</a> + one.</p></td></tr></tbody></table> + +<h4>Member Functions<a name="toc0021"></a></h4> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>All +the marker functions accept <code>x</code>, <code>y</code>, and <code>radius</code> + in pixels. +The radius in the <code>pixel()</code> marker doesn't have any effect. +The fill and line colors are taken from the base class <a +href="http://www.antigrain.com/doc/basic_renderers/basic_renderers.agdoc.html#renderer_primitives">renderer_primitives</a>.</p></td></tr></tbody></table> + +<table width="640px" border="0" cellpadding="0" cellspacing="0"><tbody><tr><td><pre><span class="kw1">void</span> square<span class="op">(</span><span class="kw1">int</span> x<span class="op">,</span> <span class="kw1">int</span> y<span class="op">,</span> <span class="kw1">int</span> r<span class="op">)</span><span class="op">;</span> +<span class="kw1">void</span> diamond<span class="op">(</span><span class="kw1">int</span> x<span class="op">,</span> <span class="kw1">int</span> y<span class="op">,</span> <span class="kw1">int</span> r<span class="op">)</span><span class="op">;</span> +<span class="kw1">void</span> circle<span class="op">(</span><span class="kw1">int</span> x<span class="op">,</span> <span class="kw1">int</span> y<span class="op">,</span> <span class="kw1">int</span> r<span class="op">)</span><span class="op">;</span> +<span class="kw1">void</span> crossed_circle<span class="op">(</span><span class="kw1">int</span> x<span class="op">,</span> <span class="kw1">int</span> y<span class="op">,</span> <span class="kw1">int</span> r<span class="op">)</span><span class="op">;</span> +<span class="kw1">void</span> semiellipse_left<span class="op">(</span><span class="kw1">int</span> x<span class="op">,</span> <span class="kw1">int</span> y<span class="op">,</span> <span class="kw1">int</span> r<span class="op">)</span><span class="op">;</span> +<span class="kw1">void</span> semiellipse_right<span class="op">(</span><span class="kw1">int</span> x<span class="op">,</span> <span class="kw1">int</span> y<span class="op">,</span> <span class="kw1">int</span> r<span class="op">)</span><span class="op">;</span> +<span class="kw1">void</span> semiellipse_up<span class="op">(</span><span class="kw1">int</span> x<span class="op">,</span> <span class="kw1">int</span> y<span class="op">,</span> <span class="kw1">int</span> r<span class="op">)</span><span class="op">;</span> +<span class="kw1">void</span> semiellipse_down<span class="op">(</span><span class="kw1">int</span> x<span class="op">,</span> <span class="kw1">int</span> y<span class="op">,</span> <span class="kw1">int</span> r<span class="op">)</span><span class="op">;</span> +<span class="kw1">void</span> triangle_left<span class="op">(</span><span class="kw1">int</span> x<span class="op">,</span> <span class="kw1">int</span> y<span class="op">,</span> <span class="kw1">int</span> r<span class="op">)</span><span class="op">;</span> +<span class="kw1">void</span> triangle_right<span class="op">(</span><span class="kw1">int</span> x<span class="op">,</span> <span class="kw1">int</span> y<span class="op">,</span> <span class="kw1">int</span> r<span class="op">)</span><span class="op">;</span> +<span class="kw1">void</span> triangle_up<span class="op">(</span><span class="kw1">int</span> x<span class="op">,</span> <span class="kw1">int</span> y<span class="op">,</span> <span class="kw1">int</span> r<span class="op">)</span><span class="op">;</span> +<span class="kw1">void</span> triangle_down<span class="op">(</span><span class="kw1">int</span> x<span class="op">,</span> <span class="kw1">int</span> y<span class="op">,</span> <span class="kw1">int</span> r<span class="op">)</span><span class="op">;</span> +<span class="kw1">void</span> four_rays<span class="op">(</span><span class="kw1">int</span> x<span class="op">,</span> <span class="kw1">int</span> y<span class="op">,</span> <span class="kw1">int</span> r<span class="op">)</span><span class="op">;</span> +<span class="kw1">void</span> cross<span class="op">(</span><span class="kw1">int</span> x<span class="op">,</span> <span class="kw1">int</span> y<span class="op">,</span> <span class="kw1">int</span> r<span class="op">)</span><span class="op">;</span> +<span class="kw1">void</span> xing<span class="op">(</span><span class="kw1">int</span> x<span class="op">,</span> <span class="kw1">int</span> y<span class="op">,</span> <span class="kw1">int</span> r<span class="op">)</span><span class="op">;</span> +<span class="kw1">void</span> dash<span class="op">(</span><span class="kw1">int</span> x<span class="op">,</span> <span class="kw1">int</span> y<span class="op">,</span> <span class="kw1">int</span> r<span class="op">)</span><span class="op">;</span> +<span class="kw1">void</span> dot<span class="op">(</span><span class="kw1">int</span> x<span class="op">,</span> <span class="kw1">int</span> y<span class="op">,</span> <span class="kw1">int</span> r<span class="op">)</span><span class="op">;</span> +<span class="kw1">void</span> pixel<span class="op">(</span><span class="kw1">int</span> x<span class="op">,</span> <span class="kw1">int</span> y<span class="op">,</span> <span class="kw1">int</span><span class="op">)</span><span class="op">;</span> +</pre></td></tr></tbody></table><font style="margin-left: 1em;"><i></i></font> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>Also, + there are some functions for the convenience that basically just use +the <code>switch/case</code> construction:</p></td></tr></tbody></table> + +<table width="640px" border="0" cellpadding="0" cellspacing="0"><tbody><tr><td><pre><span class="kw1">void</span> marker<span class="op">(</span><span class="kw1">int</span> x<span class="op">,</span> <span class="kw1">int</span> y<span class="op">,</span> <span class="kw1">int</span> r<span class="op">,</span> <a href="http://www.antigrain.com/__code/include/agg_renderer_markers.h.html#marker_e">marker_e</a> type<span class="op">)</span><span class="op">;</span></pre></td></tr></tbody></table><font + style="margin-left: 1em;"><i></i></font> +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>Draw + a single marker of the given type. +<br><br></p></td></tr></tbody></table> + +<table width="640px" border="0" cellpadding="0" cellspacing="0"><tbody><tr><td><pre><span class="kw1">template</span><span class="op"><</span><span class="kw1">class</span> T<span class="op">></span> +<span class="kw1">void</span> markers<span class="op">(</span><span class="kw1">int</span> n<span class="op">,</span> <span class="kw1">const</span> T<span class="op">*</span> x<span class="op">,</span> <span class="kw1">const</span> T<span class="op">*</span> y<span class="op">,</span> T r<span class="op">,</span> <a href="http://www.antigrain.com/__code/include/agg_renderer_markers.h.html#marker_e">marker_e</a> type<span class="op">)</span><span class="op">;</span></pre></td></tr></tbody></table><font + style="margin-left: 1em;"><i></i></font> +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>Draw + a number of markers of the given type and radius and coordinates +stored in two arrays, <code>x</code> and <code>y</code>. +<br><br></p></td></tr></tbody></table> + +<table width="640px" border="0" cellpadding="0" cellspacing="0"><tbody><tr><td><pre><span class="kw1">template</span><span class="op"><</span><span class="kw1">class</span> T<span class="op">></span> +<span class="kw1">void</span> markers<span class="op">(</span><span class="kw1">int</span> n<span class="op">,</span> <span class="kw1">const</span> T<span class="op">*</span> x<span class="op">,</span> <span class="kw1">const</span> T<span class="op">*</span> y<span class="op">,</span> <span class="kw1">const</span> T<span class="op">*</span> r<span class="op">,</span> <a href="http://www.antigrain.com/__code/include/agg_renderer_markers.h.html#marker_e">marker_e</a> type<span class="op">)</span><span class="op">;</span></pre></td></tr></tbody></table><font + style="margin-left: 1em;"><i></i></font> +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>Draw + a number of markers of the given type with coordinates and radii +stored in three arrays. +<br><br></p></td></tr></tbody></table> + +<table width="640px" border="0" cellpadding="0" cellspacing="0"><tbody><tr><td><pre><span class="kw1">template</span><span class="op"><</span><span class="kw1">class</span> T<span class="op">></span> +<span class="kw1">void</span> markers<span class="op">(</span><span class="kw1">int</span> n<span class="op">,</span> <span class="kw1">const</span> T<span class="op">*</span> x<span class="op">,</span> <span class="kw1">const</span> T<span class="op">*</span> y<span class="op">,</span> <span class="kw1">const</span> T<span class="op">*</span> r<span class="op">,</span> + <span class="kw1">const</span> color_type<span class="op">*</span> fill_colors<span class="op">,</span> + <a href="http://www.antigrain.com/__code/include/agg_renderer_markers.h.html#marker_e">marker_e</a> type<span class="op">)</span><span class="op">;</span></pre></td></tr></tbody></table><font + style="margin-left: 1em;"><i></i></font> +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>Draw + a number of markers of the given type with coordinates and radii +stored in three arrays and of different fill colors. +<br><br></p></td></tr></tbody></table> + +<table width="640px" border="0" cellpadding="0" cellspacing="0"><tbody><tr><td><pre><span class="kw1">template</span><span class="op"><</span><span class="kw1">class</span> T<span class="op">></span> +<span class="kw1">void</span> markers<span class="op">(</span><span class="kw1">int</span> n<span class="op">,</span> <span class="kw1">const</span> T<span class="op">*</span> x<span class="op">,</span> <span class="kw1">const</span> T<span class="op">*</span> y<span class="op">,</span> <span class="kw1">const</span> T<span class="op">*</span> r<span class="op">,</span> + <span class="kw1">const</span> color_type<span class="op">*</span> fc<span class="op">,</span> <span class="kw1">const</span> color_type<span class="op">*</span> lc<span class="op">,</span> + <a href="http://www.antigrain.com/__code/include/agg_renderer_markers.h.html#marker_e">marker_e</a> type<span class="op">)</span><span class="op">;</span></pre></td></tr></tbody></table><font + style="margin-left: 1em;"><i></i></font> +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>Draw + a number of markers of the given type with coordinates and radii +stored in three arrays and of different fill and line colors. +<br><br></p></td></tr></tbody></table> + + +<br><table style="margin: 0px;" height="1px" width="640px" +bgcolor="#583927" border="0" cellpadding="0" cellspacing="0"><tbody><tr><td></td></tr></tbody></table> +<table width="640px" border="0" cellpadding="0" cellspacing="0"> +<tbody><tr><td><center><span class="authors"> +Copyright <span class="larger">©</span> 2002-2006 +<a href="http://www.antigrain.com/mcseem/index.html"><b>Maxim Shemanarev</b></a> +</span></center></td></tr> +<tr><td><center><span class="authors"> +Web Design and Programming +<a href="http://www.antigrain.com/mcseem/index.html"><b>Maxim Shemanarev</b></a> +</span></center></td></tr> +</tbody></table> +<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br> +<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br> +<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br> +<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br> +</body></html>
\ No newline at end of file diff --git a/docs/aggpas/basic_renderers.agdoc_files/agg.css b/docs/aggpas/basic_renderers.agdoc_files/agg.css new file mode 100644 index 00000000..997d9d07 --- /dev/null +++ b/docs/aggpas/basic_renderers.agdoc_files/agg.css @@ -0,0 +1,239 @@ +BODY +{ + font-family:Verdana, Arial, Tahoma; + font-size:12px; + color:#160801; + background-color:#ffffff; + text-align:justify; + padding:5px; +} + +P, UL, OL, DL +{ + font-family:Verdana, Arial, Tahoma; + font-size:12px; + color:#160801; + margin-bottom:0px; + margin-top:0px; +} + + +.larger +{ + font-size:14px; +} + +LI +{ + padding:3px; +} + +HR +{ + color:#583927; + height:1px; +} + +H1 +{ + font-family:Verdana, Arial, Tahoma; + font-size:28px; + font-weight:bolder; + text-align:center; + color:#583927; + margin:0px; +} + +H1 SPAN.subtitle +{ + font-family:Verdana, Arial, Tahoma; + font-size:18px; + font-weight:lighter; +} + + +H2 +{ + font-family:Verdana, Arial, Tahoma; + font-size:26px; + font-weight:normal; + text-align:left; + color:#583927; +} + +H3 +{ + font-family:Verdana, Arial, Tahoma; + font-size:20px; + font-weight:normal; + text-align:left; + color:#583927; +} + +H4 +{ + font-family:Verdana, Arial, Tahoma; + font-size:16px; + font-weight:bold; + text-align:left; + color:#583927; +} + +H5 +{ + font-family:Verdana, Arial, Tahoma; + font-size:14px; + font-weight:bold; + text-align:left; + color:#583927; +} + +TABLE +{ + margin:5px; +} + +TD +{ + font-family:Verdana, Arial, Tahoma; + font-size:12px; +} + +TH +{ + font-family:Verdana, Arial, Tahoma; + background-color:#d4d4d4; + font-size:12px; +} + + +PRE +{ + padding: 5px; + border: gray 1px solid; + background-color:#f4f4f4; + color:#130f00; + font-family:"courier new", courier,mono; + font-size:12px; + margin:0px; +} + +TT, CODE +{ + font-family:"courier new", courier,mono; + font-size:14px; + color:#000070; +} + +.warning, .warning TD +{ + background-color:#fcf6f6; + color:#793131; + padding:0.5em; + font-family:Verdana, Arial, Tahoma; + font-size:12px; + text-align:justify; +} + +.note, .note TD +{ + background-color:#f0fafa; + color:#506580; + padding:0.5em; + font-family:Verdana, Arial, Tahoma; + font-size:12px; + text-align:justify; +} + +.quote, .quote TD +{ + background-color:#f0fafa; + color:#000540; + padding:0.5em; + font-family:Verdana, Arial, Tahoma; + font-size:12px; + text-align:justify; +} + +.tip, .tip TD +{ + background-color:#fbfff6; + color:#68771e; + padding:0.5em; + font-family:Verdana, Arial, Tahoma; + font-size:12px; + text-align:justify; +} + +.tbl TD +{ + background-color:#f4f4f4; + font-family:Verdana, Arial, Tahoma; + font-size:12px; + text-align:left; + padding:3px; +} + +.toc TD +{ + font-family:Verdana, Arial, Tahoma; + text-align:left; + padding:3px; +} + +.title {font-family:Verdana, Arial, Tahoma;} + +.warning P, +.warning PRE, +.note P, +.note PRE, +.tip P, +.tip PRE {margin:0.3em 0em 0.1em 0em;} + +.warning .code {background-color:#fcf6f6;} +.note .code {background-color:#f0fafa;} +.tip .code {background-color:#fbfff6;} + +A {text-decoration:none; color:#700000;} +A:visited {text-decoration:none; color:#85585d;} +A:link {text-decoration:none;} +A:hover {text-decoration:underline;} + +.topmenu,a.topmenu:visited,a.topmenu:hover,a.topmenu:active,a.topmenu:link +{ + font-family: Arial, Tahoma, Helvetica, sans-serif; + font-size: 11px; + font-weight: bold; + text-decoration: none; + color: #582218; +} + +.mpmenu,a.mpmenu:visited,a.mpmenu:hover,a.mpmenu:active,a.mpmenu:link +{ + font-family: Arial, Tahoma, Helvetica, sans-serif; + font-size: 12px; + font-weight: bold; + text-decoration: none; + color: #582218; +} + +.tah +{ + font-family: Tahoma, Arial, Helvetica, sans-serif; + font-size: 12px; + color: #582218; +} + +.authors +{ + font-size:10px; +} + +span.rem {color:#4c8d00;} +span.kw1 {color:#000d8e;} +span.kw2 {color:#0075ca;} +span.kw3 {color:#004645;} +span.kw4 {color:#673517;} +span.op {color:#4a006d;} +span.str {color:#ab2500;} +span.num {color:#a74c3f;} diff --git a/docs/aggpas/basic_renderers.agdoc_files/agg_logo.gif b/docs/aggpas/basic_renderers.agdoc_files/agg_logo.gif Binary files differnew file mode 100644 index 00000000..ee5c570a --- /dev/null +++ b/docs/aggpas/basic_renderers.agdoc_files/agg_logo.gif diff --git a/docs/aggpas/basic_renderers.agdoc_files/link.gif b/docs/aggpas/basic_renderers.agdoc_files/link.gif Binary files differnew file mode 100644 index 00000000..76a532cf --- /dev/null +++ b/docs/aggpas/basic_renderers.agdoc_files/link.gif diff --git a/docs/aggpas/basic_renderers.agdoc_files/pixfmt_rgb24.gif b/docs/aggpas/basic_renderers.agdoc_files/pixfmt_rgb24.gif Binary files differnew file mode 100644 index 00000000..35e4e4aa --- /dev/null +++ b/docs/aggpas/basic_renderers.agdoc_files/pixfmt_rgb24.gif diff --git a/docs/aggpas/basic_renderers.agdoc_files/rendering_buffer1.gif b/docs/aggpas/basic_renderers.agdoc_files/rendering_buffer1.gif Binary files differnew file mode 100644 index 00000000..d622ff56 --- /dev/null +++ b/docs/aggpas/basic_renderers.agdoc_files/rendering_buffer1.gif diff --git a/docs/aggpas/basic_renderers.agdoc_files/rendering_buffer2.gif b/docs/aggpas/basic_renderers.agdoc_files/rendering_buffer2.gif Binary files differnew file mode 100644 index 00000000..067ad232 --- /dev/null +++ b/docs/aggpas/basic_renderers.agdoc_files/rendering_buffer2.gif diff --git a/docs/aggpas/basic_renderers.agdoc_files/rendering_buffer3.gif b/docs/aggpas/basic_renderers.agdoc_files/rendering_buffer3.gif Binary files differnew file mode 100644 index 00000000..0e7abb05 --- /dev/null +++ b/docs/aggpas/basic_renderers.agdoc_files/rendering_buffer3.gif diff --git a/docs/aggpas/basic_renderers.agdoc_files/rendering_buffer4.gif b/docs/aggpas/basic_renderers.agdoc_files/rendering_buffer4.gif Binary files differnew file mode 100644 index 00000000..774af812 --- /dev/null +++ b/docs/aggpas/basic_renderers.agdoc_files/rendering_buffer4.gif diff --git a/docs/aggpas/basic_renderers.agdoc_files/spectrum.png b/docs/aggpas/basic_renderers.agdoc_files/spectrum.png Binary files differnew file mode 100644 index 00000000..016d5bc8 --- /dev/null +++ b/docs/aggpas/basic_renderers.agdoc_files/spectrum.png diff --git a/docs/aggpas/basic_renderers.agdoc_files/spectrum_amask1.png b/docs/aggpas/basic_renderers.agdoc_files/spectrum_amask1.png Binary files differnew file mode 100644 index 00000000..8318eddf --- /dev/null +++ b/docs/aggpas/basic_renderers.agdoc_files/spectrum_amask1.png diff --git a/docs/aggpas/basic_renderers.agdoc_files/spectrum_amask2.png b/docs/aggpas/basic_renderers.agdoc_files/spectrum_amask2.png Binary files differnew file mode 100644 index 00000000..36b33cb7 --- /dev/null +++ b/docs/aggpas/basic_renderers.agdoc_files/spectrum_amask2.png diff --git a/docs/aggpas/ddj1.agdoc.html b/docs/aggpas/ddj1.agdoc.html new file mode 100644 index 00000000..bf1db6f6 --- /dev/null +++ b/docs/aggpas/ddj1.agdoc.html @@ -0,0 +1,992 @@ +<html><head><title>Anti-Grain Geometry - Anti-Grain Geometry</title> +<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> +<link rel="stylesheet" type="text/css" href="ddj1.agdoc_files/agg.css"> +</head><body><table width="640px"><tbody><tr><td><h1>Anti-Grain Geometry<span + class="subtitle"><br>High Fidelity 2D Graphics for C++</span></h1></td></tr></tbody></table> + + +<table class="toc" width="640px"><tbody><tr><td> + <div style="margin-left: 2em; padding: 3px; font-size: 14px;"><a +href="#toc0001"><b>Introduction</b></a></div> + <div style="margin-left: 2em; padding: 3px; font-size: 14px;"><a +href="#toc0002"><b>Brief Overview of Graphic Libraries</b></a></div> + <div style="margin-left: 2em; padding: 3px; font-size: 14px;"><a +href="#toc0003"><b>The power of templates in C++</b></a></div> + <div style="margin-left: 2em; padding: 3px; font-size: 14px;"><a +href="#toc0004"><b>The key features of AGG</b></a></div> + <div style="margin-left: 2em; padding: 3px; font-size: 14px;"><a +href="#toc0005"><b>Architecture</b></a> + <div style="margin-left: 2em; font-size: 12px;"><a +href="#toc0006">Pixel Format Renderers</a></div> + <div style="margin-left: 2em; font-size: 12px;"><a +href="#toc0007">Alpha-Mask Adaptor</a></div> + <div style="margin-left: 2em; font-size: 12px;"><a +href="#toc0008">Basic Renderers</a></div> + <div style="margin-left: 2em; font-size: 12px;"><a +href="#toc0009">Scanline Renderer</a></div> + <div style="margin-left: 2em; font-size: 12px;"><a +href="#toc0010">Span Generator</a></div> + <div style="margin-left: 2em; font-size: 12px;"><a +href="#toc0011">Scanline Rasterizer</a></div> + <div style="margin-left: 2em; font-size: 12px;"><a +href="#toc0012">Outline Renderers</a></div> + <div style="margin-left: 2em; font-size: 12px;"><a +href="#toc0013">Outline Rasterizer</a></div> + <div style="margin-left: 2em; font-size: 12px;"><a +href="#toc0014">Vertex Conversion Pipeline</a></div></div> + <div style="margin-left: 2em; padding: 3px; font-size: 14px;"><a +href="#toc0015"><b>Example</b></a></div> + +</td></tr></tbody></table> + +<h2>Introduction<a name="toc0001"></a></h2> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>In +this article I would like to introduce my work called <b><nobr>Anti-Grain</nobr> + Geometry</b> (<b>AGG</b>). +It is an Open Source, free of charge 2D graphic library, written in +industrially standard C++.</p></td></tr></tbody></table> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>Scalable + 2D vector graphics is widely used in all kinds +of applications and now the performance of modern processors +makes it affordable to use <b>high quality</b> vector graphics.</p></td></tr></tbody></table> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>High + quality means multilevel Anti-Aliasing and subpixel accuracy. +Subpixel accuracy is often underestimated, but in general it's very +important to have a possibility of subpixel positioning. +It's especially important to be able to set fractional line width +that can be even less than one pixel. I would say that Anti-Aliased +rendering is practically useless without subpixel accuracy.</p></td></tr></tbody></table> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>The +first question that can arise is <i>“What is this needed for?”</i> +or even <i>“Is there a need of yet another reinvention of the wheel?”</i></p></td></tr></tbody></table> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>The +short answer is as follows. +Yes, there are many graphic standards, protocols and libraries, but +nothing that fits all my needs. It was my main motivation to start +<b>AGG</b>, namely, my exclusive requirements. Later other people +found it very interesting too.</p></td></tr></tbody></table> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>You +can think of <b>AGG</b> as of a rendering library that creates raster +images in memory from some vectorial representation. But this definition +is just the first approximation. In general, you can use any part of the +library, not obligatory as a rasterizer or renderer. +<b>AGG</b> can be used in many applications where there is a need for +high +quality and fast 2D graphics. It can be GIS/cartography applications, +fancy looking graphic user interfaces, different kinds of charts and +diagrams, +CAD/CAM, and so on. Besides, <b>AGG</b> is platform independent, +lightweight, +compact, and robust It also can be perfectly used in embedded systems +and mobile devices.</p></td></tr></tbody></table> + + +<br><h2>Brief Overview of Graphic Libraries<a name="toc0002"></a></h2> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>First, + let me briefly describe the existing tools +and libraries that can be used as 2D rendering engines. +The fastest software 2D renderer that produces images of +appropriate quality is well known Macromedia Flash viewer.</p></td></tr></tbody></table> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>The +other one is SVG standard from W3C committee, +<a href="http://www.w3.org/Graphics/SVG"><img +src="ddj1.agdoc_files/link.gif" border="0">http://www.w3.org/Graphics/SVG</a>/ + for which we can find a number of +viewers (the most advanced one is Adobe SVG, <a +href="http://www.adobe.com/svg"><img src="ddj1.agdoc_files/link.gif" +border="0">http://www.adobe.com/svg</a>/). +But they both are “end-user” applications and cannot be used as +rendering libraries available from C++. SVG would be the best 2D +standard if there were available implementations that support the +whole SVG specification and provide appropriate quality, performance, +and consume reasonable amount of memory.</p></td></tr></tbody></table> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>The +most widely used industrial libraries available from many languages +are OpenGL, Apple Quartz and GDI+.</p></td></tr></tbody></table> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>OpenGL + is good and standard, but the quality of 2D graphics is very poor. +It's perfectly “hardware accelerated”, but there are no available +accelerators that produce any valuable quality of 2D graphics. +Alex Eddy has performed a research that clearly shows the lack of the +quality in most popular OpenGL accelerators. +<a href="http://homepage.mac.com/arekkusu/bugs/invariance"><img +src="ddj1.agdoc_files/link.gif" border="0">http://homepage.mac.com/arekkusu/bugs/invariance</a>/</p></td></tr></tbody></table> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>GDI+ + has also very poor quality of rendering, it's slow and +has too many bugs to be used in practice, not to mention +that it's available only on Microsoft Windows platform.</p></td></tr></tbody></table> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>Apple + Quartz has the most advanced API and quality, but it's available +only on Apple computers.</p></td></tr></tbody></table> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>There + are two Open Source libraries, LibArt by Raph Levien +<a href="http://www.levien.com/libart"><img +src="ddj1.agdoc_files/link.gif" border="0">http://www.levien.com/libart</a>/ + and Cairo Graphics, <a href="http://cairographics.org/"><img +src="ddj1.agdoc_files/link.gif" border="0">http://cairographics.org</a>/. +LibArt + development was abandoned some time ago, and the problems with +numerical stability don't allow you to use it in practice.</p></td></tr></tbody></table> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>Cairo + Graphics is in active development and it is definitely worth +considering. Still, Cairo Graphics has certain limitations, mostly +because of its hardcoded rendering model.</p></td></tr></tbody></table> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>Besides, + LibArt and Cairo Graphics are released under LGPL license +which is too restrictive in many cases.</p></td></tr></tbody></table> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>Another + very good library is called ImageMagick (<a +href="http://www.imagemagick.org/"><img src="ddj1.agdoc_files/link.gif" +border="0">http://www.imagemagick.org</a>), +but its primary purpose is image processing.</p></td></tr></tbody></table> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>The +general problem of all existing graphic libraries and +tools is that they are too restrictive. They all are “black boxes”, +even open source ones. +I feel I need to explain this statement. Theoretically you can modify +an open source library in any way you want (assuming that it doesn't +contradict the license). But as soon as you modify a single byte you +create another branch of the library and have to take care of merging +your modifications with new versions from the authors. After some point +it becomes a nightmare. In my opinion the real “openness” of the library +appears when you can extend its functionality without having to modify a +single character in the distributed code. C++ allows us to do that.</p></td></tr></tbody></table> + +<br><h2>The power of templates in C++<a name="toc0003"></a></h2> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p><b>AGG</b> + uses C++ class and function templates very actively. The same +functionality can be achieved using dynamic polymorphism, that is, +classes with overridden virtual functions. But the templates allow +you to optimize the code having very flexible and convenient design. +Polymorphic classes work quite well until a certain level of +detailization. +A typical task in vector graphics is to have a vertex conversion +pipeline. +For example, it can be some source of vectorial commands like +MoveTo/LineTo/CurveTo, then there is a converter that “flattens” curves, +then a stroke generator, then affine transformer and so on. In most +graphic +libraries the pipelines are hardcoded. +If we want it to be more flexible, that is, if we want to construct +custom +pipelines, you will have to use polymorphism. It's appropriate to have +one virtual call per vertex but can be too expensive to have a virtual +call per vertex per pipeline element. Another approach is to have +“static” polymorphism, that is, to use class templates. It does not +directly +allow you to construct pipelines dynamically, at run time, but in most +cases +you don't really need it. Most probably you only want to have a +possibility to +construct pipelines at compile time, and if you really need dynamic +polymorphism it's very easy to write polymorphic wrappers whose +interfaces +are compatible with what the templates expect. So that, in <b>AGG</b> +it's you who has full control upon the functionality and performance. +The very same approach is used in the raster part of the rendering +pipeline. You can write your own low level renderers that work with +different color spaces, your own gradient functions, your own span +generators, and so on. An implementation based on classical +polymorphic classes would cost you several virtual calls per each pixel, +while templates allow you to do so for no extra overhead.</p></td></tr></tbody></table> + +<br><h2>The key features of AGG<a name="toc0004"></a></h2> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>Below + I just enumerate the key features of the library, so that you +could have a general idea of where it can be useful for you.</p></td></tr></tbody></table> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p></p><ul + type="disc"> +<li>Fast and high quality polygon rasterizer with 256 levels of + Anti-Aliasing. The non-zero and even-odd fill rules are applicable.</li> +<li>Customizable vector and raster pipelines.</li> +<li>Arbitrary gradients and Gouraud shading.</li> +<li>Image affine transformations with different kinds of interpolation, + from simple bilinear to high degree Lancosz and Blackman ones.</li> +<li>Pattern fill with arbitrary affine and perspective transformations + (can be used for texturing).</li> +<li>Perspective and bilinear transformations of vector and image data.</li> +<li>Stroke generator with different types of line joins and line caps.</li> +<li>Dash line generator.</li> +<li>Markers, such as arrowheads/arrow tails.</li> +<li>Fast vectorial polygon clipper to a rectangle.</li> +<li>Low-level clipping to multiple rectangular regions.</li> +<li>Alpha-Masking.</li> +<li>Fast Anti-Aliased line algorithm.</li> +<li>Arbitrary images as line patterns.</li> +<li>Rendering in separate color channels.</li> +<li>Boolean polygon operations (and, or, xor, sub) based on Alan Murta's + General Polygon Clipper.</li> +<li>Scanline Boolean Algebra. Performs boolean operations on rasterized + scanline shapes. Works in average 5-10 times faster than General + Polygon Clipper</li> +<li>Text support using FreeType library (<a +href="http://www.freetype.org/"><img src="ddj1.agdoc_files/link.gif" +border="0">http://www.freetype.org</a>) and + Windows API (<code>GetGlyphOutline()</code>).</li> +<li>Arbitrary non-linear transformations.</li></ul><p></p></td></tr></tbody></table> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>The +library and examples were successfully compiled and tested on the +following +platforms:</p></td></tr></tbody></table> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p></p><ul + type="disc"> +<li>Microsoft Windows (95,98,NT4,2000,XP,2003). Compilers Microsoft +Visual C++ + v5, v6, v7, Intel C++ v6, GNU C++ from v2.96 to v3.4.0</li> +<li>Linux, GNU C++</li> +<li>SunOS</li> +<li>SGI IRIX64</li> +<li>MacOS 9, MacOS X, Compilers Metrowerks CodeWarrior 8.3, GNU C++</li> +<li>QNX</li> +<li>BeOS</li> +<li>AmigaOS</li></ul><p></p></td></tr></tbody></table> + + +<br><h2>Architecture<a name="toc0005"></a></h2> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p><b>AGG</b> + doesn't have any predefined rendering model, it's like +"a tool to create other tools". The architecture and the +philosophy of the library is determined by the main goal +of its creation. The goal is to have a set of 2D tools united +with a common idea. You and only you define the resulting architecture +and +rendering model. <b>AGG</b> is open and flexible but not that +obvious and easy to use as other "conventional" libraries like +GDI+ or Quartz. +Besides, it makes sense to mention that <b>AGG</b> has some +restrictions too, but it's only because some algorithms and +design solutions are not yet implemented. +In particular, <b>AGG</b> currently supports only path-based model, +and there is no straight way to render graphics from Macromedia +Flash format. Flash is edge-based, so, you can render a multi-color +scene in one pass. In some cases it's better, but in general it's +more restrictive and more difficult in use. Currently we can say +that <b>AGG</b> is more SVG centric rather than Flash centric.</p></td></tr></tbody></table> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>The +following picture represents a typical architecture of a +rendering engine based on <b>AGG</b>. +</p></td></tr></tbody></table><table width="640px"><tbody><tr><td><center><img + src="ddj1.agdoc_files/architecture.gif" title="" border="0"><br><i></i></center></td></tr></tbody></table> + + +<h3>Pixel Format Renderers<a name="toc0006"></a></h3> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>Pixel + format renderers perform basic alpha-blending operations +in the resulting frame buffer. They do not perform any clipping, +thus, it's unsafe to use them directly, so, if the coordinates are +out of range it can result in undefined behaviour, most probably +segmentation fault. It doesn't mean that the design is bad, it +means that you can write your own color space and pixel format +renderers, and you don't need to worry about clipping because +it is already provided on a higher level. +It's quite possible to write a renderer to work in another color +space, say, XYZ or Lab, and define your own color type. +These additions will not affect anyhow the other parts of <b>AGG</b>.</p></td></tr></tbody></table> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>Currently + <b>AGG</b> provides 15, 16, 24, and 32 bits RGB and RGBA +pixel formats.</p></td></tr></tbody></table> + +<h3>Alpha-Mask Adaptor<a name="toc0007"></a></h3> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>Alpha-mask + adaptor allows you to use an additional +transparency channel when rendering. Strictly speaking +there can be any kind of an adaptor. Alpha-mask is just +an example of it.</p></td></tr></tbody></table> + +<h3>Basic Renderers<a name="toc0008"></a></h3> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>The +basic renderer (<a +href="http://www.antigrain.com/doc/basic_renderers/basic_renderers.agdoc.html#renderer_base">renderer_base</a>) + accepts a pixel format +renderer as its template argument and it's main purpose is +level clipping. It provides essentially the same interface as +pixel format renderers. +Also, there is <a +href="http://www.antigrain.com/doc/basic_renderers/basic_renderers.agdoc.html#renderer_mclip">renderer_mclip</a> + which is the same in use +but it can perform clipping to a number of arbitrary +rectangles.</p></td></tr></tbody></table> + +<h3>Scanline Renderer<a name="toc0009"></a></h3> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>One +of the key concepts in <b>AGG</b> is the scanline. The scanline +is a container that consist of a number of horizontal spans that +can carry Anti-Aliasing information. The scanline +renderer decomposes provided scanline into a number of spans +and in simple cases (like solid fill) calls basic renderer. +In more complex cases it can call span generator.</p></td></tr></tbody></table> + +<h3>Span Generator<a name="toc0010"></a></h3> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>Span + Generator is used in all cases that are more difficult +than solid fill. It's a common mechanism that can produce +any kind of color spans, such as gradients, Gouraud shading, +image transformations, pattern fill, and so on. Particularly +this mechanism allows you to transform a part of the image +bounded with an arbitrary shape with Anti-Aliased edges. +The span generator can consist of the whole pipeline, +for example, there can be an image transformer plus alpha +(transparency) gradient.</p></td></tr></tbody></table> + +<h3>Scanline Rasterizer<a name="toc0011"></a></h3> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>The +scanline rasterizer accepts a number of arbitrary polygons +as its input and produces anti-aliased scanlines. This is +the primary rendering technique in <b>AGG</b>. It means that +the only shape that can be rasterized is a polygon (poly-polygon +to be exact). If you need to draw a line you need to calculate +at least four points that define its outline. At the first sight +it can seem like an overkill, but it isn't. The main point is +that the algorithm uses subpixel accuracy and correctly rasterizes +any shapes, even when a single pixel is crossed by the edges many +times. It allows the result to remain consistent regardless +of the scale and the algorithm guarantees that there will be +no defects. +</p></td></tr></tbody></table><table width="640px"><tbody><tr><td><center><img + src="ddj1.agdoc_files/subpixel_accuracy2.gif" title="" border="0"><br><i></i></center></td></tr></tbody></table> +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>The +initial idea was taken from the rasterizer +of FreeType font engine by David Turner (<a +href="http://www.freetype.org/"><img src="ddj1.agdoc_files/link.gif" +border="0">http://www.freetype.org</a>). +David kindly allowed me to rewrite the rasterizer in C++ and +release the code independently.</p></td></tr></tbody></table> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>Such + kind of the design (rasterizer <span class="larger">→</span> +scanline_renderer <span class="larger">→</span> base_renderer <span +class="larger">→</span> pixel_format) +allows us to implement very interesting algorithms, for example, +renderers optimized for LCD color triplets (like Microsoft ClearType) +and +it will be applicable to all primitives, not only for text.</p></td></tr></tbody></table> + +<h3>Outline Renderers<a name="toc0012"></a></h3> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>This + is yet another algorithm of drawing Anti-Aliased lines. +The use of the algorithm is more limited than the scanline rasterizer, +but it also has many advantages. +</p><ul type="disc"> +<li>It works about 2…3 times faster than the scanline rasterizer.</li> +<li>It allows you to have the Anti-Aliased area of any profile and +width.</li> +<li>The Anti-Aliasing algorithm is distance-based, unlike area-based + in the scanline rasterizer. In most cases it allows you to produce + better visual result.</li> +<li>Most importantly, the algorithm allows you to use an arbitrary + image as the line pattern. + This is the key capability when rendering high quality + geographic maps. +In general we can say that it's dedicated for fast drawing of +relatively thin polylines.</li></ul><p></p></td></tr></tbody></table> + +<h3>Outline Rasterizer<a name="toc0013"></a></h3> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>The +outline rasterizer is just an adaptor that unifies the use of +the solid outline rasterizer and the one with image patterns.</p></td></tr></tbody></table> + +<h3>Vertex Conversion Pipeline<a name="toc0014"></a></h3> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>The +vertex pipeline consists of a number of converters. +Each converter accepts an abstract Vertex Source as the input +and works as another Vertex Source. Usually graphic libraries +have hardcoded pipelines, typically they consist of a curve +decomposer (that converts curves to a number of short line segments), +affine transformer, dash generator, stroke generator, +and polygon clipper.</p></td></tr></tbody></table> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>In <b>AGG</b> + you can construct custom pipelines and there can be as many +pipelines as you need. Besides, the pipelines can have branches, in +other words you can extract vertices from any point of the pipeline. +The most important thing is you can combine the converters as +you want and get quite different results.</p></td></tr></tbody></table> + +<br><h2>Example<a name="toc0015"></a></h2> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>The +example below demonstrates how to create basic types needed +for rendering and the effect of the pipelines. To keep the things +as simple as possible it will be a console application that +produces a raster file (result.ppm) that has a very simple format. +You can display this files with many kinds of viewers, for example, +IrfanView (<a href="http://www.irfanview.com/"><img +src="ddj1.agdoc_files/link.gif" border="0">http://www.irfanview.com</a>/).</p></td></tr></tbody></table> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>Also + I'd like to mention that it's not necessary for <b>AGG</b> to have +any building environment. It has automake/autoconfig files, but you +can do without them. Since <b>AGG</b> doesn't depend on any +platform-specific +tools you can just include all necessary source files into your +project/makefile and they will perfectly compile and work.</p></td></tr></tbody></table> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p><b>AGG</b> + is written according to the “Just Compile It” principle.</p></td></tr></tbody></table> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>Type + (or take from the CD) the following code and name the file +<code>example_pipeline1.cpp</code>:</p></td></tr></tbody></table> + +<table width="640px" border="0" cellpadding="0" cellspacing="0"><tbody><tr><td><pre><span class="kw2">#include</span> <span class="op"><</span>stdio<span class="op">.</span>h<span class="op">></span> +<span class="kw2">#include</span> <span class="op"><</span>string<span class="op">.</span>h<span class="op">></span> +<span class="kw2">#include</span> <span class="str">"agg_pixfmt_rgb24.h"</span> +<span class="kw2">#include</span> <span class="str">"<a href="http://www.antigrain.com/__code/include/agg_renderer_base.h.html">agg_renderer_base.h</a>"</span> +<span class="kw2">#include</span> <span class="str">"<a href="http://www.antigrain.com/__code/include/agg_renderer_scanline.h.html">agg_renderer_scanline.h</a>"</span> +<span class="kw2">#include</span> <span class="str">"<a href="http://www.antigrain.com/__code/include/agg_scanline_u.h.html">agg_scanline_u.h</a>"</span> +<span class="kw2">#include</span> <span class="str">"<a href="http://www.antigrain.com/__code/include/agg_rasterizer_scanline_aa.h.html">agg_rasterizer_scanline_aa.h</a>"</span> +<span class="kw2">#include</span> <span class="str">"<a href="http://www.antigrain.com/__code/include/agg_path_storage.h.html">agg_path_storage.h</a>"</span> + +<span class="kw1">enum</span> +<span class="op">{</span> + frame_width <span class="op">=</span> <span class="num">200</span><span class="op">,</span> + frame_height <span class="op">=</span> <span class="num">200</span> +<span class="op">}</span><span class="op">;</span> + +<span class="rem">// Writing the buffer to a .PPM file, assuming it has</span> +<span class="rem">// RGB-structure, one byte per color component</span> +<span class="rem">//--------------------------------------------------</span> +<span class="kw1">bool</span> write_ppm<span class="op">(</span><span class="kw1">const</span> <span class="kw1">unsigned</span> <span class="kw1">char</span><span class="op">*</span> buf<span class="op">,</span> + <span class="kw1">unsigned</span> width<span class="op">,</span> + <span class="kw1">unsigned</span> height<span class="op">,</span> + <span class="kw1">const</span> <span class="kw1">char</span><span class="op">*</span> file_name<span class="op">)</span> +<span class="op">{</span> + FILE<span class="op">*</span> fd <span class="op">=</span> fopen<span class="op">(</span>file_name<span class="op">,</span> <span class="str">"wb"</span><span class="op">)</span><span class="op">;</span> + <span class="kw1">if</span><span class="op">(</span>fd<span class="op">)</span> + <span class="op">{</span> + fprintf<span class="op">(</span>fd<span class="op">,</span> <span class="str">"P6 %d %d 255 "</span><span class="op">,</span> width<span class="op">,</span> height<span class="op">)</span><span class="op">;</span> + fwrite<span class="op">(</span>buf<span class="op">,</span> <span class="num">1</span><span class="op">,</span> width <span class="op">*</span> height <span class="op">*</span> <span class="num">3</span><span class="op">,</span> fd<span class="op">)</span><span class="op">;</span> + fclose<span class="op">(</span>fd<span class="op">)</span><span class="op">;</span> + <span class="kw1">return</span> <span class="kw1">true</span><span class="op">;</span> + <span class="op">}</span> + <span class="kw1">return</span> <span class="kw1">false</span><span class="op">;</span> +<span class="op">}</span> + + +<span class="kw1">int</span> <span class="kw1">main</span><span class="op">(</span><span class="op">)</span> +<span class="op">{</span> + <span class="rem">// Allocate the frame buffer (in this case "manually")</span> + <span class="rem">// and create the rendering buffer object</span> + <span class="kw1">unsigned</span> <span class="kw1">char</span><span class="op">*</span> buffer <span class="op">=</span> <span class="kw1">new</span> <span class="kw1">unsigned</span> <span class="kw1">char</span><span class="op">[</span>frame_width <span class="op">*</span> frame_height <span class="op">*</span> <span class="num">3</span><span class="op">]</span><span class="op">;</span> + agg::<a href="http://www.antigrain.com/doc/basic_renderers/basic_renderers.agdoc.html#rendering_buffer">rendering_buffer</a> rbuf<span class="op">(</span>buffer<span class="op">,</span> + frame_width<span class="op">,</span> + frame_height<span class="op">,</span> + frame_width <span class="op">*</span> <span class="num">3</span><span class="op">)</span><span class="op">;</span> + + <span class="rem">// Create Pixel Format and Basic renderers</span> + <span class="rem">//--------------------</span> + agg::<a href="http://www.antigrain.com/__code/include/agg_pixfmt_rgb.h.html#pixfmt_rgb24">pixfmt_rgb24</a> pixf<span class="op">(</span>rbuf<span class="op">)</span><span class="op">;</span> + agg::<a href="http://www.antigrain.com/doc/basic_renderers/basic_renderers.agdoc.html#renderer_base">renderer_base</a><span class="op"><</span>agg::<a href="http://www.antigrain.com/__code/include/agg_pixfmt_rgb.h.html#pixfmt_rgb24">pixfmt_rgb24</a><span class="op">></span> ren_base<span class="op">(</span>pixf<span class="op">)</span><span class="op">;</span> + + <span class="rem">// At last we do some very simple things, like clear</span> + <span class="rem">//--------------------</span> + ren_base<span class="op">.</span>clear<span class="op">(</span>agg::<a href="http://www.antigrain.com/__code/include/agg_color_rgba.h.html#rgba8">rgba8</a><span class="op">(</span><span class="num">255</span><span class="op">,</span> <span class="num">250</span><span class="op">,</span> <span class="num">230</span><span class="op">)</span><span class="op">)</span><span class="op">;</span> + + <span class="rem">// Create Scanline Container, Scanline Rasterizer,</span> + <span class="rem">// and Scanline Renderer for solid fill.</span> + <span class="rem">//--------------------</span> + agg::<a href="http://www.antigrain.com/__code/include/agg_scanline_u.h.html#scanline_u8">scanline_u8</a> sl<span class="op">;</span> + agg::<a href="http://www.antigrain.com/__code/include/agg_rasterizer_scanline_aa.h.html#rasterizer_scanline_aa">rasterizer_scanline_aa</a><span class="op"><</span><span class="op">></span> ras<span class="op">;</span> + agg::<a href="http://www.antigrain.com/__code/include/agg_renderer_scanline.h.html#renderer_scanline_aa_solid">renderer_scanline_aa_solid</a><span class="op"><</span> + agg::<a href="http://www.antigrain.com/doc/basic_renderers/basic_renderers.agdoc.html#renderer_base">renderer_base</a><span class="op"><</span>agg::<a href="http://www.antigrain.com/__code/include/agg_pixfmt_rgb.h.html#pixfmt_rgb24">pixfmt_rgb24</a><span class="op">></span> <span class="op">></span> ren_sl<span class="op">(</span>ren_base<span class="op">)</span><span class="op">;</span> + + <span class="rem">// Create Vertex Source (path) object, in our case it's</span> + <span class="rem">// <a href="http://www.antigrain.com/__code/include/agg_path_storage.h.html#path_storage">path_storage</a> and form the path.</span> + <span class="rem">//--------------------</span> + agg::<a href="http://www.antigrain.com/__code/include/agg_path_storage.h.html#path_storage">path_storage</a> path<span class="op">;</span> + path<span class="op">.</span>remove_all<span class="op">(</span><span class="op">)</span><span class="op">;</span> <span class="rem">// Not obligatory in this case</span> + path<span class="op">.</span>move_to<span class="op">(</span><span class="num">10</span><span class="op">,</span> <span class="num">10</span><span class="op">)</span><span class="op">;</span> + path<span class="op">.</span>line_to<span class="op">(</span>frame_width<span class="op">-</span><span class="num">10</span><span class="op">,</span> <span class="num">10</span><span class="op">)</span><span class="op">;</span> + path<span class="op">.</span>line_to<span class="op">(</span>frame_width<span class="op">-</span><span class="num">10</span><span class="op">,</span> frame_height<span class="op">-</span><span class="num">10</span><span class="op">)</span><span class="op">;</span> + path<span class="op">.</span>line_to<span class="op">(</span><span class="num">10</span><span class="op">,</span> frame_height<span class="op">-</span><span class="num">10</span><span class="op">)</span><span class="op">;</span> + path<span class="op">.</span>line_to<span class="op">(</span><span class="num">10</span><span class="op">,</span> frame_height<span class="op">-</span><span class="num">20</span><span class="op">)</span><span class="op">;</span> + path<span class="op">.</span><a href="http://www.antigrain.com/__code/include/agg_curves.h.html#curve4">curve4</a><span class="op">(</span>frame_width<span class="op">-</span><span class="num">20</span><span class="op">,</span> frame_height<span class="op">-</span><span class="num">20</span><span class="op">,</span> + frame_width<span class="op">-</span><span class="num">20</span><span class="op">,</span> <span class="num">20</span><span class="op">,</span> + <span class="num">10</span><span class="op">,</span> <span class="num">20</span><span class="op">)</span><span class="op">;</span> + + <span class="rem">// The vectorial pipeline</span> + <span class="rem">//-----------------------</span> + ras<span class="op">.</span>add_path<span class="op">(</span>path<span class="op">)</span><span class="op">;</span> + <span class="rem">//-----------------------</span> + + <span class="rem">// Set the color and render the scanlines</span> + <span class="rem">//-----------------------</span> + ren_sl<span class="op">.</span>color<span class="op">(</span>agg::<a href="http://www.antigrain.com/__code/include/agg_color_rgba.h.html#rgba8">rgba8</a><span class="op">(</span><span class="num">120</span><span class="op">,</span> <span class="num">60</span><span class="op">,</span> <span class="num">0</span><span class="op">)</span><span class="op">)</span><span class="op">;</span> + agg::<a href="http://www.antigrain.com/__code/include/agg_renderer_scanline.h.html#render_scanlines">render_scanlines</a><span class="op">(</span>ras<span class="op">,</span> sl<span class="op">,</span> ren_sl<span class="op">)</span><span class="op">;</span> + + <span class="rem">// Write the buffer to result.ppm and liberate memory.</span> + <span class="rem">//-----------------------</span> + write_ppm<span class="op">(</span>buffer<span class="op">,</span> frame_width<span class="op">,</span> frame_height<span class="op">,</span> <span class="str">"result.ppm"</span><span class="op">)</span><span class="op">;</span> + <span class="kw1">delete</span> <span class="op">[</span><span class="op">]</span> buffer<span class="op">;</span> + <span class="kw1">return</span> <span class="num">0</span><span class="op">;</span> +<span class="op">}</span> +</pre></td></tr></tbody></table><font style="margin-left: 1em;"><i></i></font> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>Then + you can compile and link this code with <b>AGG</b>: using GNU C++:</p></td></tr></tbody></table> + +<table width="640px" border="0" cellpadding="0" cellspacing="0"><tbody><tr><td><pre>g++ -I/agg2/include example_pipeline1.cpp + /agg2/src/agg_rasterizer_scanline_aa.cpp + /agg2/src/agg_path_storage.cpp + /agg2/src/<a href="http://www.antigrain.com/__code/src/agg_bezier_arc.cpp.html">agg_bezier_arc.cpp</a> + /agg2/src/<a href="http://www.antigrain.com/__code/src/agg_trans_affine.cpp.html">agg_trans_affine.cpp</a> +</pre></td></tr></tbody></table><font style="margin-left: 1em;"><i></i></font> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>or +Microsoft C++, v6 or later:</p></td></tr></tbody></table> + +<table width="640px" border="0" cellpadding="0" cellspacing="0"><tbody><tr><td><pre>cl -I/agg2/include example_pipeline1.cpp + /agg2/src/agg_rasterizer_scanline_aa.cpp + /agg2/src/agg_path_storage.cpp + /agg2/src/<a href="http://www.antigrain.com/__code/src/agg_bezier_arc.cpp.html">agg_bezier_arc.cpp</a> + /agg2/src/<a href="http://www.antigrain.com/__code/src/agg_trans_affine.cpp.html">agg_trans_affine.cpp</a> +</pre></td></tr></tbody></table><font style="margin-left: 1em;"><i></i></font> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>Of +course, you will need +to replace <code>“/agg2/”</code> to the actual path to the library.</p></td></tr></tbody></table> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>The +result.ppm should be as follows:</p></td></tr></tbody></table> + +<table width="640px"><tbody><tr><td><center><img +src="ddj1.agdoc_files/example_pipeline1.gif" title="" border="0"><br><i></i></center></td></tr></tbody></table> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>You +can think that this code is too complex to produce this +simplest figure, but let us look at the following changes.</p></td></tr></tbody></table> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>Currently + we have a null-pipeline, that is an empty one. In this case +all the points are interpreted like move-to/line-to commands. This is +why the call of <code>path.<a +href="http://www.antigrain.com/__code/include/agg_curves.h.html#curve4">curve4</a>()</code> + does not have any effect.</p></td></tr></tbody></table> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>The +first modification is to add the curve converter +(curve flattener in other words), that is, the one that decomposes +Bezier +curves to a number of short line segments (<code>example_pipeline2.cpp</code>):</p></td></tr></tbody></table> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>Add <code>#include + "<a +href="http://www.antigrain.com/__code/include/agg_conv_curve.h.html">agg_conv_curve.h</a>"</code> + and change the following: +</p></td></tr></tbody></table><table width="640px" border="0" +cellpadding="0" cellspacing="0"><tbody><tr><td><pre> <span class="rem">// The vectorial pipeline</span> + <span class="rem">//-----------------------</span> + agg::<a href="http://www.antigrain.com/__code/include/agg_conv_curve.h.html#conv_curve">conv_curve</a><span class="op"><</span>agg::<a href="http://www.antigrain.com/__code/include/agg_path_storage.h.html#path_storage">path_storage</a><span class="op">></span> curve<span class="op">(</span>path<span class="op">)</span><span class="op">;</span> + ras<span class="op">.</span>add_path<span class="op">(</span>curve<span class="op">)</span><span class="op">;</span> + <span class="rem">//-----------------------</span> +</pre></td></tr></tbody></table><font style="margin-left: 1em;"><i></i></font> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>Also + add /agg2/src/<a +href="http://www.antigrain.com/__code/src/agg_curves.cpp.html">agg_curves.cpp</a> + to the compile list and see the result:</p></td></tr></tbody></table> + +<table width="640px"><tbody><tr><td><center><img +src="ddj1.agdoc_files/example_pipeline2.gif" title="" border="0"><br><i></i></center></td></tr></tbody></table> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>Then + let as draw a stroke (<code>example_pipeline3.cpp</code>):</p></td></tr></tbody></table> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>Add <code>#include + "<a +href="http://www.antigrain.com/__code/include/agg_conv_stroke.h.html">agg_conv_stroke.h</a>"</code> + and change the following: +</p></td></tr></tbody></table><table width="640px" border="0" +cellpadding="0" cellspacing="0"><tbody><tr><td><pre> <span class="rem">// The vectorial pipeline</span> + <span class="rem">//-----------------------</span> + agg::<a href="http://www.antigrain.com/__code/include/agg_conv_curve.h.html#conv_curve">conv_curve</a><span class="op"><</span>agg::<a href="http://www.antigrain.com/__code/include/agg_path_storage.h.html#path_storage">path_storage</a><span class="op">></span> curve<span class="op">(</span>path<span class="op">)</span><span class="op">;</span> + agg::<a href="http://www.antigrain.com/__code/include/agg_conv_stroke.h.html#conv_stroke">conv_stroke</a><span class="op"><</span>agg::<a href="http://www.antigrain.com/__code/include/agg_conv_curve.h.html#conv_curve">conv_curve</a><span class="op"><</span>agg::<a href="http://www.antigrain.com/__code/include/agg_path_storage.h.html#path_storage">path_storage</a><span class="op">></span> <span class="op">></span> stroke<span class="op">(</span>curve<span class="op">)</span><span class="op">;</span> + stroke<span class="op">.</span>width<span class="op">(</span><span class="num">6</span><span class="op">.</span><span class="num">0</span><span class="op">)</span><span class="op">;</span> + ras<span class="op">.</span>add_path<span class="op">(</span>stroke<span class="op">)</span><span class="op">;</span> + <span class="rem">//-----------------------</span> +</pre></td></tr></tbody></table><font style="margin-left: 1em;"><i></i></font> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>Add +/agg2/src/<a +href="http://www.antigrain.com/__code/src/agg_vcgen_stroke.cpp.html">agg_vcgen_stroke.cpp</a> + to the compile list. The result is:</p></td></tr></tbody></table> + +<table width="640px"><tbody><tr><td><center><img +src="ddj1.agdoc_files/example_pipeline3.gif" title="" border="0"><br><i></i></center></td></tr></tbody></table> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>Of +course, you can set line width, line cap, and line join. Our polygon +is not closed, to close it just call:</p></td></tr></tbody></table> + +<table width="640px" border="0" cellpadding="0" cellspacing="0"><tbody><tr><td><pre> path<span class="op">.</span>close_polygon<span class="op">(</span><span class="op">)</span><span class="op">;</span> +</pre></td></tr></tbody></table><font style="margin-left: 1em;"><i></i></font> + +<table width="640px"><tbody><tr><td><center><img +src="ddj1.agdoc_files/example_pipeline31.gif" title="" border="0"><br><i></i></center></td></tr></tbody></table> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>I +hope you get the idea of how to draw a filled polygon with a stroke. +Just in case let us see this code:</p></td></tr></tbody></table> + +<table width="640px" border="0" cellpadding="0" cellspacing="0"><tbody><tr><td><pre> <span class="rem">// The vectorial pipeline</span> + <span class="rem">//-----------------------</span> + agg::<a href="http://www.antigrain.com/__code/include/agg_conv_curve.h.html#conv_curve">conv_curve</a><span class="op"><</span>agg::<a href="http://www.antigrain.com/__code/include/agg_path_storage.h.html#path_storage">path_storage</a><span class="op">></span> curve<span class="op">(</span>path<span class="op">)</span><span class="op">;</span> + agg::<a href="http://www.antigrain.com/__code/include/agg_conv_stroke.h.html#conv_stroke">conv_stroke</a><span class="op"><</span>agg::<a href="http://www.antigrain.com/__code/include/agg_conv_curve.h.html#conv_curve">conv_curve</a><span class="op"><</span>agg::<a href="http://www.antigrain.com/__code/include/agg_path_storage.h.html#path_storage">path_storage</a><span class="op">></span> <span class="op">></span> stroke<span class="op">(</span>curve<span class="op">)</span><span class="op">;</span> + stroke<span class="op">.</span>width<span class="op">(</span><span class="num">6</span><span class="op">.</span><span class="num">0</span><span class="op">)</span><span class="op">;</span> + + <span class="rem">// Set the fill color and render the polygon:</span> + <span class="rem">//-----------------------</span> + ras<span class="op">.</span>add_path<span class="op">(</span>curve<span class="op">)</span><span class="op">;</span> + ren_sl<span class="op">.</span>color<span class="op">(</span>agg::<a href="http://www.antigrain.com/__code/include/agg_color_rgba.h.html#rgba8">rgba8</a><span class="op">(</span><span class="num">160</span><span class="op">,</span> <span class="num">180</span><span class="op">,</span> <span class="num">80</span><span class="op">)</span><span class="op">)</span><span class="op">;</span> + agg::<a href="http://www.antigrain.com/__code/include/agg_renderer_scanline.h.html#render_scanlines">render_scanlines</a><span class="op">(</span>ras<span class="op">,</span> sl<span class="op">,</span> ren_sl<span class="op">)</span><span class="op">;</span> + + <span class="rem">// Set the stroke color and render the stroke:</span> + <span class="rem">//-----------------------</span> + ras<span class="op">.</span>add_path<span class="op">(</span>stroke<span class="op">)</span><span class="op">;</span> + ren_sl<span class="op">.</span>color<span class="op">(</span>agg::<a href="http://www.antigrain.com/__code/include/agg_color_rgba.h.html#rgba8">rgba8</a><span class="op">(</span><span class="num">120</span><span class="op">,</span> <span class="num">100</span><span class="op">,</span> <span class="num">0</span><span class="op">)</span><span class="op">)</span><span class="op">;</span> + agg::<a href="http://www.antigrain.com/__code/include/agg_renderer_scanline.h.html#render_scanlines">render_scanlines</a><span class="op">(</span>ras<span class="op">,</span> sl<span class="op">,</span> ren_sl<span class="op">)</span><span class="op">;</span> + <span class="rem">//-----------------------</span> +</pre></td></tr></tbody></table><font style="margin-left: 1em;"><i></i></font> +<table width="640px"><tbody><tr><td><center><img +src="ddj1.agdoc_files/example_pipeline4.gif" title="" border="0"><br><i></i></center></td></tr></tbody></table> +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>Here + we can see that the pipeline consists of two consecutive +converters (curve and stroke) and we can use both of them in the +very same way.</p></td></tr></tbody></table> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>The +next step is adding affine transformations and the main +question is where to add them. The answer is it depends. +You can add the affine transformer before the curve converter, +so that it will process very few points, but the stroke converter +will generate a stroke as if it were the original shape. +Let us see (<code>example_pipeline5.cpp</code>).</p></td></tr></tbody></table> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>The +pipeline is: +</p></td></tr></tbody></table><table width="640px" border="0" +cellpadding="0" cellspacing="0"><tbody><tr><td><pre> <span class="rem">// The vectorial pipeline</span> + <span class="rem">//-----------------------</span> + agg::<a href="http://www.antigrain.com/__code/include/agg_trans_affine.h.html#trans_affine">trans_affine</a> matrix<span class="op">;</span> + matrix <span class="op">*=</span> agg::<a href="http://www.antigrain.com/__code/include/agg_trans_affine.h.html#trans_affine_translation">trans_affine_translation</a><span class="op">(</span><span class="op">-</span>frame_width<span class="op">/</span><span class="num">2</span><span class="op">,</span> <span class="op">-</span>frame_height<span class="op">/</span><span class="num">2</span><span class="op">)</span><span class="op">;</span> + matrix <span class="op">*=</span> agg::<a href="http://www.antigrain.com/__code/include/agg_trans_affine.h.html#trans_affine_rotation">trans_affine_rotation</a><span class="op">(</span>agg::<a href="http://www.antigrain.com/__code/include/agg_basics.h.html#deg2rad">deg2rad</a><span class="op">(</span><span class="num">35</span><span class="op">.</span><span class="num">0</span><span class="op">)</span><span class="op">)</span><span class="op">;</span> + matrix <span class="op">*=</span> agg::<a href="http://www.antigrain.com/__code/include/agg_trans_affine.h.html#trans_affine_scaling">trans_affine_scaling</a><span class="op">(</span><span class="num">0</span><span class="op">.</span><span class="num">4</span><span class="op">,</span> <span class="num">0</span><span class="op">.</span><span class="num">75</span><span class="op">)</span><span class="op">;</span> + matrix <span class="op">*=</span> agg::<a href="http://www.antigrain.com/__code/include/agg_trans_affine.h.html#trans_affine_translation">trans_affine_translation</a><span class="op">(</span>frame_width<span class="op">/</span><span class="num">2</span><span class="op">,</span> frame_height<span class="op">/</span><span class="num">2</span><span class="op">)</span><span class="op">;</span> + + agg::<a href="http://www.antigrain.com/__code/include/agg_conv_transform.h.html#conv_transform">conv_transform</a><span class="op"><</span>agg::<a href="http://www.antigrain.com/__code/include/agg_path_storage.h.html#path_storage">path_storage</a><span class="op">,</span> agg::<a href="http://www.antigrain.com/__code/include/agg_trans_affine.h.html#trans_affine">trans_affine</a><span class="op">></span> trans<span class="op">(</span>path<span class="op">,</span> matrix<span class="op">)</span><span class="op">;</span> + + agg::<a href="http://www.antigrain.com/__code/include/agg_conv_curve.h.html#conv_curve">conv_curve</a><span class="op"><</span> + agg::<a href="http://www.antigrain.com/__code/include/agg_conv_transform.h.html#conv_transform">conv_transform</a><span class="op"><</span> + agg::<a href="http://www.antigrain.com/__code/include/agg_path_storage.h.html#path_storage">path_storage</a><span class="op">,</span> agg::<a href="http://www.antigrain.com/__code/include/agg_trans_affine.h.html#trans_affine">trans_affine</a><span class="op">></span> <span class="op">></span> curve<span class="op">(</span>trans<span class="op">)</span><span class="op">;</span> + + agg::<a href="http://www.antigrain.com/__code/include/agg_conv_stroke.h.html#conv_stroke">conv_stroke</a><span class="op"><</span> + agg::<a href="http://www.antigrain.com/__code/include/agg_conv_curve.h.html#conv_curve">conv_curve</a><span class="op"><</span> + agg::<a href="http://www.antigrain.com/__code/include/agg_conv_transform.h.html#conv_transform">conv_transform</a><span class="op"><</span>agg::<a href="http://www.antigrain.com/__code/include/agg_path_storage.h.html#path_storage">path_storage</a><span class="op">,</span> + agg::<a href="http://www.antigrain.com/__code/include/agg_trans_affine.h.html#trans_affine">trans_affine</a><span class="op">></span> <span class="op">></span> <span class="op">></span> stroke<span class="op">(</span>curve<span class="op">)</span><span class="op">;</span> + stroke<span class="op">.</span>width<span class="op">(</span><span class="num">6</span><span class="op">.</span><span class="num">0</span><span class="op">)</span><span class="op">;</span> + + <span class="rem">// Set the fill color and render the polygon:</span> + <span class="rem">//-----------------------</span> + ras<span class="op">.</span>add_path<span class="op">(</span>curve<span class="op">)</span><span class="op">;</span> + ren_sl<span class="op">.</span>color<span class="op">(</span>agg::<a href="http://www.antigrain.com/__code/include/agg_color_rgba.h.html#rgba8">rgba8</a><span class="op">(</span><span class="num">160</span><span class="op">,</span> <span class="num">180</span><span class="op">,</span> <span class="num">80</span><span class="op">)</span><span class="op">)</span><span class="op">;</span> + agg::<a href="http://www.antigrain.com/__code/include/agg_renderer_scanline.h.html#render_scanlines">render_scanlines</a><span class="op">(</span>ras<span class="op">,</span> sl<span class="op">,</span> ren_sl<span class="op">)</span><span class="op">;</span> + + <span class="rem">// Set the stroke color and render the stroke:</span> + <span class="rem">//-----------------------</span> + ras<span class="op">.</span>add_path<span class="op">(</span>stroke<span class="op">)</span><span class="op">;</span> + ren_sl<span class="op">.</span>color<span class="op">(</span>agg::<a href="http://www.antigrain.com/__code/include/agg_color_rgba.h.html#rgba8">rgba8</a><span class="op">(</span><span class="num">120</span><span class="op">,</span> <span class="num">100</span><span class="op">,</span> <span class="num">0</span><span class="op">)</span><span class="op">)</span><span class="op">;</span> + agg::<a href="http://www.antigrain.com/__code/include/agg_renderer_scanline.h.html#render_scanlines">render_scanlines</a><span class="op">(</span>ras<span class="op">,</span> sl<span class="op">,</span> ren_sl<span class="op">)</span><span class="op">;</span> + <span class="rem">//-----------------------</span> +</pre></td></tr></tbody></table><font style="margin-left: 1em;"><i></i></font> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>And +the result:</p></td></tr></tbody></table> + +<table width="640px"><tbody><tr><td><center><img +src="ddj1.agdoc_files/example_pipeline5.gif" title="" border="0"><br><i></i></center></td></tr></tbody></table> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>Now +let us modify the pipeline in such a way that the affine +transformer would be after the stroke generator (<code>example_pipeline6.cpp</code>)</p></td></tr></tbody></table> + +<table width="640px" border="0" cellpadding="0" cellspacing="0"><tbody><tr><td><pre> <span class="rem">// The vectorial pipeline</span> + <span class="rem">//-----------------------</span> + agg::<a href="http://www.antigrain.com/__code/include/agg_trans_affine.h.html#trans_affine">trans_affine</a> matrix<span class="op">;</span> + matrix <span class="op">*=</span> agg::<a href="http://www.antigrain.com/__code/include/agg_trans_affine.h.html#trans_affine_translation">trans_affine_translation</a><span class="op">(</span><span class="op">-</span>frame_width<span class="op">/</span><span class="num">2</span><span class="op">,</span> <span class="op">-</span>frame_height<span class="op">/</span><span class="num">2</span><span class="op">)</span><span class="op">;</span> + matrix <span class="op">*=</span> agg::<a href="http://www.antigrain.com/__code/include/agg_trans_affine.h.html#trans_affine_rotation">trans_affine_rotation</a><span class="op">(</span>agg::<a href="http://www.antigrain.com/__code/include/agg_basics.h.html#deg2rad">deg2rad</a><span class="op">(</span><span class="num">35</span><span class="op">.</span><span class="num">0</span><span class="op">)</span><span class="op">)</span><span class="op">;</span> + matrix <span class="op">*=</span> agg::<a href="http://www.antigrain.com/__code/include/agg_trans_affine.h.html#trans_affine_scaling">trans_affine_scaling</a><span class="op">(</span><span class="num">0</span><span class="op">.</span><span class="num">4</span><span class="op">,</span> <span class="num">0</span><span class="op">.</span><span class="num">75</span><span class="op">)</span><span class="op">;</span> + matrix <span class="op">*=</span> agg::<a href="http://www.antigrain.com/__code/include/agg_trans_affine.h.html#trans_affine_translation">trans_affine_translation</a><span class="op">(</span>frame_width<span class="op">/</span><span class="num">2</span><span class="op">,</span> frame_height<span class="op">/</span><span class="num">2</span><span class="op">)</span><span class="op">;</span> + + agg::<a href="http://www.antigrain.com/__code/include/agg_conv_curve.h.html#conv_curve">conv_curve</a><span class="op"><</span>agg::<a href="http://www.antigrain.com/__code/include/agg_path_storage.h.html#path_storage">path_storage</a><span class="op">></span> curve<span class="op">(</span>path<span class="op">)</span><span class="op">;</span> + agg::<a href="http://www.antigrain.com/__code/include/agg_conv_transform.h.html#conv_transform">conv_transform</a><span class="op"><</span> + agg::<a href="http://www.antigrain.com/__code/include/agg_conv_curve.h.html#conv_curve">conv_curve</a><span class="op"><</span>agg::<a href="http://www.antigrain.com/__code/include/agg_path_storage.h.html#path_storage">path_storage</a><span class="op">></span><span class="op">,</span> + agg::<a href="http://www.antigrain.com/__code/include/agg_trans_affine.h.html#trans_affine">trans_affine</a><span class="op">></span> trans_curve<span class="op">(</span>curve<span class="op">,</span> matrix<span class="op">)</span><span class="op">;</span> + + agg::<a href="http://www.antigrain.com/__code/include/agg_conv_stroke.h.html#conv_stroke">conv_stroke</a><span class="op"><</span>agg::<a href="http://www.antigrain.com/__code/include/agg_conv_curve.h.html#conv_curve">conv_curve</a><span class="op"><</span>agg::<a href="http://www.antigrain.com/__code/include/agg_path_storage.h.html#path_storage">path_storage</a><span class="op">></span> <span class="op">></span> stroke<span class="op">(</span>curve<span class="op">)</span><span class="op">;</span> + + agg::<a href="http://www.antigrain.com/__code/include/agg_conv_transform.h.html#conv_transform">conv_transform</a><span class="op"><</span> + agg::<a href="http://www.antigrain.com/__code/include/agg_conv_stroke.h.html#conv_stroke">conv_stroke</a><span class="op"><</span>agg::<a href="http://www.antigrain.com/__code/include/agg_conv_curve.h.html#conv_curve">conv_curve</a><span class="op"><</span>agg::<a href="http://www.antigrain.com/__code/include/agg_path_storage.h.html#path_storage">path_storage</a><span class="op">></span> <span class="op">></span><span class="op">,</span> + agg::<a href="http://www.antigrain.com/__code/include/agg_trans_affine.h.html#trans_affine">trans_affine</a><span class="op">></span> trans_stroke<span class="op">(</span>stroke<span class="op">,</span> matrix<span class="op">)</span><span class="op">;</span> + + stroke<span class="op">.</span>width<span class="op">(</span><span class="num">6</span><span class="op">.</span><span class="num">0</span><span class="op">)</span><span class="op">;</span> + + <span class="rem">// Set the fill color and render the polygon:</span> + <span class="rem">//-----------------------</span> + ras<span class="op">.</span>add_path<span class="op">(</span>trans_curve<span class="op">)</span><span class="op">;</span> + ren_sl<span class="op">.</span>color<span class="op">(</span>agg::<a href="http://www.antigrain.com/__code/include/agg_color_rgba.h.html#rgba8">rgba8</a><span class="op">(</span><span class="num">160</span><span class="op">,</span> <span class="num">180</span><span class="op">,</span> <span class="num">80</span><span class="op">)</span><span class="op">)</span><span class="op">;</span> + agg::<a href="http://www.antigrain.com/__code/include/agg_renderer_scanline.h.html#render_scanlines">render_scanlines</a><span class="op">(</span>ras<span class="op">,</span> sl<span class="op">,</span> ren_sl<span class="op">)</span><span class="op">;</span> + + <span class="rem">// Set the stroke color and render the stroke:</span> + <span class="rem">//-----------------------</span> + ras<span class="op">.</span>add_path<span class="op">(</span>trans_stroke<span class="op">)</span><span class="op">;</span> + ren_sl<span class="op">.</span>color<span class="op">(</span>agg::<a href="http://www.antigrain.com/__code/include/agg_color_rgba.h.html#rgba8">rgba8</a><span class="op">(</span><span class="num">120</span><span class="op">,</span> <span class="num">100</span><span class="op">,</span> <span class="num">0</span><span class="op">)</span><span class="op">)</span><span class="op">;</span> + agg::<a href="http://www.antigrain.com/__code/include/agg_renderer_scanline.h.html#render_scanlines">render_scanlines</a><span class="op">(</span>ras<span class="op">,</span> sl<span class="op">,</span> ren_sl<span class="op">)</span><span class="op">;</span> + <span class="rem">//-----------------------</span> +</pre></td></tr></tbody></table><font style="margin-left: 1em;"><i></i></font> +<table width="640px"><tbody><tr><td><center><img +src="ddj1.agdoc_files/example_pipeline6.gif" title="" border="0"><br><i></i></center></td></tr></tbody></table> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>Here + we actually have two pipelines, path<span class="larger">→</span><a +href="http://www.antigrain.com/__code/include/agg_conv_curve.h.html#conv_curve">conv_curve</a><span + class="larger">→</span><a +href="http://www.antigrain.com/__code/include/agg_conv_transform.h.html#conv_transform">conv_transform</a>, +the other one is path<span class="larger">→</span><a +href="http://www.antigrain.com/__code/include/agg_conv_curve.h.html#conv_curve">conv_curve</a><span + class="larger">→</span><a +href="http://www.antigrain.com/__code/include/agg_conv_stroke.h.html#conv_stroke">conv_stroke</a><span + class="larger">→</span><a +href="http://www.antigrain.com/__code/include/agg_conv_transform.h.html#conv_transform">conv_transform</a>. +At the first sight it looks like now the stroke is thinner. But +it's more complex than that. Note that the width of the stroke is +not uniform. I intentionally set different scaling coefficients +by X and Y to demonstrate that you can control the result by +changing the order of the converters.</p></td></tr></tbody></table> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>Note + that the pipeline branches after <a +href="http://www.antigrain.com/__code/include/agg_conv_curve.h.html#conv_curve">conv_curve</a>. + For the sake +of efficiency it would be better to keep the fill pipeline as it was +in the previous example (path<span class="larger">→</span><a +href="http://www.antigrain.com/__code/include/agg_conv_transform.h.html#conv_transform">conv_transform</a><span + class="larger">→</span><a +href="http://www.antigrain.com/__code/include/agg_conv_curve.h.html#conv_curve">conv_curve</a>). + This code +just demonstrates a possibility to have complex pipelines.</p></td></tr></tbody></table> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>In +the last example let us demonstrate some non-linear transformation +effects. It will be a circular warp magnifier. But since the +transformation is non-linear, we can't just transform vertices, we need +to prepare the initial path in such a way that the initial vectors +would consist of many short line segments. Of course, we could do +that when adding vertices to the path storage, but there is a better +way. We use an additional intermediate converter that segments long +vectors. It's <a +href="http://www.antigrain.com/__code/include/agg_conv_segmentator.h.html#conv_segmentator">conv_segmentator</a>.</p></td></tr></tbody></table> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>We +also need to add two include files: +</p></td></tr></tbody></table><table width="640px" border="0" +cellpadding="0" cellspacing="0"><tbody><tr><td><pre><span class="kw2">#include</span> <span class="str">"<a href="http://www.antigrain.com/__code/include/agg_conv_segmentator.h.html">agg_conv_segmentator.h</a>"</span> +<span class="kw2">#include</span> <span class="str">"<a href="http://www.antigrain.com/__code/include/agg_trans_warp_magnifier.h.html">agg_trans_warp_magnifier.h</a>"</span> +</pre></td></tr></tbody></table><font style="margin-left: 1em;"><i></i></font> +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>And +the pipelines look as follows (<code>example_pipeline7.cpp</code>):</p></td></tr></tbody></table> + +<table width="640px" border="0" cellpadding="0" cellspacing="0"><tbody><tr><td><pre> <span class="rem">// The vectorial pipeline</span> + <span class="rem">//-----------------------</span> + agg::<a href="http://www.antigrain.com/__code/include/agg_trans_affine.h.html#trans_affine">trans_affine</a> matrix<span class="op">;</span> + matrix <span class="op">*=</span> agg::<a href="http://www.antigrain.com/__code/include/agg_trans_affine.h.html#trans_affine_translation">trans_affine_translation</a><span class="op">(</span><span class="op">-</span>frame_width<span class="op">/</span><span class="num">2</span><span class="op">,</span> <span class="op">-</span>frame_height<span class="op">/</span><span class="num">2</span><span class="op">)</span><span class="op">;</span> + matrix <span class="op">*=</span> agg::<a href="http://www.antigrain.com/__code/include/agg_trans_affine.h.html#trans_affine_rotation">trans_affine_rotation</a><span class="op">(</span>agg::<a href="http://www.antigrain.com/__code/include/agg_basics.h.html#deg2rad">deg2rad</a><span class="op">(</span><span class="num">35</span><span class="op">.</span><span class="num">0</span><span class="op">)</span><span class="op">)</span><span class="op">;</span> + matrix <span class="op">*=</span> agg::<a href="http://www.antigrain.com/__code/include/agg_trans_affine.h.html#trans_affine_scaling">trans_affine_scaling</a><span class="op">(</span><span class="num">0</span><span class="op">.</span><span class="num">3</span><span class="op">,</span> <span class="num">0</span><span class="op">.</span><span class="num">45</span><span class="op">)</span><span class="op">;</span> + matrix <span class="op">*=</span> agg::<a href="http://www.antigrain.com/__code/include/agg_trans_affine.h.html#trans_affine_translation">trans_affine_translation</a><span class="op">(</span>frame_width<span class="op">/</span><span class="num">2</span><span class="op">,</span> frame_height<span class="op">/</span><span class="num">2</span><span class="op">)</span><span class="op">;</span> + + agg::<a href="http://www.antigrain.com/__code/include/agg_trans_warp_magnifier.h.html#trans_warp_magnifier">trans_warp_magnifier</a> lens<span class="op">;</span> + lens<span class="op">.</span>center<span class="op">(</span><span class="num">120</span><span class="op">,</span> <span class="num">100</span><span class="op">)</span><span class="op">;</span> + lens<span class="op">.</span>magnification<span class="op">(</span><span class="num">3</span><span class="op">.</span><span class="num">0</span><span class="op">)</span><span class="op">;</span> + lens<span class="op">.</span>radius<span class="op">(</span><span class="num">18</span><span class="op">)</span><span class="op">;</span> + + agg::<a href="http://www.antigrain.com/__code/include/agg_conv_curve.h.html#conv_curve">conv_curve</a><span class="op"><</span>agg::<a href="http://www.antigrain.com/__code/include/agg_path_storage.h.html#path_storage">path_storage</a><span class="op">></span> curve<span class="op">(</span>path<span class="op">)</span><span class="op">;</span> + agg::<a href="http://www.antigrain.com/__code/include/agg_conv_segmentator.h.html#conv_segmentator">conv_segmentator</a><span class="op"><</span>agg::<a href="http://www.antigrain.com/__code/include/agg_conv_curve.h.html#conv_curve">conv_curve</a><span class="op"><</span>agg::<a href="http://www.antigrain.com/__code/include/agg_path_storage.h.html#path_storage">path_storage</a><span class="op">></span> <span class="op">></span> segm<span class="op">(</span>curve<span class="op">)</span><span class="op">;</span> + + agg::<a href="http://www.antigrain.com/__code/include/agg_conv_transform.h.html#conv_transform">conv_transform</a><span class="op"><</span> + agg::<a href="http://www.antigrain.com/__code/include/agg_conv_segmentator.h.html#conv_segmentator">conv_segmentator</a><span class="op"><</span> + agg::<a href="http://www.antigrain.com/__code/include/agg_conv_curve.h.html#conv_curve">conv_curve</a><span class="op"><</span> + agg::<a href="http://www.antigrain.com/__code/include/agg_path_storage.h.html#path_storage">path_storage</a><span class="op">></span> <span class="op">></span><span class="op">,</span> + agg::<a href="http://www.antigrain.com/__code/include/agg_trans_affine.h.html#trans_affine">trans_affine</a><span class="op">></span> trans_curve<span class="op">(</span>segm<span class="op">,</span> matrix<span class="op">)</span><span class="op">;</span> + + agg::<a href="http://www.antigrain.com/__code/include/agg_conv_transform.h.html#conv_transform">conv_transform</a><span class="op"><</span> + agg::<a href="http://www.antigrain.com/__code/include/agg_conv_transform.h.html#conv_transform">conv_transform</a><span class="op"><</span> + agg::<a href="http://www.antigrain.com/__code/include/agg_conv_segmentator.h.html#conv_segmentator">conv_segmentator</a><span class="op"><</span> + agg::<a href="http://www.antigrain.com/__code/include/agg_conv_curve.h.html#conv_curve">conv_curve</a><span class="op"><</span> + agg::<a href="http://www.antigrain.com/__code/include/agg_path_storage.h.html#path_storage">path_storage</a><span class="op">></span> <span class="op">></span><span class="op">,</span> + agg::<a href="http://www.antigrain.com/__code/include/agg_trans_affine.h.html#trans_affine">trans_affine</a><span class="op">></span><span class="op">,</span> + agg::<a href="http://www.antigrain.com/__code/include/agg_trans_warp_magnifier.h.html#trans_warp_magnifier">trans_warp_magnifier</a><span class="op">></span> trans_warp<span class="op">(</span>trans_curve<span class="op">,</span> lens<span class="op">)</span><span class="op">;</span> + + agg::<a href="http://www.antigrain.com/__code/include/agg_conv_stroke.h.html#conv_stroke">conv_stroke</a><span class="op"><</span> + agg::<a href="http://www.antigrain.com/__code/include/agg_conv_segmentator.h.html#conv_segmentator">conv_segmentator</a><span class="op"><</span> + agg::<a href="http://www.antigrain.com/__code/include/agg_conv_curve.h.html#conv_curve">conv_curve</a><span class="op"><</span> + agg::<a href="http://www.antigrain.com/__code/include/agg_path_storage.h.html#path_storage">path_storage</a><span class="op">></span> <span class="op">></span> <span class="op">></span> stroke<span class="op">(</span>segm<span class="op">)</span><span class="op">;</span> + + agg::<a href="http://www.antigrain.com/__code/include/agg_conv_transform.h.html#conv_transform">conv_transform</a><span class="op"><</span> + agg::<a href="http://www.antigrain.com/__code/include/agg_conv_stroke.h.html#conv_stroke">conv_stroke</a><span class="op"><</span> + agg::<a href="http://www.antigrain.com/__code/include/agg_conv_segmentator.h.html#conv_segmentator">conv_segmentator</a><span class="op"><</span> + agg::<a href="http://www.antigrain.com/__code/include/agg_conv_curve.h.html#conv_curve">conv_curve</a><span class="op"><</span> + agg::<a href="http://www.antigrain.com/__code/include/agg_path_storage.h.html#path_storage">path_storage</a><span class="op">></span> <span class="op">></span> <span class="op">></span><span class="op">,</span> + agg::<a href="http://www.antigrain.com/__code/include/agg_trans_affine.h.html#trans_affine">trans_affine</a><span class="op">></span> trans_stroke<span class="op">(</span>stroke<span class="op">,</span> matrix<span class="op">)</span><span class="op">;</span> + + agg::<a href="http://www.antigrain.com/__code/include/agg_conv_transform.h.html#conv_transform">conv_transform</a><span class="op"><</span> + agg::<a href="http://www.antigrain.com/__code/include/agg_conv_transform.h.html#conv_transform">conv_transform</a><span class="op"><</span> + agg::<a href="http://www.antigrain.com/__code/include/agg_conv_stroke.h.html#conv_stroke">conv_stroke</a><span class="op"><</span> + agg::<a href="http://www.antigrain.com/__code/include/agg_conv_segmentator.h.html#conv_segmentator">conv_segmentator</a><span class="op"><</span> + agg::<a href="http://www.antigrain.com/__code/include/agg_conv_curve.h.html#conv_curve">conv_curve</a><span class="op"><</span> + agg::<a href="http://www.antigrain.com/__code/include/agg_path_storage.h.html#path_storage">path_storage</a><span class="op">></span> <span class="op">></span> <span class="op">></span><span class="op">,</span> + agg::<a href="http://www.antigrain.com/__code/include/agg_trans_affine.h.html#trans_affine">trans_affine</a><span class="op">></span><span class="op">,</span> + agg::<a href="http://www.antigrain.com/__code/include/agg_trans_warp_magnifier.h.html#trans_warp_magnifier">trans_warp_magnifier</a><span class="op">></span> trans_warp_stroke<span class="op">(</span>trans_stroke<span class="op">,</span> lens<span class="op">)</span><span class="op">;</span> + + stroke<span class="op">.</span>width<span class="op">(</span><span class="num">6</span><span class="op">.</span><span class="num">0</span><span class="op">)</span><span class="op">;</span> + + <span class="rem">// Set the fill color and render the polygon:</span> + <span class="rem">//-----------------------</span> + ras<span class="op">.</span>add_path<span class="op">(</span>trans_warp<span class="op">)</span><span class="op">;</span> + ren_sl<span class="op">.</span>color<span class="op">(</span>agg::<a href="http://www.antigrain.com/__code/include/agg_color_rgba.h.html#rgba8">rgba8</a><span class="op">(</span><span class="num">160</span><span class="op">,</span> <span class="num">180</span><span class="op">,</span> <span class="num">80</span><span class="op">)</span><span class="op">)</span><span class="op">;</span> + agg::<a href="http://www.antigrain.com/__code/include/agg_renderer_scanline.h.html#render_scanlines">render_scanlines</a><span class="op">(</span>ras<span class="op">,</span> sl<span class="op">,</span> ren_sl<span class="op">)</span><span class="op">;</span> + + <span class="rem">// Set the stroke color and render the stroke:</span> + <span class="rem">//-----------------------</span> + ras<span class="op">.</span>add_path<span class="op">(</span>trans_warp_stroke<span class="op">)</span><span class="op">;</span> + ren_sl<span class="op">.</span>color<span class="op">(</span>agg::<a href="http://www.antigrain.com/__code/include/agg_color_rgba.h.html#rgba8">rgba8</a><span class="op">(</span><span class="num">120</span><span class="op">,</span> <span class="num">100</span><span class="op">,</span> <span class="num">0</span><span class="op">)</span><span class="op">)</span><span class="op">;</span> + agg::<a href="http://www.antigrain.com/__code/include/agg_renderer_scanline.h.html#render_scanlines">render_scanlines</a><span class="op">(</span>ras<span class="op">,</span> sl<span class="op">,</span> ren_sl<span class="op">)</span><span class="op">;</span> + <span class="rem">//-----------------------</span> +</pre></td></tr></tbody></table><font style="margin-left: 1em;"><i></i></font> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>The +compilation command line is: +</p></td></tr></tbody></table><table width="640px" border="0" +cellpadding="0" cellspacing="0"><tbody><tr><td><pre>g++ -I/agg2/include example_pipeline7.cpp + /agg2/src/agg_rasterizer_scanline_aa.cpp + /agg2/src/agg_path_storage.cpp + /agg2/src/<a href="http://www.antigrain.com/__code/src/agg_bezier_arc.cpp.html">agg_bezier_arc.cpp</a> + /agg2/src/<a href="http://www.antigrain.com/__code/src/agg_trans_affine.cpp.html">agg_trans_affine.cpp</a> + /agg2/src/<a href="http://www.antigrain.com/__code/src/agg_curves.cpp.html">agg_curves.cpp</a> + /agg2/src/<a href="http://www.antigrain.com/__code/src/agg_vcgen_stroke.cpp.html">agg_vcgen_stroke.cpp</a> + /agg2/src/<a href="http://www.antigrain.com/__code/src/agg_vpgen_segmentator.cpp.html">agg_vpgen_segmentator.cpp</a> + /agg2/src/<a href="http://www.antigrain.com/__code/src/agg_trans_warp_magnifier.cpp.html">agg_trans_warp_magnifier.cpp</a> +</pre></td></tr></tbody></table><font style="margin-left: 1em;"><i></i></font> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>The +result: +</p></td></tr></tbody></table><table width="640px"><tbody><tr><td><center><img + src="ddj1.agdoc_files/example_pipeline7.gif" title="" border="0"><br><i></i></center></td></tr></tbody></table> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>These + examples demonstrate the main principle of <b>AGG</b> design, that is +that you have full control upon your rendering model and required +capabilities. The declarations can look too complex, but first, +they can be simplified with the use of <code>typedef</code>s, and +second, +they usually are not seen outside. You just create a problem oriented +wrapper once and use it as a conventional graphic library. +The pipelines that support capabilities of SVG, GDI+, or say, +PDF are very simple. The last example just demonstrates that +it's very easy to extend the functionality. In the examples +the pipeline is defined statically, at the compile time, which +is suitable in most cases. But the template mechanism allows you +to write simple polymorphic wrappers and construct the pipelines +dynamically, at run-tume.</p></td></tr></tbody></table> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>The +raster pipelines are organized in a similar way, but they are +usually much simpler. After the vectorial shape is rasterized you can +do the following:</p></td></tr></tbody></table> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p></p><ul + type="disc"> +<li>Fill the shape with a solid color and possible transparency.</li> +<li>Fill with an arbitrary gradient. All possible transformations + are applicable to the gradients as well.</li> +<li>Fill the shape with a transformed image. There many different + Anti-Aliasing filter are available, from simple bilinear to + high degree Lancosz and Blackman ones.</li> +<li>Fill the shape with an arbitrary pattern.</li> +<li>Apply an alpha-mask.</li> +<li>Apply a number of Scanline Boolean Algebra operations, such as, + Intersection, Union, Difference, and XOR between two or more + scanline shapes.</li></ul><p></p></td></tr></tbody></table> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>The +number of possibilities is practically endless, and the point +is that you can always write your own algorithms and span +generators and insert them into the pipeline.</p></td></tr></tbody></table> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p><b>AGG</b> + has many other interesting algorithms, in particular, using +raster images as line patterns. This is a very powerful mechanism +for cartography and similar applications and I haven't seen +any valuable implementation of it so far. +</p></td></tr></tbody></table><table width="640px"><tbody><tr><td><center><img + src="ddj1.agdoc_files/line_patterns.gif" title="" border="0"><br><i></i></center></td></tr></tbody></table> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>Currently + <b>AGG</b> is in active development, but its main interfaces +are pretty much stabilized.</p></td></tr></tbody></table> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>You +can find many other examples, including multi-platform +interactive ones on the Antigrain.com web site <a +href="http://antigrain.com/"><img src="ddj1.agdoc_files/link.gif" +border="0">http://antigrain.com</a>. +</p></td></tr></tbody></table><br><table style="margin: 0px;" +height="1px" width="640px" bgcolor="#583927" border="0" cellpadding="0" +cellspacing="0"><tbody><tr><td></td></tr></tbody></table> +<table width="640px" border="0" cellpadding="0" cellspacing="0"> +<tbody><tr><td><center><span class="authors"> +Copyright <span class="larger">©</span> 2002-2006 +<a href="http://www.antigrain.com/mcseem/index.html"><b>Maxim Shemanarev</b></a> +</span></center></td></tr> +<tr><td><center><span class="authors"> +Web Design and Programming +<a href="http://www.antigrain.com/mcseem/index.html"><b>Maxim Shemanarev</b></a> +</span></center></td></tr> +</tbody></table> +<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br> +<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br> +<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br> +<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br> +</body></html>
\ No newline at end of file diff --git a/docs/aggpas/ddj1.agdoc_files/agg.css b/docs/aggpas/ddj1.agdoc_files/agg.css new file mode 100644 index 00000000..997d9d07 --- /dev/null +++ b/docs/aggpas/ddj1.agdoc_files/agg.css @@ -0,0 +1,239 @@ +BODY +{ + font-family:Verdana, Arial, Tahoma; + font-size:12px; + color:#160801; + background-color:#ffffff; + text-align:justify; + padding:5px; +} + +P, UL, OL, DL +{ + font-family:Verdana, Arial, Tahoma; + font-size:12px; + color:#160801; + margin-bottom:0px; + margin-top:0px; +} + + +.larger +{ + font-size:14px; +} + +LI +{ + padding:3px; +} + +HR +{ + color:#583927; + height:1px; +} + +H1 +{ + font-family:Verdana, Arial, Tahoma; + font-size:28px; + font-weight:bolder; + text-align:center; + color:#583927; + margin:0px; +} + +H1 SPAN.subtitle +{ + font-family:Verdana, Arial, Tahoma; + font-size:18px; + font-weight:lighter; +} + + +H2 +{ + font-family:Verdana, Arial, Tahoma; + font-size:26px; + font-weight:normal; + text-align:left; + color:#583927; +} + +H3 +{ + font-family:Verdana, Arial, Tahoma; + font-size:20px; + font-weight:normal; + text-align:left; + color:#583927; +} + +H4 +{ + font-family:Verdana, Arial, Tahoma; + font-size:16px; + font-weight:bold; + text-align:left; + color:#583927; +} + +H5 +{ + font-family:Verdana, Arial, Tahoma; + font-size:14px; + font-weight:bold; + text-align:left; + color:#583927; +} + +TABLE +{ + margin:5px; +} + +TD +{ + font-family:Verdana, Arial, Tahoma; + font-size:12px; +} + +TH +{ + font-family:Verdana, Arial, Tahoma; + background-color:#d4d4d4; + font-size:12px; +} + + +PRE +{ + padding: 5px; + border: gray 1px solid; + background-color:#f4f4f4; + color:#130f00; + font-family:"courier new", courier,mono; + font-size:12px; + margin:0px; +} + +TT, CODE +{ + font-family:"courier new", courier,mono; + font-size:14px; + color:#000070; +} + +.warning, .warning TD +{ + background-color:#fcf6f6; + color:#793131; + padding:0.5em; + font-family:Verdana, Arial, Tahoma; + font-size:12px; + text-align:justify; +} + +.note, .note TD +{ + background-color:#f0fafa; + color:#506580; + padding:0.5em; + font-family:Verdana, Arial, Tahoma; + font-size:12px; + text-align:justify; +} + +.quote, .quote TD +{ + background-color:#f0fafa; + color:#000540; + padding:0.5em; + font-family:Verdana, Arial, Tahoma; + font-size:12px; + text-align:justify; +} + +.tip, .tip TD +{ + background-color:#fbfff6; + color:#68771e; + padding:0.5em; + font-family:Verdana, Arial, Tahoma; + font-size:12px; + text-align:justify; +} + +.tbl TD +{ + background-color:#f4f4f4; + font-family:Verdana, Arial, Tahoma; + font-size:12px; + text-align:left; + padding:3px; +} + +.toc TD +{ + font-family:Verdana, Arial, Tahoma; + text-align:left; + padding:3px; +} + +.title {font-family:Verdana, Arial, Tahoma;} + +.warning P, +.warning PRE, +.note P, +.note PRE, +.tip P, +.tip PRE {margin:0.3em 0em 0.1em 0em;} + +.warning .code {background-color:#fcf6f6;} +.note .code {background-color:#f0fafa;} +.tip .code {background-color:#fbfff6;} + +A {text-decoration:none; color:#700000;} +A:visited {text-decoration:none; color:#85585d;} +A:link {text-decoration:none;} +A:hover {text-decoration:underline;} + +.topmenu,a.topmenu:visited,a.topmenu:hover,a.topmenu:active,a.topmenu:link +{ + font-family: Arial, Tahoma, Helvetica, sans-serif; + font-size: 11px; + font-weight: bold; + text-decoration: none; + color: #582218; +} + +.mpmenu,a.mpmenu:visited,a.mpmenu:hover,a.mpmenu:active,a.mpmenu:link +{ + font-family: Arial, Tahoma, Helvetica, sans-serif; + font-size: 12px; + font-weight: bold; + text-decoration: none; + color: #582218; +} + +.tah +{ + font-family: Tahoma, Arial, Helvetica, sans-serif; + font-size: 12px; + color: #582218; +} + +.authors +{ + font-size:10px; +} + +span.rem {color:#4c8d00;} +span.kw1 {color:#000d8e;} +span.kw2 {color:#0075ca;} +span.kw3 {color:#004645;} +span.kw4 {color:#673517;} +span.op {color:#4a006d;} +span.str {color:#ab2500;} +span.num {color:#a74c3f;} diff --git a/docs/aggpas/ddj1.agdoc_files/architecture.gif b/docs/aggpas/ddj1.agdoc_files/architecture.gif Binary files differnew file mode 100644 index 00000000..dadc04f2 --- /dev/null +++ b/docs/aggpas/ddj1.agdoc_files/architecture.gif diff --git a/docs/aggpas/ddj1.agdoc_files/example_pipeline1.gif b/docs/aggpas/ddj1.agdoc_files/example_pipeline1.gif Binary files differnew file mode 100644 index 00000000..a31f14e5 --- /dev/null +++ b/docs/aggpas/ddj1.agdoc_files/example_pipeline1.gif diff --git a/docs/aggpas/ddj1.agdoc_files/example_pipeline2.gif b/docs/aggpas/ddj1.agdoc_files/example_pipeline2.gif Binary files differnew file mode 100644 index 00000000..60839093 --- /dev/null +++ b/docs/aggpas/ddj1.agdoc_files/example_pipeline2.gif diff --git a/docs/aggpas/ddj1.agdoc_files/example_pipeline3.gif b/docs/aggpas/ddj1.agdoc_files/example_pipeline3.gif Binary files differnew file mode 100644 index 00000000..56295bef --- /dev/null +++ b/docs/aggpas/ddj1.agdoc_files/example_pipeline3.gif diff --git a/docs/aggpas/ddj1.agdoc_files/example_pipeline31.gif b/docs/aggpas/ddj1.agdoc_files/example_pipeline31.gif Binary files differnew file mode 100644 index 00000000..ddd0172a --- /dev/null +++ b/docs/aggpas/ddj1.agdoc_files/example_pipeline31.gif diff --git a/docs/aggpas/ddj1.agdoc_files/example_pipeline4.gif b/docs/aggpas/ddj1.agdoc_files/example_pipeline4.gif Binary files differnew file mode 100644 index 00000000..b3da50b1 --- /dev/null +++ b/docs/aggpas/ddj1.agdoc_files/example_pipeline4.gif diff --git a/docs/aggpas/ddj1.agdoc_files/example_pipeline5.gif b/docs/aggpas/ddj1.agdoc_files/example_pipeline5.gif Binary files differnew file mode 100644 index 00000000..98016c43 --- /dev/null +++ b/docs/aggpas/ddj1.agdoc_files/example_pipeline5.gif diff --git a/docs/aggpas/ddj1.agdoc_files/example_pipeline6.gif b/docs/aggpas/ddj1.agdoc_files/example_pipeline6.gif Binary files differnew file mode 100644 index 00000000..09e40e19 --- /dev/null +++ b/docs/aggpas/ddj1.agdoc_files/example_pipeline6.gif diff --git a/docs/aggpas/ddj1.agdoc_files/example_pipeline7.gif b/docs/aggpas/ddj1.agdoc_files/example_pipeline7.gif Binary files differnew file mode 100644 index 00000000..35e4bb5a --- /dev/null +++ b/docs/aggpas/ddj1.agdoc_files/example_pipeline7.gif diff --git a/docs/aggpas/ddj1.agdoc_files/line_patterns.gif b/docs/aggpas/ddj1.agdoc_files/line_patterns.gif Binary files differnew file mode 100644 index 00000000..558aa340 --- /dev/null +++ b/docs/aggpas/ddj1.agdoc_files/line_patterns.gif diff --git a/docs/aggpas/ddj1.agdoc_files/link.gif b/docs/aggpas/ddj1.agdoc_files/link.gif Binary files differnew file mode 100644 index 00000000..76a532cf --- /dev/null +++ b/docs/aggpas/ddj1.agdoc_files/link.gif diff --git a/docs/aggpas/ddj1.agdoc_files/subpixel_accuracy2.gif b/docs/aggpas/ddj1.agdoc_files/subpixel_accuracy2.gif Binary files differnew file mode 100644 index 00000000..c940508c --- /dev/null +++ b/docs/aggpas/ddj1.agdoc_files/subpixel_accuracy2.gif diff --git a/docs/aggpas/gamma_correction.html b/docs/aggpas/gamma_correction.html new file mode 100644 index 00000000..e5c91926 --- /dev/null +++ b/docs/aggpas/gamma_correction.html @@ -0,0 +1,245 @@ +<html><head><title>Anti-Grain Geometry - Gamma Correction</title> +<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> +<link rel="stylesheet" type="text/css" +href="gamma_correction_files/agg.css"> +</head><body><a name="PAGE_GAMMA_CORRECTION"><b></b></a> + + +<table style="margin: 0px;" height="1px" width="640px" border="0" +cellpadding="0" cellspacing="0"> +<tbody><tr> +<td bgcolor="#583927"></td> +</tr> +</tbody></table> +<table style="margin: 0px;" width="640px" border="0" cellpadding="0" +cellspacing="0"> +<tbody><tr> +<td> +<table style="margin: 0px;" width="170px" border="0" cellpadding="0" +cellspacing="0"> +<tbody><tr><td><a href="http://www.antigrain.com/index.html" +class="mpmenu">Home/</a></td></tr> +<tr><td><a href="http://www.antigrain.com/research/index.html" +class="mpmenu">Research/</a></td></tr> +<tr><td><a href="" class="mpmenu"></a></td></tr> +<tr><td><a href="" class="mpmenu"></a></td></tr> +<tr><td><a href="" class="mpmenu"></a></td></tr> +<tr><td><a href="" class="mpmenu"></a></td></tr> +</tbody></table> +</td> +<td width="1px" bgcolor="#583927"></td> +<td style="text-align: right;" valign="top" width="450px"> +<table style="margin: 0px;" border="0" cellpadding="0" cellspacing="0"> +<tbody><tr> +<td><img src="gamma_correction_files/agg_logo.gif" border="0"></td> +</tr> +<tr> +<td> +<table style="margin: 0px;" border="0" cellpadding="0" cellspacing="0"> +<tbody><tr height="15px"> +<td> <a class="topmenu" +href="http://www.antigrain.com/news/index.html">News</a> </td> +<td width="1px" bgcolor="#8e521d"></td> +<td> <a class="topmenu" +href="http://www.antigrain.com/doc/index.html">Docs</a> </td> +<td width="1px" bgcolor="#8e521d"></td> +<td> <a class="topmenu" +href="http://www.antigrain.com/download/index.html">Download</a> </td> +<td width="1px" bgcolor="#8e521d"></td> +<td> <a class="topmenu" +href="http://www.antigrain.com/maillist/index.html">Mailing List</a> </td> +<td width="1px" bgcolor="#8e521d"></td> +<td> <a class="topmenu" +href="http://www.antigrain.com/cvs/index.html">CVS</a> </td> +</tr> +</tbody></table> +</td> +</tr> +</tbody></table> +</td> +</tr> +</tbody></table> +<table style="margin: 0px;" height="1px" width="640px" bgcolor="#583927" + border="0" cellpadding="0" cellspacing="0"><tbody><tr><td></td></tr></tbody></table> + + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p> +</p></td></tr></tbody></table> + +<table width="640px"><tbody><tr><td><h1>Gamma Correction<span +class="subtitle"><br>Using Gamma Correction in Anti-Aliasing</span></h1></td></tr></tbody></table> + + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p><b><nobr>Anti-Aliasing</nobr></b> + technology is always difficult. The difficulty here +is not only in algorithms, but also because the visual quality of +the image depends on the displaying equipment. <b><nobr>Anti-Aliasing</nobr></b> + images look +differently on CRT monitors and on LCD ones. In general it's a +science (or maybe even art) called Color Management. +<b><nobr>Anti-Grain</nobr> Geometry</b> uses the approach of <b><nobr>Anti-Aliasing</nobr></b> + that potentially allows us to +obtain the best result. The rendering procedure calculates the +exact coverage values for every boundary pixel and as a result +one can have any number of <b><nobr>Anti-Aliasing</nobr></b> levels. +<b><nobr>Anti-Grain</nobr> Geometry</b> uses 256 levels which is quite +enough for any practical +purpose and much better than 5-level <b><nobr>Anti-Aliasing</nobr></b> +used in many applications, +for example, True-Type font renderers, almost all +<a href="http://www.adobe.com/"><img +src="gamma_correction_files/link.gif" border="0">Adobe</a> products and +so on. +I was absolutely sure that the rendering method I use gives +the best result. But when I tried to render the same image +with <b><nobr>Anti-Grain</nobr> Geometry</b> and <a +href="http://www.adobe.com/svg/"><img +src="gamma_correction_files/link.gif" border="0">Adobe SVG Viewer</a> +I found out that the Adobe SVG Viewer uses only 5 levels of <b><nobr>Anti-Aliasing</nobr></b>, + +but the result sometimes looks better than in <b><nobr>Anti-Grain</nobr> + Geometry</b>.</p></td></tr></tbody></table> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p><img + src="gamma_correction_files/gamma_lion1.jpg" title="" border="0"><!----> + <img src="gamma_correction_files/gamma_lion2.jpg" +title="" border="0"><!----></p></td></tr></tbody></table> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>The +left image is rendered with <b><nobr>Anti-Grain</nobr> Geometry</b>, the + right one with the +<a href="http://www.adobe.com/svg/"><img +src="gamma_correction_files/link.gif" border="0">Adobe SVG Viewer</a>. +</p></td></tr></tbody></table><table style="margin: 0px;" height="1px" +width="640px" bgcolor="#583927" border="0" cellpadding="0" +cellspacing="0"><tbody><tr><td></td></tr></tbody></table> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>The +lion's moustache look smoother when rendering with 5-level +Adobe SVG Viewer, al least on CRT monitors. But still, the enlarged +images show us the lack of the <b><nobr>Anti-Aliasing</nobr></b> levels +used in Adobe Viewer.</p></td></tr></tbody></table> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p><img + src="gamma_correction_files/gamma_lion1e.jpg" title="" border="0"><!----> + <img src="gamma_correction_files/gamma_lion2e.jpg" +title="" border="0"><!----></p></td></tr></tbody></table> + +<table style="margin: 0px;" height="1px" width="640px" bgcolor="#583927" + border="0" cellpadding="0" cellspacing="0"><tbody><tr><td></td></tr></tbody></table> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p><img + src="gamma_correction_files/gamma.gif" title="" style="border-color: +rgb(255, 255, 255);" align="left" border="4"><!----> +Obviously, <b><nobr>Anti-Grain</nobr> Geometry</b> can render better, +but using a simple linear dependance +Pixel Coverage <span class="larger">→</span> Brightness is not the best +and should be corrected. +In color management it's called Gamma Correction. For gamma correction +I use a simple array of 256 values that give the desired value of +brightness +depending on the pixel coverage. If all the values in the array are +equal +to their index, i.e., 0,1,2,3,4,… it means that there's no gamma +correction. +The array can be calculated using any approach, but the simplest method +is to use a B-Spline curve with two reference points and four +coeffitiens +(kx1, ky1, kx2, ky2) that determine its shape. So, I created an +application +with a special gamma correction control that allows for calculation of +the +array of the gamma values. +It draws 6 very narrow ellipses, 6 circles and some other figures that +can be used as a visual test of the quality of <b><nobr>Anti-Aliasing</nobr></b>. +</p></td></tr></tbody></table><table style="margin: 0px;" height="1px" +width="640px" bgcolor="#583927" border="0" cellpadding="0" +cellspacing="0"><tbody><tr><td></td></tr></tbody></table> + +<table width="640px"><tbody><tr><td><center><img +src="gamma_correction_files/gamma1.gif" title="Default Shape - No Gamma +Correction" border="0"><br><i>Default Shape - No Gamma Correction</i></center></td></tr></tbody></table> +<table style="margin: 0px;" height="1px" width="640px" bgcolor="#583927" + border="0" cellpadding="0" cellspacing="0"><tbody><tr><td></td></tr></tbody></table> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>The +control points can be moved inside their quadrants. +The following image looks much better at least on CRT monitors.</p></td></tr></tbody></table> + +<table width="640px"><tbody><tr><td><center><img +src="gamma_correction_files/gamma2.gif" title="Gamma Correction for CRT +Monitors" border="0"><br><i>Gamma Correction for CRT Monitors</i></center></td></tr></tbody></table> +<table style="margin: 0px;" height="1px" width="640px" bgcolor="#583927" + border="0" cellpadding="0" cellspacing="0"><tbody><tr><td></td></tr></tbody></table> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>We +actually can obtain much better result of certain thickness and +brightness, but it cannot be used for general case. The shown above +example is a kind of an average case which is not the best for certain +parameters, but gives us rather a good average result on CRT monitors, +as well as on LCD ones. Below are the examples of other shapes of the +gamma curve.</p></td></tr></tbody></table> + +<table width="640px"><tbody><tr><td><center><img +src="gamma_correction_files/gamma3.gif" title="Test Gamma 1" border="0"><br><i>Test + Gamma 1</i></center></td></tr></tbody></table> +<table width="640px"><tbody><tr><td><center><img +src="gamma_correction_files/gamma4.gif" title="Test Gamma 2" border="0"><br><i>Test + Gamma 2</i></center></td></tr></tbody></table> +<table width="640px"><tbody><tr><td><center><img +src="gamma_correction_files/gamma5.gif" title="Test Gamma 3" border="0"><br><i>Test + Gamma 3</i></center></td></tr></tbody></table> +<table style="margin: 0px;" height="1px" width="640px" bgcolor="#583927" + border="0" cellpadding="0" cellspacing="0"><tbody><tr><td></td></tr></tbody></table> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>Besides, + the gamma correction strongly depends on the content of the image. +The values that are good enough for rendering ellipses like shown above +may give a very bad result when rendering small text glyphs. The latest +require sharper forms, while large geometric figures look better with +very smooth edges. +</p></td></tr></tbody></table><table style="margin: 0px;" height="1px" +width="640px" bgcolor="#583927" border="0" cellpadding="0" +cellspacing="0"><tbody><tr><td></td></tr></tbody></table> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>Finally, + this is the result of rendering the same lion with gamma correction +for CRT monitors. Now it looks better than the one rendered with Adobe +SVG Viewer.</p></td></tr></tbody></table> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p><img + src="gamma_correction_files/gamma_lion3.jpg" title="" border="0"><!----> + <img src="gamma_correction_files/gamma_lion3e.jpg" +title="" border="0"><!----></p></td></tr></tbody></table> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>You +can download the working application for Windows: +<a +href="http://www.antigrain.com/research/gamma_correction/gamma_ctrl.zip"><img + src="gamma_correction_files/download.gif" border="0">Gamma Control + (gamma_ctrl.zip)</a></p></td></tr></tbody></table> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>The +source code can be found in the <code>examples</code> directory of the +distribution package. Visit the <a +href="http://www.antigrain.com/download/index.html#PAGE_DOWNLOAD">Download</a> + page.</p></td></tr></tbody></table> + + +<table style="margin: 0px;" height="1px" width="640px" bgcolor="#583927" + border="0" cellpadding="0" cellspacing="0"><tbody><tr><td></td></tr></tbody></table> +<table width="640px" border="0" cellpadding="0" cellspacing="0"> +<tbody><tr><td><center><span class="authors"> +Copyright <span class="larger">©</span> 2002-2006 +<a href="http://www.antigrain.com/mcseem/index.html"><b>Maxim Shemanarev</b></a> +</span></center></td></tr> +<tr><td><center><span class="authors"> +Web Design and Programming +<a href="http://www.antigrain.com/mcseem/index.html"><b>Maxim Shemanarev</b></a> +</span></center></td></tr> +</tbody></table> +<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br> +<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br> +<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br> +<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br> +</body></html>
\ No newline at end of file diff --git a/docs/aggpas/gamma_correction_files/agg.css b/docs/aggpas/gamma_correction_files/agg.css new file mode 100644 index 00000000..997d9d07 --- /dev/null +++ b/docs/aggpas/gamma_correction_files/agg.css @@ -0,0 +1,239 @@ +BODY +{ + font-family:Verdana, Arial, Tahoma; + font-size:12px; + color:#160801; + background-color:#ffffff; + text-align:justify; + padding:5px; +} + +P, UL, OL, DL +{ + font-family:Verdana, Arial, Tahoma; + font-size:12px; + color:#160801; + margin-bottom:0px; + margin-top:0px; +} + + +.larger +{ + font-size:14px; +} + +LI +{ + padding:3px; +} + +HR +{ + color:#583927; + height:1px; +} + +H1 +{ + font-family:Verdana, Arial, Tahoma; + font-size:28px; + font-weight:bolder; + text-align:center; + color:#583927; + margin:0px; +} + +H1 SPAN.subtitle +{ + font-family:Verdana, Arial, Tahoma; + font-size:18px; + font-weight:lighter; +} + + +H2 +{ + font-family:Verdana, Arial, Tahoma; + font-size:26px; + font-weight:normal; + text-align:left; + color:#583927; +} + +H3 +{ + font-family:Verdana, Arial, Tahoma; + font-size:20px; + font-weight:normal; + text-align:left; + color:#583927; +} + +H4 +{ + font-family:Verdana, Arial, Tahoma; + font-size:16px; + font-weight:bold; + text-align:left; + color:#583927; +} + +H5 +{ + font-family:Verdana, Arial, Tahoma; + font-size:14px; + font-weight:bold; + text-align:left; + color:#583927; +} + +TABLE +{ + margin:5px; +} + +TD +{ + font-family:Verdana, Arial, Tahoma; + font-size:12px; +} + +TH +{ + font-family:Verdana, Arial, Tahoma; + background-color:#d4d4d4; + font-size:12px; +} + + +PRE +{ + padding: 5px; + border: gray 1px solid; + background-color:#f4f4f4; + color:#130f00; + font-family:"courier new", courier,mono; + font-size:12px; + margin:0px; +} + +TT, CODE +{ + font-family:"courier new", courier,mono; + font-size:14px; + color:#000070; +} + +.warning, .warning TD +{ + background-color:#fcf6f6; + color:#793131; + padding:0.5em; + font-family:Verdana, Arial, Tahoma; + font-size:12px; + text-align:justify; +} + +.note, .note TD +{ + background-color:#f0fafa; + color:#506580; + padding:0.5em; + font-family:Verdana, Arial, Tahoma; + font-size:12px; + text-align:justify; +} + +.quote, .quote TD +{ + background-color:#f0fafa; + color:#000540; + padding:0.5em; + font-family:Verdana, Arial, Tahoma; + font-size:12px; + text-align:justify; +} + +.tip, .tip TD +{ + background-color:#fbfff6; + color:#68771e; + padding:0.5em; + font-family:Verdana, Arial, Tahoma; + font-size:12px; + text-align:justify; +} + +.tbl TD +{ + background-color:#f4f4f4; + font-family:Verdana, Arial, Tahoma; + font-size:12px; + text-align:left; + padding:3px; +} + +.toc TD +{ + font-family:Verdana, Arial, Tahoma; + text-align:left; + padding:3px; +} + +.title {font-family:Verdana, Arial, Tahoma;} + +.warning P, +.warning PRE, +.note P, +.note PRE, +.tip P, +.tip PRE {margin:0.3em 0em 0.1em 0em;} + +.warning .code {background-color:#fcf6f6;} +.note .code {background-color:#f0fafa;} +.tip .code {background-color:#fbfff6;} + +A {text-decoration:none; color:#700000;} +A:visited {text-decoration:none; color:#85585d;} +A:link {text-decoration:none;} +A:hover {text-decoration:underline;} + +.topmenu,a.topmenu:visited,a.topmenu:hover,a.topmenu:active,a.topmenu:link +{ + font-family: Arial, Tahoma, Helvetica, sans-serif; + font-size: 11px; + font-weight: bold; + text-decoration: none; + color: #582218; +} + +.mpmenu,a.mpmenu:visited,a.mpmenu:hover,a.mpmenu:active,a.mpmenu:link +{ + font-family: Arial, Tahoma, Helvetica, sans-serif; + font-size: 12px; + font-weight: bold; + text-decoration: none; + color: #582218; +} + +.tah +{ + font-family: Tahoma, Arial, Helvetica, sans-serif; + font-size: 12px; + color: #582218; +} + +.authors +{ + font-size:10px; +} + +span.rem {color:#4c8d00;} +span.kw1 {color:#000d8e;} +span.kw2 {color:#0075ca;} +span.kw3 {color:#004645;} +span.kw4 {color:#673517;} +span.op {color:#4a006d;} +span.str {color:#ab2500;} +span.num {color:#a74c3f;} diff --git a/docs/aggpas/gamma_correction_files/agg_logo.gif b/docs/aggpas/gamma_correction_files/agg_logo.gif Binary files differnew file mode 100644 index 00000000..ee5c570a --- /dev/null +++ b/docs/aggpas/gamma_correction_files/agg_logo.gif diff --git a/docs/aggpas/gamma_correction_files/download.gif b/docs/aggpas/gamma_correction_files/download.gif Binary files differnew file mode 100644 index 00000000..fd9367e4 --- /dev/null +++ b/docs/aggpas/gamma_correction_files/download.gif diff --git a/docs/aggpas/gamma_correction_files/gamma.gif b/docs/aggpas/gamma_correction_files/gamma.gif Binary files differnew file mode 100644 index 00000000..fedf07a6 --- /dev/null +++ b/docs/aggpas/gamma_correction_files/gamma.gif diff --git a/docs/aggpas/gamma_correction_files/gamma1.gif b/docs/aggpas/gamma_correction_files/gamma1.gif Binary files differnew file mode 100644 index 00000000..73b0d368 --- /dev/null +++ b/docs/aggpas/gamma_correction_files/gamma1.gif diff --git a/docs/aggpas/gamma_correction_files/gamma2.gif b/docs/aggpas/gamma_correction_files/gamma2.gif Binary files differnew file mode 100644 index 00000000..0670ad4e --- /dev/null +++ b/docs/aggpas/gamma_correction_files/gamma2.gif diff --git a/docs/aggpas/gamma_correction_files/gamma3.gif b/docs/aggpas/gamma_correction_files/gamma3.gif Binary files differnew file mode 100644 index 00000000..c2d474b3 --- /dev/null +++ b/docs/aggpas/gamma_correction_files/gamma3.gif diff --git a/docs/aggpas/gamma_correction_files/gamma4.gif b/docs/aggpas/gamma_correction_files/gamma4.gif Binary files differnew file mode 100644 index 00000000..4da1c607 --- /dev/null +++ b/docs/aggpas/gamma_correction_files/gamma4.gif diff --git a/docs/aggpas/gamma_correction_files/gamma5.gif b/docs/aggpas/gamma_correction_files/gamma5.gif Binary files differnew file mode 100644 index 00000000..65820b2c --- /dev/null +++ b/docs/aggpas/gamma_correction_files/gamma5.gif diff --git a/docs/aggpas/gamma_correction_files/gamma_lion1.jpg b/docs/aggpas/gamma_correction_files/gamma_lion1.jpg Binary files differnew file mode 100644 index 00000000..f1ce3270 --- /dev/null +++ b/docs/aggpas/gamma_correction_files/gamma_lion1.jpg diff --git a/docs/aggpas/gamma_correction_files/gamma_lion1e.jpg b/docs/aggpas/gamma_correction_files/gamma_lion1e.jpg Binary files differnew file mode 100644 index 00000000..0f3753a9 --- /dev/null +++ b/docs/aggpas/gamma_correction_files/gamma_lion1e.jpg diff --git a/docs/aggpas/gamma_correction_files/gamma_lion2.jpg b/docs/aggpas/gamma_correction_files/gamma_lion2.jpg Binary files differnew file mode 100644 index 00000000..21bba5ef --- /dev/null +++ b/docs/aggpas/gamma_correction_files/gamma_lion2.jpg diff --git a/docs/aggpas/gamma_correction_files/gamma_lion2e.jpg b/docs/aggpas/gamma_correction_files/gamma_lion2e.jpg Binary files differnew file mode 100644 index 00000000..6c6ae9b7 --- /dev/null +++ b/docs/aggpas/gamma_correction_files/gamma_lion2e.jpg diff --git a/docs/aggpas/gamma_correction_files/gamma_lion3.jpg b/docs/aggpas/gamma_correction_files/gamma_lion3.jpg Binary files differnew file mode 100644 index 00000000..9710e0e3 --- /dev/null +++ b/docs/aggpas/gamma_correction_files/gamma_lion3.jpg diff --git a/docs/aggpas/gamma_correction_files/gamma_lion3e.jpg b/docs/aggpas/gamma_correction_files/gamma_lion3e.jpg Binary files differnew file mode 100644 index 00000000..34f6bddc --- /dev/null +++ b/docs/aggpas/gamma_correction_files/gamma_lion3e.jpg diff --git a/docs/aggpas/gamma_correction_files/link.gif b/docs/aggpas/gamma_correction_files/link.gif Binary files differnew file mode 100644 index 00000000..76a532cf --- /dev/null +++ b/docs/aggpas/gamma_correction_files/link.gif diff --git a/docs/aggpas/gradients_tutorial.html b/docs/aggpas/gradients_tutorial.html new file mode 100644 index 00000000..b9302451 --- /dev/null +++ b/docs/aggpas/gradients_tutorial.html @@ -0,0 +1,539 @@ +<html><head><title>Anti-Grain Geometry - Working with Gradients</title> +<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> +<link rel="stylesheet" type="text/css" +href="gradients_tutorial_files/agg.css"> +</head><body><a name="PAGE_GRADIENTS_TUTORIAL"><b></b></a> + + +<table style="margin: 0px;" height="1px" width="640px" border="0" +cellpadding="0" cellspacing="0"> +<tbody><tr> +<td bgcolor="#583927"></td> +</tr> +</tbody></table> +<table style="margin: 0px;" width="640px" border="0" cellpadding="0" +cellspacing="0"> +<tbody><tr> +<td> +<table style="margin: 0px;" width="170px" border="0" cellpadding="0" +cellspacing="0"> +<tbody><tr><td><a href="http://www.antigrain.com/index.html" +class="mpmenu">Home/</a></td></tr> +<tr><td><a href="http://www.antigrain.com/tips/index.html" +class="mpmenu">Tips & Tricks/</a></td></tr> +<tr><td><a href="" class="mpmenu"></a></td></tr> +<tr><td><a href="" class="mpmenu"></a></td></tr> +<tr><td><a href="" class="mpmenu"></a></td></tr> +<tr><td><a href="" class="mpmenu"></a></td></tr> +</tbody></table> +</td> +<td width="1px" bgcolor="#583927"></td> +<td style="text-align: right;" valign="top" width="450px"> +<table style="margin: 0px;" border="0" cellpadding="0" cellspacing="0"> +<tbody><tr> +<td><img src="gradients_tutorial_files/agg_logo.gif" border="0"></td> +</tr> +<tr> +<td> +<table style="margin: 0px;" border="0" cellpadding="0" cellspacing="0"> +<tbody><tr height="15px"> +<td> <a class="topmenu" +href="http://www.antigrain.com/news/index.html">News</a> </td> +<td width="1px" bgcolor="#8e521d"></td> +<td> <a class="topmenu" +href="http://www.antigrain.com/doc/index.html">Docs</a> </td> +<td width="1px" bgcolor="#8e521d"></td> +<td> <a class="topmenu" +href="http://www.antigrain.com/download/index.html">Download</a> </td> +<td width="1px" bgcolor="#8e521d"></td> +<td> <a class="topmenu" +href="http://www.antigrain.com/maillist/index.html">Mailing List</a> </td> +<td width="1px" bgcolor="#8e521d"></td> +<td> <a class="topmenu" +href="http://www.antigrain.com/cvs/index.html">CVS</a> </td> +</tr> +</tbody></table> +</td> +</tr> +</tbody></table> +</td> +</tr> +</tbody></table> +<table style="margin: 0px;" height="1px" width="640px" bgcolor="#583927" + border="0" cellpadding="0" cellspacing="0"><tbody><tr><td></td></tr></tbody></table> + + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p> +</p></td></tr></tbody></table> + +<table width="640px"><tbody><tr><td><h1>Working with Gradients<span +class="subtitle"><br>A Simple Step-by-Step Tutorial</span></h1></td></tr></tbody></table> + + + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>This + article will explain to you how to set up gradients and render them. +We will use a simple command-line example that produces the result in +the +<code>agg_test.ppm</code> file. You can use, for example +<a href="http://www.irfanview.com/"><img +src="gradients_tutorial_files/link.gif" border="0">IrfanView +(www.irfanview.com)</a> to see the +results.</p></td></tr></tbody></table> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>You +will need to tell the compiler the <b>AGG</b> include directory and add +three source files to the project or to the command line: +<code>agg_rasterizer_scanline_aa.cpp</code>, +<code><a +href="http://www.antigrain.com/__code/src/agg_trans_affine.cpp.html">agg_trans_affine.cpp</a></code>, + and <code><a +href="http://www.antigrain.com/__code/src/agg_sqrt_tables.cpp.html">agg_sqrt_tables.cpp</a></code>. + You +can find the source file here: <a +href="http://www.antigrain.com/tips/gradients_tutorial/gradients.cpp"><img + src="gradients_tutorial_files/download.gif" border="0"> (gradients.cpp)</a>.</p></td></tr></tbody></table> + +<table width="640px" border="0" cellpadding="0" cellspacing="0"><tbody><tr><td><pre><span class="kw2">#include</span> <span class="op"><</span>stdio<span class="op">.</span>h<span class="op">></span> +<span class="kw2">#include</span> <span class="op"><</span>string<span class="op">.</span>h<span class="op">></span> +<span class="kw2">#include</span> <span class="str">"<a href="http://www.antigrain.com/__code/include/agg_pixfmt_rgb.h.html">agg_pixfmt_rgb.h</a>"</span> +<span class="kw2">#include</span> <span class="str">"<a href="http://www.antigrain.com/__code/include/agg_renderer_base.h.html">agg_renderer_base.h</a>"</span> +<span class="kw2">#include</span> <span class="str">"<a href="http://www.antigrain.com/__code/include/agg_renderer_scanline.h.html">agg_renderer_scanline.h</a>"</span> +<span class="kw2">#include</span> <span class="str">"<a href="http://www.antigrain.com/__code/include/agg_scanline_u.h.html">agg_scanline_u.h</a>"</span> +<span class="kw2">#include</span> <span class="str">"<a href="http://www.antigrain.com/__code/include/agg_rasterizer_scanline_aa.h.html">agg_rasterizer_scanline_aa.h</a>"</span> +<span class="kw2">#include</span> <span class="str">"<a href="http://www.antigrain.com/__code/include/agg_ellipse.h.html">agg_ellipse.h</a>"</span> +<span class="kw2">#include</span> <span class="str">"<a href="http://www.antigrain.com/__code/include/agg_span_gradient.h.html">agg_span_gradient.h</a>"</span> +<span class="kw2">#include</span> <span class="str">"<a href="http://www.antigrain.com/__code/include/agg_span_interpolator_linear.h.html">agg_span_interpolator_linear.h</a>"</span> + +<span class="kw1">enum</span> +<span class="op">{</span> + frame_width <span class="op">=</span> <span class="num">320</span><span class="op">,</span> + frame_height <span class="op">=</span> <span class="num">200</span> +<span class="op">}</span><span class="op">;</span> + +<span class="rem">// Writing the buffer to a .PPM file, assuming it has </span> +<span class="rem">// RGB-structure, one byte per color component</span> +<span class="rem">//--------------------------------------------------</span> +<span class="kw1">bool</span> write_ppm<span class="op">(</span><span class="kw1">const</span> <span class="kw1">unsigned</span> <span class="kw1">char</span><span class="op">*</span> buf<span class="op">,</span> + <span class="kw1">unsigned</span> width<span class="op">,</span> + <span class="kw1">unsigned</span> height<span class="op">,</span> + <span class="kw1">const</span> <span class="kw1">char</span><span class="op">*</span> file_name<span class="op">)</span> +<span class="op">{</span> + FILE<span class="op">*</span> fd <span class="op">=</span> fopen<span class="op">(</span>file_name<span class="op">,</span> <span class="str">"wb"</span><span class="op">)</span><span class="op">;</span> + <span class="kw1">if</span><span class="op">(</span>fd<span class="op">)</span> + <span class="op">{</span> + fprintf<span class="op">(</span>fd<span class="op">,</span> <span class="str">"P6 %d %d 255 "</span><span class="op">,</span> width<span class="op">,</span> height<span class="op">)</span><span class="op">;</span> + fwrite<span class="op">(</span>buf<span class="op">,</span> <span class="num">1</span><span class="op">,</span> width <span class="op">*</span> height <span class="op">*</span> <span class="num">3</span><span class="op">,</span> fd<span class="op">)</span><span class="op">;</span> + fclose<span class="op">(</span>fd<span class="op">)</span><span class="op">;</span> + <span class="kw1">return</span> <span class="kw1">true</span><span class="op">;</span> + <span class="op">}</span> + <span class="kw1">return</span> <span class="kw1">false</span><span class="op">;</span> +<span class="op">}</span> + + + +<span class="rem">// A simple function to form the gradient color array </span> +<span class="rem">// consisting of 3 colors, "begin", "middle", "end"</span> +<span class="rem">//---------------------------------------------------</span> +<span class="kw1">template</span><span class="op"><</span><span class="kw1">class</span> Array<span class="op">></span> +<span class="kw1">void</span> fill_color_array<span class="op">(</span>Array<span class="op">&</span> array<span class="op">,</span> + agg::<a href="http://www.antigrain.com/__code/include/agg_color_rgba.h.html#rgba8">rgba8</a> begin<span class="op">,</span> + agg::<a href="http://www.antigrain.com/__code/include/agg_color_rgba.h.html#rgba8">rgba8</a> middle<span class="op">,</span> + agg::<a href="http://www.antigrain.com/__code/include/agg_color_rgba.h.html#rgba8">rgba8</a> end<span class="op">)</span> +<span class="op">{</span> + <span class="kw1">unsigned</span> i<span class="op">;</span> + <span class="kw1">unsigned</span> half_size <span class="op">=</span> array<span class="op">.</span>size<span class="op">(</span><span class="op">)</span> <span class="op">/</span> <span class="num">2</span><span class="op">;</span> + <span class="kw1">for</span><span class="op">(</span>i <span class="op">=</span> <span class="num">0</span><span class="op">;</span> i <span class="op"><</span> half_size<span class="op">;</span> <span class="op">++</span>i<span class="op">)</span> + <span class="op">{</span> + array<span class="op">[</span>i<span class="op">]</span> <span class="op">=</span> begin<span class="op">.</span>gradient<span class="op">(</span>middle<span class="op">,</span> i <span class="op">/</span> <span class="kw1">double</span><span class="op">(</span>half_size<span class="op">)</span><span class="op">)</span><span class="op">;</span> + <span class="op">}</span> + <span class="kw1">for</span><span class="op">(</span><span class="op">;</span> i <span class="op"><</span> array<span class="op">.</span>size<span class="op">(</span><span class="op">)</span><span class="op">;</span> <span class="op">++</span>i<span class="op">)</span> + <span class="op">{</span> + array<span class="op">[</span>i<span class="op">]</span> <span class="op">=</span> middle<span class="op">.</span>gradient<span class="op">(</span>end<span class="op">,</span> <span class="op">(</span>i <span class="op">-</span> half_size<span class="op">)</span> <span class="op">/</span> <span class="kw1">double</span><span class="op">(</span>half_size<span class="op">)</span><span class="op">)</span><span class="op">;</span> + <span class="op">}</span> +<span class="op">}</span> + + + + +<span class="kw1">int</span> <span class="kw1">main</span><span class="op">(</span><span class="op">)</span> +<span class="op">{</span> + <span class="kw1">unsigned</span> <span class="kw1">char</span><span class="op">*</span> buffer <span class="op">=</span> <span class="kw1">new</span> <span class="kw1">unsigned</span> <span class="kw1">char</span><span class="op">[</span>frame_width <span class="op">*</span> frame_height <span class="op">*</span> <span class="num">3</span><span class="op">]</span><span class="op">;</span> + + agg::<a href="http://www.antigrain.com/doc/basic_renderers/basic_renderers.agdoc.html#rendering_buffer">rendering_buffer</a> rbuf<span class="op">(</span>buffer<span class="op">,</span> + frame_width<span class="op">,</span> + frame_height<span class="op">,</span> + <span class="op">-</span>frame_width <span class="op">*</span> <span class="num">3</span><span class="op">)</span><span class="op">;</span> + + <span class="rem">// Pixel format and basic renderers.</span> + <span class="rem">//-----------------</span> + <span class="kw1">typedef</span> agg::<a href="http://www.antigrain.com/__code/include/agg_pixfmt_rgb.h.html#pixfmt_rgb24">pixfmt_rgb24</a> pixfmt_type<span class="op">;</span> + <span class="kw1">typedef</span> agg::<a href="http://www.antigrain.com/doc/basic_renderers/basic_renderers.agdoc.html#renderer_base">renderer_base</a><span class="op"><</span>pixfmt_type<span class="op">></span> renderer_base_type<span class="op">;</span> + + + <span class="rem">// The gradient color array</span> + <span class="kw1">typedef</span> agg::<a href="http://www.antigrain.com/__code/include/agg_array.h.html#pod_auto_array">pod_auto_array</a><span class="op"><</span>agg::<a href="http://www.antigrain.com/__code/include/agg_color_rgba.h.html#rgba8">rgba8</a><span class="op">,</span> <span class="num">256</span><span class="op">></span> color_array_type<span class="op">;</span> + + + <span class="rem">// Gradient shape function (linear, radial, custom, etc)</span> + <span class="rem">//-----------------</span> + <span class="kw1">typedef</span> agg::<a href="http://www.antigrain.com/__code/include/agg_span_gradient.h.html#gradient_x">gradient_x</a> gradient_func_type<span class="op">;</span> + + + <span class="rem">// Span interpolator. This object is used in all span generators </span> + <span class="rem">// that operate with transformations during iterating of the spans,</span> + <span class="rem">// for example, image transformers use the interpolator too.</span> + <span class="rem">//-----------------</span> + <span class="kw1">typedef</span> agg::<a href="http://www.antigrain.com/__code/include/agg_span_interpolator_linear.h.html#span_interpolator_linear">span_interpolator_linear</a><span class="op"><</span><span class="op">></span> interpolator_type<span class="op">;</span> + + + <span class="rem">// Span allocator is an object that allocates memory for </span> + <span class="rem">// the array of colors that will be used to render the </span> + <span class="rem">// color spans. One object can be shared between different </span> + <span class="rem">// span generators.</span> + <span class="rem">//-----------------</span> + <span class="kw1">typedef</span> agg::<a href="http://www.antigrain.com/__code/include/agg_span_allocator.h.html#span_allocator">span_allocator</a><span class="op"><</span>agg::<a href="http://www.antigrain.com/__code/include/agg_color_rgba.h.html#rgba8">rgba8</a><span class="op">></span> span_allocator_type<span class="op">;</span> + + + <span class="rem">// Finally, the gradient span generator working with the agg::<a href="http://www.antigrain.com/__code/include/agg_color_rgba.h.html#rgba8">rgba8</a> </span> + <span class="rem">// color type. </span> + <span class="rem">// The 4-th argument is the color function that should have </span> + <span class="rem">// the [] operator returning the color in range of [0...255].</span> + <span class="rem">// In our case it will be a simple look-up table of 256 colors.</span> + <span class="rem">//-----------------</span> + <span class="kw1">typedef</span> agg::<a href="http://www.antigrain.com/__code/include/agg_span_gradient.h.html#span_gradient">span_gradient</a><span class="op"><</span>agg::<a href="http://www.antigrain.com/__code/include/agg_color_rgba.h.html#rgba8">rgba8</a><span class="op">,</span> + interpolator_type<span class="op">,</span> + gradient_func_type<span class="op">,</span> + color_array_type<span class="op">,</span> + span_allocator_type<span class="op">></span> span_gradient_type<span class="op">;</span> + + + <span class="rem">// The gradient scanline renderer type</span> + <span class="rem">//-----------------</span> + <span class="kw1">typedef</span> agg::<a href="http://www.antigrain.com/__code/include/agg_renderer_scanline.h.html#renderer_scanline_aa">renderer_scanline_aa</a><span class="op"><</span>renderer_base_type<span class="op">,</span> + span_gradient_type<span class="op">></span> renderer_gradient_type<span class="op">;</span> + + + <span class="rem">// Common declarations (pixel format and basic renderer).</span> + <span class="rem">//----------------</span> + pixfmt_type pixf<span class="op">(</span>rbuf<span class="op">)</span><span class="op">;</span> + renderer_base_type rbase<span class="op">(</span>pixf<span class="op">)</span><span class="op">;</span> + + + <span class="rem">// The gradient objects declarations</span> + <span class="rem">//----------------</span> + gradient_func_type gradient_func<span class="op">;</span> <span class="rem">// The gradient function</span> + agg::<a href="http://www.antigrain.com/__code/include/agg_trans_affine.h.html#trans_affine">trans_affine</a> gradient_mtx<span class="op">;</span> <span class="rem">// Affine transformer</span> + interpolator_type span_interpolator<span class="op">(</span>gradient_mtx<span class="op">)</span><span class="op">;</span> <span class="rem">// Span interpolator</span> + span_allocator_type <a href="http://www.antigrain.com/__code/include/agg_span_allocator.h.html#span_allocator">span_allocator</a><span class="op">;</span> <span class="rem">// Span Allocator</span> + color_array_type color_array<span class="op">;</span> <span class="rem">// Gradient colors</span> + + + <span class="rem">// Declare the gradient span itself. </span> + <span class="rem">// The last two arguments are so called "d1" and "d2" </span> + <span class="rem">// defining two distances in pixels, where the gradient starts</span> + <span class="rem">// and where it ends. The actual meaning of "d1" and "d2" depands</span> + <span class="rem">// on the gradient function.</span> + <span class="rem">//----------------</span> + span_gradient_type <a href="http://www.antigrain.com/__code/include/agg_span_gradient.h.html#span_gradient">span_gradient</a><span class="op">(</span><a href="http://www.antigrain.com/__code/include/agg_span_allocator.h.html#span_allocator">span_allocator</a><span class="op">,</span> + span_interpolator<span class="op">,</span> + gradient_func<span class="op">,</span> + color_array<span class="op">,</span> + <span class="num">0</span><span class="op">,</span> <span class="num">100</span><span class="op">)</span><span class="op">;</span> + + <span class="rem">// The gradient renderer</span> + <span class="rem">//----------------</span> + renderer_gradient_type ren_gradient<span class="op">(</span>rbase<span class="op">,</span> <a href="http://www.antigrain.com/__code/include/agg_span_gradient.h.html#span_gradient">span_gradient</a><span class="op">)</span><span class="op">;</span> + + + <span class="rem">// The rasterizing/scanline stuff</span> + <span class="rem">//----------------</span> + agg::<a href="http://www.antigrain.com/__code/include/agg_rasterizer_scanline_aa.h.html#rasterizer_scanline_aa">rasterizer_scanline_aa</a><span class="op"><</span><span class="op">></span> ras<span class="op">;</span> + agg::<a href="http://www.antigrain.com/__code/include/agg_scanline_u.h.html#scanline_u8">scanline_u8</a> sl<span class="op">;</span> + + + <span class="rem">// Finally we can draw a circle.</span> + <span class="rem">//----------------</span> + rbase<span class="op">.</span>clear<span class="op">(</span>agg::<a href="http://www.antigrain.com/__code/include/agg_color_rgba.h.html#rgba8">rgba8</a><span class="op">(</span><span class="num">255</span><span class="op">,</span> <span class="num">255</span><span class="op">,</span> <span class="num">255</span><span class="op">)</span><span class="op">)</span><span class="op">;</span> + + fill_color_array<span class="op">(</span>color_array<span class="op">,</span> + agg::<a href="http://www.antigrain.com/__code/include/agg_color_rgba.h.html#rgba8">rgba8</a><span class="op">(</span><span class="num">0</span><span class="op">,</span><span class="num">50</span><span class="op">,</span><span class="num">50</span><span class="op">)</span><span class="op">,</span> + agg::<a href="http://www.antigrain.com/__code/include/agg_color_rgba.h.html#rgba8">rgba8</a><span class="op">(</span><span class="num">240</span><span class="op">,</span> <span class="num">255</span><span class="op">,</span> <span class="num">100</span><span class="op">)</span><span class="op">,</span> + agg::<a href="http://www.antigrain.com/__code/include/agg_color_rgba.h.html#rgba8">rgba8</a><span class="op">(</span><span class="num">80</span><span class="op">,</span> <span class="num">0</span><span class="op">,</span> <span class="num">0</span><span class="op">)</span><span class="op">)</span><span class="op">;</span> + + agg::<a href="http://www.antigrain.com/__code/include/agg_ellipse.h.html#ellipse">ellipse</a> ell<span class="op">(</span><span class="num">50</span><span class="op">,</span> <span class="num">50</span><span class="op">,</span> <span class="num">50</span><span class="op">,</span> <span class="num">50</span><span class="op">,</span> <span class="num">100</span><span class="op">)</span><span class="op">;</span> + ras<span class="op">.</span>add_path<span class="op">(</span>ell<span class="op">)</span><span class="op">;</span> + + agg::<a href="http://www.antigrain.com/__code/include/agg_renderer_scanline.h.html#render_scanlines">render_scanlines</a><span class="op">(</span>ras<span class="op">,</span> sl<span class="op">,</span> ren_gradient<span class="op">)</span><span class="op">;</span> + + write_ppm<span class="op">(</span>buffer<span class="op">,</span> frame_width<span class="op">,</span> frame_height<span class="op">,</span> <span class="str">"agg_test.ppm"</span><span class="op">)</span><span class="op">;</span> + + <span class="kw1">delete</span> <span class="op">[</span><span class="op">]</span> buffer<span class="op">;</span> + <span class="kw1">return</span> <span class="num">0</span><span class="op">;</span> +<span class="op">}</span> +</pre></td></tr></tbody></table><font style="margin-left: 1em;"><i></i></font> + + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>It +looks rather complex, especially the necessity to declare a lot +of types and objects. But the “complexity” gives you freedom, for +example, you can define your own gradient functions or even arbitrary +distortions.</p></td></tr></tbody></table> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>The +example renders a circle with linear gradient from (0,0) to (100,0). +In <b>AGG</b> you can define an arbitrary color function, in our case +it's a +simple look-up table generated from three colors, <code>start</code>, <code>middle</code>, + and +<code>end</code>.</p></td></tr></tbody></table> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>Here + is the result (the axes and text were added in <a +href="http://www.xara.com/"><img src="gradients_tutorial_files/link.gif" + border="0"><b><nobr>Xara X</nobr></b></a>):</p></td></tr></tbody></table> + +<table width="640px"><tbody><tr><td><center><img +src="gradients_tutorial_files/gradients1.png" title="" border="0"><br><i></i></center></td></tr></tbody></table> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>It +also can seem like an overkill for this simple task, but later +you will see that it's not so. +<br><br><br></p></td></tr></tbody></table> + +<table style="margin: 0px;" height="1px" width="640px" bgcolor="#583927" + border="0" cellpadding="0" cellspacing="0"><tbody><tr><td></td></tr></tbody></table> +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>The +next step is one little modification. Modify the following:</p></td></tr></tbody></table> + +<table width="640px" border="0" cellpadding="0" cellspacing="0"><tbody><tr><td><pre> <span class="rem">// Declare the gradient span itself. </span> + <span class="rem">// The last two arguments are so called "d1" and "d2" </span> + <span class="rem">// defining two distances in pixels, where the gradient starts</span> + <span class="rem">// and where it ends. The actual meaning of "d1" and "d2" depands</span> + <span class="rem">// on the gradient function.</span> + <span class="rem">//----------------</span> + span_gradient_type <a href="http://www.antigrain.com/__code/include/agg_span_gradient.h.html#span_gradient">span_gradient</a><span class="op">(</span><a href="http://www.antigrain.com/__code/include/agg_span_allocator.h.html#span_allocator">span_allocator</a><span class="op">,</span> + span_interpolator<span class="op">,</span> + gradient_func<span class="op">,</span> + color_array<span class="op">,</span> + <span class="num">50</span><span class="op">,</span> <span class="num">100</span><span class="op">)</span><span class="op">;</span> +</pre></td></tr></tbody></table><font style="margin-left: 1em;"><i></i></font> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>The +result:</p></td></tr></tbody></table> + +<table width="640px"><tbody><tr><td><center><img +src="gradients_tutorial_files/gradients2.png" title="" border="0"><br><i></i></center></td></tr></tbody></table> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>It +should explain those freaky <code>d1</code> and <code>d2</code> +arguments. In fact, they +determine the geometrical <code>start</code> and <code>end</code> of the + gradient and their meaning +depends on the gradient function. +<br><br><br> +</p></td></tr></tbody></table><table style="margin: 0px;" height="1px" +width="640px" bgcolor="#583927" border="0" cellpadding="0" +cellspacing="0"><tbody><tr><td></td></tr></tbody></table> +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>Now +change the gradient function:</p></td></tr></tbody></table> + +<table width="640px" border="0" cellpadding="0" cellspacing="0"><tbody><tr><td><pre> <span class="rem">// Gradient shape function (linear, radial, custom, etc)</span> + <span class="rem">//-----------------</span> + <span class="kw1">typedef</span> agg::<a href="http://www.antigrain.com/__code/include/agg_span_gradient.h.html#gradient_circle">gradient_circle</a> gradient_func_type<span class="op">;</span> +</pre></td></tr></tbody></table><font style="margin-left: 1em;"><i></i></font> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>Set <code>d1</code> + back to 0:</p></td></tr></tbody></table> + +<table width="640px" border="0" cellpadding="0" cellspacing="0"><tbody><tr><td><pre> <span class="rem">// Declare the gradient span itself. </span> + <span class="rem">// The last two arguments are so called "d1" and "d2" </span> + <span class="rem">// defining two distances in pixels, where the gradient starts</span> + <span class="rem">// and where it ends. The actual meaning of "d1" and "d2" depands</span> + <span class="rem">// on the gradient function.</span> + <span class="rem">//----------------</span> + span_gradient_type <a href="http://www.antigrain.com/__code/include/agg_span_gradient.h.html#span_gradient">span_gradient</a><span class="op">(</span><a href="http://www.antigrain.com/__code/include/agg_span_allocator.h.html#span_allocator">span_allocator</a><span class="op">,</span> + span_interpolator<span class="op">,</span> + gradient_func<span class="op">,</span> + color_array<span class="op">,</span> + <span class="num">0</span><span class="op">,</span> <span class="num">100</span><span class="op">)</span><span class="op">;</span> +</pre></td></tr></tbody></table><font style="margin-left: 1em;"><i></i></font> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>And +modify the circle:</p></td></tr></tbody></table> + +<table width="640px" border="0" cellpadding="0" cellspacing="0"><tbody><tr><td><pre> agg::<a href="http://www.antigrain.com/__code/include/agg_ellipse.h.html#ellipse">ellipse</a> ell<span class="op">(</span><span class="num">0</span><span class="op">,</span> <span class="num">0</span><span class="op">,</span> <span class="num">120</span><span class="op">,</span> <span class="num">120</span><span class="op">,</span> <span class="num">100</span><span class="op">)</span><span class="op">;</span> +</pre></td></tr></tbody></table><font style="margin-left: 1em;"><i></i></font> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>The +result:</p></td></tr></tbody></table> + +<table width="640px"><tbody><tr><td><center><img +src="gradients_tutorial_files/gradients3.png" title="" border="0"><br><i></i></center></td></tr></tbody></table> +<table width="640px"><tbody><tr><td style="text-align: justify;"><p><br><br><br> +</p></td></tr></tbody></table><table style="margin: 0px;" height="1px" +width="640px" bgcolor="#583927" border="0" cellpadding="0" +cellspacing="0"><tbody><tr><td></td></tr></tbody></table> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>Modify + <code>d1</code> again: +</p></td></tr></tbody></table><table width="640px" border="0" +cellpadding="0" cellspacing="0"><tbody><tr><td><pre> <span class="rem">// Declare the gradient span itself. </span> + <span class="rem">// The last two arguments are so called "d1" and "d2" </span> + <span class="rem">// defining two distances in pixels, where the gradient starts</span> + <span class="rem">// and where it ends. The actual meaning of "d1" and "d2" depands</span> + <span class="rem">// on the gradient function.</span> + <span class="rem">//----------------</span> + span_gradient_type <a href="http://www.antigrain.com/__code/include/agg_span_gradient.h.html#span_gradient">span_gradient</a><span class="op">(</span><a href="http://www.antigrain.com/__code/include/agg_span_allocator.h.html#span_allocator">span_allocator</a><span class="op">,</span> + span_interpolator<span class="op">,</span> + gradient_func<span class="op">,</span> + color_array<span class="op">,</span> + <span class="num">50</span><span class="op">,</span> <span class="num">100</span><span class="op">)</span><span class="op">;</span> +</pre></td></tr></tbody></table><font style="margin-left: 1em;"><i></i></font> + +<table width="640px"><tbody><tr><td><center><img +src="gradients_tutorial_files/gradients4.png" title="" border="0"><br><i></i></center></td></tr></tbody></table> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>So +that, in case of a radial gradient, <code>d1</code> and <code>d2</code> +define the starting +and ending radii. +<br><br><br> +</p></td></tr></tbody></table><table style="margin: 0px;" height="1px" +width="640px" bgcolor="#583927" border="0" cellpadding="0" +cellspacing="0"><tbody><tr><td></td></tr></tbody></table> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>By +default the origin point for the gradients is (0,0). How to draw a +gradient +in some other place? The answer is to use affine transformations. +Strictly +speaking, the transformations are fully defined by the span +interpolator. In our case +we use <a +href="http://www.antigrain.com/__code/include/agg_span_interpolator_linear.h.html#span_interpolator_linear">span_interpolator_linear</a> + with an affine matrix. The linear interpolator +allows you to speed up the calculations vastly, because we calculate the + floating +point coordinates only in the begin and end of the horizontal spans and +then +use a fast, integer, Bresenham-like interpolation with <b>Subpixel +Accuracy</b>.</p></td></tr></tbody></table> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>Add +the following code somewhere before calling <code>agg::<a +href="http://www.antigrain.com/__code/include/agg_renderer_scanline.h.html#render_scanlines">render_scanlines</a>(ras, + sl, ren_gradient);</code></p></td></tr></tbody></table> + +<table width="640px" border="0" cellpadding="0" cellspacing="0"><tbody><tr><td><pre> gradient_mtx <span class="op">*=</span> agg::<a href="http://www.antigrain.com/__code/include/agg_trans_affine.h.html#trans_affine_scaling">trans_affine_scaling</a><span class="op">(</span><span class="num">0</span><span class="op">.</span><span class="num">75</span><span class="op">,</span> <span class="num">1</span><span class="op">.</span><span class="num">2</span><span class="op">)</span><span class="op">;</span> + gradient_mtx <span class="op">*=</span> agg::<a href="http://www.antigrain.com/__code/include/agg_trans_affine.h.html#trans_affine_rotation">trans_affine_rotation</a><span class="op">(</span><span class="op">-</span>agg::<a href="http://www.antigrain.com/__code/include/agg_basics.h.html#pi">pi</a><span class="op">/</span><span class="num">3</span><span class="op">.</span><span class="num">0</span><span class="op">)</span><span class="op">;</span> + gradient_mtx <span class="op">*=</span> agg::<a href="http://www.antigrain.com/__code/include/agg_trans_affine.h.html#trans_affine_translation">trans_affine_translation</a><span class="op">(</span><span class="num">100</span><span class="op">.</span><span class="num">0</span><span class="op">,</span> <span class="num">100</span><span class="op">.</span><span class="num">0</span><span class="op">)</span><span class="op">;</span> + gradient_mtx<span class="op">.</span>invert<span class="op">(</span><span class="op">)</span><span class="op">;</span> +</pre></td></tr></tbody></table><font style="margin-left: 1em;"><i></i></font> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>And +modify the circle:</p></td></tr></tbody></table> + +<table width="640px" border="0" cellpadding="0" cellspacing="0"><tbody><tr><td><pre> agg::<a href="http://www.antigrain.com/__code/include/agg_ellipse.h.html#ellipse">ellipse</a> ell<span class="op">(</span><span class="num">100</span><span class="op">,</span> <span class="num">100</span><span class="op">,</span> <span class="num">120</span><span class="op">,</span> <span class="num">120</span><span class="op">,</span> <span class="num">100</span><span class="op">)</span><span class="op">;</span> +</pre></td></tr></tbody></table><font style="margin-left: 1em;"><i></i></font> + +<table width="640px"><tbody><tr><td><center><img +src="gradients_tutorial_files/gradients5.png" title="" border="0"><br><i></i></center></td></tr></tbody></table> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>The +code of initializing of the affine matrix should be obvious except +for some strange <code>gradient_mtx.invert()</code>. It's necessary +because +the gradient generator uses <b>reverse</b> transformations instead of +<b>direct</b> ones. In other words it takes the destination point, +applies the transformations and obtains the coordinates in the gradient. +Note that the affine transformations allow you to turn a circular +gradient +into elliptical. +<br><br><br> +</p></td></tr></tbody></table><table style="margin: 0px;" height="1px" +width="640px" bgcolor="#583927" border="0" cellpadding="0" +cellspacing="0"><tbody><tr><td></td></tr></tbody></table> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>Now +it should be obvious how to define a linear gradient from some +<code>Point1</code> to <code>Point2</code>. So, get back to the original + code and +add the following function:</p></td></tr></tbody></table> + +<table width="640px" border="0" cellpadding="0" cellspacing="0"><tbody><tr><td><pre><span class="rem">// Calculate the affine transformation matrix for the linear gradient </span> +<span class="rem">// from (x1, y1) to (x2, y2). gradient_d2 is the "base" to scale the</span> +<span class="rem">// gradient. Here d1 must be 0.0, and d2 must equal gradient_d2.</span> +<span class="rem">//---------------------------------------------------------------</span> +<span class="kw1">void</span> calc_linear_gradient_transform<span class="op">(</span><span class="kw1">double</span> x1<span class="op">,</span> <span class="kw1">double</span> y1<span class="op">,</span> <span class="kw1">double</span> x2<span class="op">,</span> <span class="kw1">double</span> y2<span class="op">,</span> + agg::<a href="http://www.antigrain.com/__code/include/agg_trans_affine.h.html#trans_affine">trans_affine</a><span class="op">&</span> mtx<span class="op">,</span> + <span class="kw1">double</span> gradient_d2 <span class="op">=</span> <span class="num">100</span><span class="op">.</span><span class="num">0</span><span class="op">)</span> +<span class="op">{</span> + <span class="kw1">double</span> dx <span class="op">=</span> x2 <span class="op">-</span> x1<span class="op">;</span> + <span class="kw1">double</span> dy <span class="op">=</span> y2 <span class="op">-</span> y1<span class="op">;</span> + mtx<span class="op">.</span>reset<span class="op">(</span><span class="op">)</span><span class="op">;</span> + mtx <span class="op">*=</span> agg::<a href="http://www.antigrain.com/__code/include/agg_trans_affine.h.html#trans_affine_scaling">trans_affine_scaling</a><span class="op">(</span>sqrt<span class="op">(</span>dx <span class="op">*</span> dx <span class="op">+</span> dy <span class="op">*</span> dy<span class="op">)</span> <span class="op">/</span> gradient_d2<span class="op">)</span><span class="op">;</span> + mtx <span class="op">*=</span> agg::<a href="http://www.antigrain.com/__code/include/agg_trans_affine.h.html#trans_affine_rotation">trans_affine_rotation</a><span class="op">(</span>atan2<span class="op">(</span>dy<span class="op">,</span> dx<span class="op">)</span><span class="op">)</span><span class="op">;</span> + mtx <span class="op">*=</span> agg::<a href="http://www.antigrain.com/__code/include/agg_trans_affine.h.html#trans_affine_translation">trans_affine_translation</a><span class="op">(</span>x1<span class="op">,</span> y1<span class="op">)</span><span class="op">;</span> + mtx<span class="op">.</span>invert<span class="op">(</span><span class="op">)</span><span class="op">;</span> +<span class="op">}</span> +</pre></td></tr></tbody></table><font style="margin-left: 1em;"><i></i></font> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>Then + modify the circle:</p></td></tr></tbody></table> + +<table width="640px" border="0" cellpadding="0" cellspacing="0"><tbody><tr><td><pre> agg::<a href="http://www.antigrain.com/__code/include/agg_ellipse.h.html#ellipse">ellipse</a> ell<span class="op">(</span><span class="num">100</span><span class="op">,</span> <span class="num">100</span><span class="op">,</span> <span class="num">80</span><span class="op">,</span> <span class="num">80</span><span class="op">,</span> <span class="num">100</span><span class="op">)</span><span class="op">;</span> +</pre></td></tr></tbody></table><font style="margin-left: 1em;"><i></i></font> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>And +add the transformations:</p></td></tr></tbody></table> + +<table width="640px" border="0" cellpadding="0" cellspacing="0"><tbody><tr><td><pre> calc_linear_gradient_transform<span class="op">(</span><span class="num">50</span><span class="op">,</span> <span class="num">50</span><span class="op">,</span> <span class="num">150</span><span class="op">,</span> <span class="num">150</span><span class="op">,</span> gradient_mtx<span class="op">)</span><span class="op">;</span> +</pre></td></tr></tbody></table><font style="margin-left: 1em;"><i></i></font> + +<table width="640px"><tbody><tr><td><center><img +src="gradients_tutorial_files/gradients6.png" title="" border="0"><br><i></i></center></td></tr></tbody></table> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>Try +to play with different parameters, +transformations, and gradient functions: <a +href="http://www.antigrain.com/__code/include/agg_span_gradient.h.html#gradient_circle">gradient_circle</a>, + <a +href="http://www.antigrain.com/__code/include/agg_span_gradient.h.html#gradient_x">gradient_x</a>, + +<a +href="http://www.antigrain.com/__code/include/agg_span_gradient.h.html#gradient_y">gradient_y</a>, + <a +href="http://www.antigrain.com/__code/include/agg_span_gradient.h.html#gradient_diamond">gradient_diamond</a>, + <a +href="http://www.antigrain.com/__code/include/agg_span_gradient.h.html#gradient_xy">gradient_xy</a>, + <a +href="http://www.antigrain.com/__code/include/agg_span_gradient.h.html#gradient_sqrt_xy">gradient_sqrt_xy</a>, + <a +href="http://www.antigrain.com/__code/include/agg_span_gradient.h.html#gradient_conic">gradient_conic</a>. +Also look at the gradient functions and try to write your own. Actually, + +the set of the gradient functions in <b>AGG</b> is rather poor, it just +demonstrates +the possibilities. For example, repeating or reflecting gradients should +be implemented in gradient functions (or you can write adaptors that +will +use the existing functions). +</p></td></tr></tbody></table><table style="margin: 0px;" height="1px" +width="640px" bgcolor="#583927" border="0" cellpadding="0" +cellspacing="0"><tbody><tr><td></td></tr></tbody></table> +<table width="640px" border="0" cellpadding="0" cellspacing="0"> +<tbody><tr><td><center><span class="authors"> +Copyright <span class="larger">©</span> 2002-2006 +<a href="http://www.antigrain.com/mcseem/index.html"><b>Maxim Shemanarev</b></a> +</span></center></td></tr> +<tr><td><center><span class="authors"> +Web Design and Programming +<a href="http://www.antigrain.com/mcseem/index.html"><b>Maxim Shemanarev</b></a> +</span></center></td></tr> +</tbody></table> +<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br> +<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br> +<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br> +<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br> +</body></html>
\ No newline at end of file diff --git a/docs/aggpas/gradients_tutorial_files/agg.css b/docs/aggpas/gradients_tutorial_files/agg.css new file mode 100644 index 00000000..997d9d07 --- /dev/null +++ b/docs/aggpas/gradients_tutorial_files/agg.css @@ -0,0 +1,239 @@ +BODY +{ + font-family:Verdana, Arial, Tahoma; + font-size:12px; + color:#160801; + background-color:#ffffff; + text-align:justify; + padding:5px; +} + +P, UL, OL, DL +{ + font-family:Verdana, Arial, Tahoma; + font-size:12px; + color:#160801; + margin-bottom:0px; + margin-top:0px; +} + + +.larger +{ + font-size:14px; +} + +LI +{ + padding:3px; +} + +HR +{ + color:#583927; + height:1px; +} + +H1 +{ + font-family:Verdana, Arial, Tahoma; + font-size:28px; + font-weight:bolder; + text-align:center; + color:#583927; + margin:0px; +} + +H1 SPAN.subtitle +{ + font-family:Verdana, Arial, Tahoma; + font-size:18px; + font-weight:lighter; +} + + +H2 +{ + font-family:Verdana, Arial, Tahoma; + font-size:26px; + font-weight:normal; + text-align:left; + color:#583927; +} + +H3 +{ + font-family:Verdana, Arial, Tahoma; + font-size:20px; + font-weight:normal; + text-align:left; + color:#583927; +} + +H4 +{ + font-family:Verdana, Arial, Tahoma; + font-size:16px; + font-weight:bold; + text-align:left; + color:#583927; +} + +H5 +{ + font-family:Verdana, Arial, Tahoma; + font-size:14px; + font-weight:bold; + text-align:left; + color:#583927; +} + +TABLE +{ + margin:5px; +} + +TD +{ + font-family:Verdana, Arial, Tahoma; + font-size:12px; +} + +TH +{ + font-family:Verdana, Arial, Tahoma; + background-color:#d4d4d4; + font-size:12px; +} + + +PRE +{ + padding: 5px; + border: gray 1px solid; + background-color:#f4f4f4; + color:#130f00; + font-family:"courier new", courier,mono; + font-size:12px; + margin:0px; +} + +TT, CODE +{ + font-family:"courier new", courier,mono; + font-size:14px; + color:#000070; +} + +.warning, .warning TD +{ + background-color:#fcf6f6; + color:#793131; + padding:0.5em; + font-family:Verdana, Arial, Tahoma; + font-size:12px; + text-align:justify; +} + +.note, .note TD +{ + background-color:#f0fafa; + color:#506580; + padding:0.5em; + font-family:Verdana, Arial, Tahoma; + font-size:12px; + text-align:justify; +} + +.quote, .quote TD +{ + background-color:#f0fafa; + color:#000540; + padding:0.5em; + font-family:Verdana, Arial, Tahoma; + font-size:12px; + text-align:justify; +} + +.tip, .tip TD +{ + background-color:#fbfff6; + color:#68771e; + padding:0.5em; + font-family:Verdana, Arial, Tahoma; + font-size:12px; + text-align:justify; +} + +.tbl TD +{ + background-color:#f4f4f4; + font-family:Verdana, Arial, Tahoma; + font-size:12px; + text-align:left; + padding:3px; +} + +.toc TD +{ + font-family:Verdana, Arial, Tahoma; + text-align:left; + padding:3px; +} + +.title {font-family:Verdana, Arial, Tahoma;} + +.warning P, +.warning PRE, +.note P, +.note PRE, +.tip P, +.tip PRE {margin:0.3em 0em 0.1em 0em;} + +.warning .code {background-color:#fcf6f6;} +.note .code {background-color:#f0fafa;} +.tip .code {background-color:#fbfff6;} + +A {text-decoration:none; color:#700000;} +A:visited {text-decoration:none; color:#85585d;} +A:link {text-decoration:none;} +A:hover {text-decoration:underline;} + +.topmenu,a.topmenu:visited,a.topmenu:hover,a.topmenu:active,a.topmenu:link +{ + font-family: Arial, Tahoma, Helvetica, sans-serif; + font-size: 11px; + font-weight: bold; + text-decoration: none; + color: #582218; +} + +.mpmenu,a.mpmenu:visited,a.mpmenu:hover,a.mpmenu:active,a.mpmenu:link +{ + font-family: Arial, Tahoma, Helvetica, sans-serif; + font-size: 12px; + font-weight: bold; + text-decoration: none; + color: #582218; +} + +.tah +{ + font-family: Tahoma, Arial, Helvetica, sans-serif; + font-size: 12px; + color: #582218; +} + +.authors +{ + font-size:10px; +} + +span.rem {color:#4c8d00;} +span.kw1 {color:#000d8e;} +span.kw2 {color:#0075ca;} +span.kw3 {color:#004645;} +span.kw4 {color:#673517;} +span.op {color:#4a006d;} +span.str {color:#ab2500;} +span.num {color:#a74c3f;} diff --git a/docs/aggpas/gradients_tutorial_files/agg_logo.gif b/docs/aggpas/gradients_tutorial_files/agg_logo.gif Binary files differnew file mode 100644 index 00000000..ee5c570a --- /dev/null +++ b/docs/aggpas/gradients_tutorial_files/agg_logo.gif diff --git a/docs/aggpas/gradients_tutorial_files/download.gif b/docs/aggpas/gradients_tutorial_files/download.gif Binary files differnew file mode 100644 index 00000000..fd9367e4 --- /dev/null +++ b/docs/aggpas/gradients_tutorial_files/download.gif diff --git a/docs/aggpas/gradients_tutorial_files/gradients1.png b/docs/aggpas/gradients_tutorial_files/gradients1.png Binary files differnew file mode 100644 index 00000000..5812f347 --- /dev/null +++ b/docs/aggpas/gradients_tutorial_files/gradients1.png diff --git a/docs/aggpas/gradients_tutorial_files/gradients2.png b/docs/aggpas/gradients_tutorial_files/gradients2.png Binary files differnew file mode 100644 index 00000000..da5ff091 --- /dev/null +++ b/docs/aggpas/gradients_tutorial_files/gradients2.png diff --git a/docs/aggpas/gradients_tutorial_files/gradients3.png b/docs/aggpas/gradients_tutorial_files/gradients3.png Binary files differnew file mode 100644 index 00000000..d4cb9ae1 --- /dev/null +++ b/docs/aggpas/gradients_tutorial_files/gradients3.png diff --git a/docs/aggpas/gradients_tutorial_files/gradients4.png b/docs/aggpas/gradients_tutorial_files/gradients4.png Binary files differnew file mode 100644 index 00000000..fe3e4a19 --- /dev/null +++ b/docs/aggpas/gradients_tutorial_files/gradients4.png diff --git a/docs/aggpas/gradients_tutorial_files/gradients5.png b/docs/aggpas/gradients_tutorial_files/gradients5.png Binary files differnew file mode 100644 index 00000000..e6766bba --- /dev/null +++ b/docs/aggpas/gradients_tutorial_files/gradients5.png diff --git a/docs/aggpas/gradients_tutorial_files/gradients6.png b/docs/aggpas/gradients_tutorial_files/gradients6.png Binary files differnew file mode 100644 index 00000000..a87f1f5c --- /dev/null +++ b/docs/aggpas/gradients_tutorial_files/gradients6.png diff --git a/docs/aggpas/gradients_tutorial_files/link.gif b/docs/aggpas/gradients_tutorial_files/link.gif Binary files differnew file mode 100644 index 00000000..76a532cf --- /dev/null +++ b/docs/aggpas/gradients_tutorial_files/link.gif diff --git a/docs/aggpas/introduction.agdoc.html b/docs/aggpas/introduction.agdoc.html new file mode 100644 index 00000000..c26ea581 --- /dev/null +++ b/docs/aggpas/introduction.agdoc.html @@ -0,0 +1,690 @@ +<html><head><title>Anti-Grain Geometry - Introduction</title> +<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> +<link rel="stylesheet" type="text/css" +href="introduction.agdoc_files/agg.css"> +</head><body><a name="PAGE_INTRODUCTION"><b></b></a> + + +<table style="margin: 0px;" height="1px" width="640px" border="0" +cellpadding="0" cellspacing="0"> +<tbody><tr> +<td bgcolor="#583927"></td> +</tr> +</tbody></table> +<table style="margin: 0px;" width="640px" border="0" cellpadding="0" +cellspacing="0"> +<tbody><tr> +<td> +<table style="margin: 0px;" width="170px" border="0" cellpadding="0" +cellspacing="0"> +<tbody><tr><td><a href="http://www.antigrain.com/index.html" +class="mpmenu">Home/</a></td></tr> +<tr><td><a href="http://www.antigrain.com/doc/index.html" class="mpmenu">Table + of Content/</a></td></tr> +<tr><td><a href="" class="mpmenu"></a></td></tr> +<tr><td><a href="" class="mpmenu"></a></td></tr> +<tr><td><a href="" class="mpmenu"></a></td></tr> +<tr><td><a href="" class="mpmenu"></a></td></tr> +</tbody></table> +</td> +<td width="1px" bgcolor="#583927"></td> +<td style="text-align: right;" valign="top" width="450px"> +<table style="margin: 0px;" border="0" cellpadding="0" cellspacing="0"> +<tbody><tr> +<td><img src="introduction.agdoc_files/agg_logo.gif" border="0"></td> +</tr> +<tr> +<td> +<table style="margin: 0px;" border="0" cellpadding="0" cellspacing="0"> +<tbody><tr height="15px"> +<td> <a class="topmenu" +href="http://www.antigrain.com/news/index.html">News</a> </td> +<td width="1px" bgcolor="#8e521d"></td> +<td> <a class="topmenu" +href="http://www.antigrain.com/doc/index.html">Docs</a> </td> +<td width="1px" bgcolor="#8e521d"></td> +<td> <a class="topmenu" +href="http://www.antigrain.com/download/index.html">Download</a> </td> +<td width="1px" bgcolor="#8e521d"></td> +<td> <a class="topmenu" +href="http://www.antigrain.com/maillist/index.html">Mailing List</a> </td> +<td width="1px" bgcolor="#8e521d"></td> +<td> <a class="topmenu" +href="http://www.antigrain.com/cvs/index.html">CVS</a> </td> +</tr> +</tbody></table> +</td> +</tr> +</tbody></table> +</td> +</tr> +</tbody></table> +<table style="margin: 0px;" height="1px" width="640px" bgcolor="#583927" + border="0" cellpadding="0" cellspacing="0"><tbody><tr><td></td></tr></tbody></table> + + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p> +</p></td></tr></tbody></table> + +<table width="640px"><tbody><tr><td><h1>Introduction<span +class="subtitle"><br>Overview and Basic Concepts</span></h1></td></tr></tbody></table> + + +<table class="toc" width="640px"><tbody><tr><td> + <div style="margin-left: 2em; padding: 3px; font-size: 14px;"><a +href="#toc0001"><b>Brief Overview</b></a> + <div style="margin-left: 2em; font-size: 12px;"><a +href="#toc0002">Yet Another Invention of the Wheel</a></div> + <div style="margin-left: 2em; font-size: 12px;"><a +href="#toc0003">Gentle Criticism</a></div> + <div style="margin-left: 2em; font-size: 12px;"><a +href="#toc0004">The Proposal</a></div> + <div style="margin-left: 2em; font-size: 12px;"><a +href="#toc0005">Anti-Aliasing and Subpixel Accuracy</a></div></div> + <div style="margin-left: 2em; padding: 3px; font-size: 14px;"><a +href="#toc0006"><b>Basic Concepts</b></a> + <div style="margin-left: 2em; font-size: 12px;"><a +href="#toc0007">Design of the Library</a></div> + <div style="margin-left: 2em; font-size: 12px;"><a +href="#toc0008">Colors, Color Spaces, and Pixel Formats</a></div> + <div style="margin-left: 2em; font-size: 12px;"><a +href="#toc0009">Coordinate Units</a></div> + <div style="margin-left: 2em; font-size: 12px;"><a +href="#toc0010">AGG Building and Coding Notes</a></div></div> + <div style="margin-left: 2em; padding: 3px; font-size: 14px;"><a +href="#toc0011"><b>About this Manual</b></a></div> + +</td></tr></tbody></table> + + +<h2>Brief Overview<a name="toc0001"></a></h2> + + +<h3>Yet Another Invention of the Wheel<a name="toc0002"></a></h3> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p><b><nobr>Anti-Grain</nobr> + Geometry</b> (<b>AGG</b>) is a general purpose graphical toolkit +written completely in +standard and platform independent <b>C++</b>. +It can be used in many areas of computer programming where high quality +2D +graphics is an essential part of the project. For example, if you render + +2D geographic maps <b>AGG</b> is a must. <b>AGG</b> uses only <b>C++</b> + and standard +C runtime functions, such as <b>memcpy, sin, cos, sqrt</b>, etc. +The basic algorithms don't even use <b>C++ Standard Template Library</b>. + Thus, <b>AGG</b> can be used in a very large +number of applications, including embedded systems.</p></td></tr></tbody></table> + + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>On +the other hand, <b>AGG</b> allows you to replace any part of the +library, if, for example, +it doesn't fit performance requirements. Or you can add another color +space if needed. +All of it is possible because of extensive using of <b>C++</b> <b>template</b> + mechanism.</p></td></tr></tbody></table> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p><b><nobr>Anti-Grain</nobr> + Geometry</b> is not a solid graphic library and it's not very easy to +use. +I consider <b>AGG</b> as a <b>“tool to create other tools”</b>. It means + that there's +no <b>“Graphics”</b> object or something like that, instead, <b>AGG</b> +consists of +a number of loosely coupled algorithms that can be used together or +separately. +All of them have well defined interfaces and absolute minimum of +implicit or explicit +dependencies.</p></td></tr></tbody></table> + + + +<h3>Gentle Criticism<a name="toc0003"></a></h3> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>Most + of the graphic libraries have a single class like <b>“Graphics”</b> +in GDI+, that has hundred or even thousands of functions. This object +can exist implicitly, like in OpenGL. Anyway, all commonly used +graphical tool kits, including Java2D, DisplayPDF, SVG, and other very +good ones have this kind of a class explicitly or implicitly. +That's simple and in some cases quite suitable, but always very +restrictive. It works well only in simple cases, at least I haven't +seen a graphical library that would completely fit all my needs. +Moreover, all that kinds of libraries or standards have a +syndrome of giantism. Most of the functionality is never +used, but some simple things are impossible to achieve. Herein, the +graphical engines (or libraries) typically weigh tons of +mega-bytes. If you take the most advanced SVG viewer, +<a href="http://www.adobe.com/svg/main.html"><img +src="introduction.agdoc_files/link.gif" border="0">Adobe SVG</a>, it +works well only with +simplest primitives. As soon as you try to use some advanced things, +like interactive SVG with different graphical filters, you will have +memory leaks, or even crashes. It's not because it has bad design, +it's because the proposed possibilities assume extremely complex design. +The design itself becomes an <b>NP-complete</b> task, which is +impossible +to perceive by a human mind as impossible to perceive the infinity.</p></td></tr></tbody></table> + + + +<h3>The Proposal<a name="toc0004"></a></h3> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>The +primary goal of <b><nobr>Anti-Grain</nobr> Geometry</b> is to break this + ancient as mammoth's manure +tradition and show you the beauty of stability, lightness, +flexibility, and freedom. The basic concepts can seem not very +conventional at the beginning, but they are very close to the ones +used in <b>STL</b>. But there's a big difference too. <b>STL</b> is a +general <b>C++</b> tool +while <b>AGG</b> is <b>C++</b> graphics. You usually use <b>STL</b> in +your applications directly +as a convenient toolkit. I wouldn't say it's a good idea to use <b>AGG</b> + in the +very same way. A good idea is to create a +lightweight, problem oriented wrapper over <b>AGG</b> to solve your +particular +tasks. How can that be different from that very GDI+ then? The first +thing is that you have total control upon that wrapper. <b><nobr>Anti-Grain</nobr> + Geometry</b> just provides +you a set of basic algorithms and flexible design with the minimum of +implicit +or explitit dependencies. You and only you define the interface, +conversion pipelines, and the form of output. You can even simulate a +part +of any existing graphical interface. For example, you can use <b>AGG</b> + rasterizer +to display graphics on the screen and direct Windows GDI calls for +printing, +incorporating it into a single API. Not convincing? Look at the quality +of +rendering in <b>GDI+</b> and <b>AGG</b>: +</p></td></tr></tbody></table><a name="GDIP_AGG_QUALITY"><b></b></a><table + width="640px"><tbody><tr><td><center><img +src="introduction.agdoc_files/qual_gdip_agg.gif" title="Quality of +Rendering" border="0"><br><i>Quality of Rendering</i></center></td></tr></tbody></table> +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>But +most of all, your applications become absolutely portable, if +your design is smart enough. <b>AGG</b> can be also a tool to combine +different +outputs in a uniform API. Particularly, you can use <b>AGG</b> to +generate +raster images on the server side in your Web-Based applications. And it +all +can be <b>cross-platform!</b></p></td></tr></tbody></table> + + + +<a name="PAGE_ANTI_ALIASING"><b></b></a> +<h3>Anti-Aliasing and Subpixel Accuracy<a name="toc0005"></a></h3> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p><b><nobr>Anti-Aliasing</nobr></b> + is a very well known technique used to improve the visual quality of +images when displaying them on low resolution devices. It's based on the + properties +of the human vision. Look at the following picture and try to guess what + it means. +</p></td></tr></tbody></table><table width="640px"><tbody><tr><td><center><img + src="introduction.agdoc_files/stereo_enlarged.gif" title="" border="0"><br><i></i></center></td></tr></tbody></table> +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>Well, + it's a word drawn with <b><nobr>Anti-Aliasing</nobr></b>. In terms of +Kotelnikov-Shannon's theorem, +the maximal frequency of the image is far above of the Shannon limit.</p></td></tr></tbody></table> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p><img + src="introduction.agdoc_files/stereo_small.gif" title="" +style="border-color: rgb(255, 255, 255);" align="left" border="4"><!----> + +Now look at the same picture that has normal size and <b>within the +context</b>. You easily +recognize word <b>“stereo”</b>. However, the pictrures are exactly the +same. The first +one is just an enlarged version of the last one. This very property +allows us to +reconstruct missing information on the basis of accumulated experience. <b><nobr>Anti-Aliasing</nobr></b> + +doesn't make you see better, it basically makes you brain work better +and reconstruct +missing details. The result is great. It allows us to draw much more +detailed maps for +example.</p></td></tr></tbody></table> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>But +the point is not only in <b><nobr>Anti-Aliasing</nobr></b> itself. The +point is we can draw primitives +with <b>Subpixel Accuracy</b>. It's especially important for the visual +thickness of the lines. +First, let us see that even with simple Bresenham line interpolator we +can achieve +a better result if we use <b>Subpixel Accuracy</b>. The following +picture shows enlarged +results of the simple Bresenham interpolator. +</p></td></tr></tbody></table><a name="SUBPIXEL_BRESENHAM"><b></b></a><table + width="640px"><tbody><tr><td><center><img +src="introduction.agdoc_files/subpixel_bresenham.gif" title="A Bresenham + Line Rendered with Subpixel Accuracy" border="0"><br><i>A Bresenham +Line Rendered with Subpixel Accuracy</i></center></td></tr></tbody></table> +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>Consider + cases (2) and (3). The thin black lines are what we need to +interpolate. +If we use <b>Subpixel Accuracy</b> we will really have two different +sets of pixels +displayed, despite of the fact that the begins and ends of both lines +fall into +the same pixels. And the lines have really different tangents, which is +very important. +If we use a classical Bresenham, without considering the <b>Subpixel +Accuracy</b> we will see +result (1) in all cases. That's especially important to approximate +curves with short +line segments. But if we use <b><nobr>Anti-Aliasing</nobr></b> plus <b>Subpixel + Accuracy</b> we can do much better. +Look at that difference. +</p></td></tr></tbody></table><table width="640px"><tbody><tr><td +style="text-align: center;"><p> +<img src="introduction.agdoc_files/aliased_pix_accuracy.gif" title="" +border="0"><!----> +<img src="introduction.agdoc_files/aliased_subpix_accuracy.gif" title="" + border="0"><!----> +<img src="introduction.agdoc_files/anti_aliased.gif" title="" border="0"><!----> +</p></td></tr></tbody></table> +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>Here + all three spirals are approximated with short straight line segments. +The left one is drawn using regular integer Bresenham, when the +coordinates +are rounded off to pixels (you will have a similar result if you use +Winwows GDI MoveTo/LineTo, for example). The one in the middle uses a +modified +integer Bresenham with precision of 1/256 of a pixel. And the right one +uses +the same 1/256 accuracy, but with <b><nobr>Anti-Aliasing</nobr></b>. +Note that it's very important +to have a possibility of real subpixel positioning of the line segments. + +If we use regular pixel coordinates with <b><nobr>Anti-Aliasing</nobr></b>, + the spiral will look +smooth but still, as ugly as the one on the left.</p></td></tr></tbody></table> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>The <b>Subpixel + Accuracy</b> is even more important to control the visual thickness +of the lines. It's possible only if we have good algorithms of +<b><nobr>Anti-Aliasing</nobr></b>. On the other hand, there's no much +sense of <b><nobr>Anti-Aliasing</nobr></b> +if can set the line width with the discretness of one pixel only. <b><nobr>Anti-Aliasing</nobr></b> +and <b>Subpixel Accuracy</b> always work in cooperation.</p></td></tr></tbody></table> + + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>Modern + displays have resolutions of at most 120 DPI, while <b>Subpixel +Accuracy</b> +is actual up to 300 DPI. The following picture shows lines with +thickness +starting from 0.3 pixels and increasing by 0.3 pixel. +</p></td></tr></tbody></table><a name="LINE_THICKNESS"><b></b></a><table + width="640px"><tbody><tr><td><center><img +src="introduction.agdoc_files/line_thickness.gif" title="Lines Rendered +with Anti-Aliasing and Subpixel Accuracy" border="0"><br><i>Lines +Rendered with Anti-Aliasing and Subpixel Accuracy</i></center></td></tr></tbody></table> +<table style="margin: 0px;" height="1px" width="640px" bgcolor="#583927" + border="0" cellpadding="0" cellspacing="0"><tbody><tr><td></td></tr></tbody></table> +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>There + are two more examples of rendering with <b>Subpixel Accuracy</b>.</p></td></tr></tbody></table> + +<a name="SUBPIXEL_ACCURACY1"><b></b></a><table width="640px"><tbody><tr><td><center><img + src="introduction.agdoc_files/subpixel_accuracy1.gif" title="Circles +Rendered with Anti-Aliasing and Subpixel Accuracy" border="0"><br><i>Circles + Rendered with Anti-Aliasing and Subpixel Accuracy</i></center></td></tr></tbody></table> +<table style="margin: 0px;" height="1px" width="640px" bgcolor="#583927" + border="0" cellpadding="0" cellspacing="0"><tbody><tr><td></td></tr></tbody></table> +<a name="SUBPIXEL_ACCURACY2"><b></b></a><table width="640px"><tbody><tr><td><center><img + src="introduction.agdoc_files/subpixel_accuracy2.gif" title="Cute +Lions" border="0"><br><i>Cute Lions</i></center></td></tr></tbody></table> +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>Note + that the appearance of the small ones remains consistent +despite of lost details. +</p></td></tr></tbody></table><table style="margin: 0px;" height="1px" +width="640px" bgcolor="#583927" border="0" cellpadding="0" +cellspacing="0"><tbody><tr><td></td></tr></tbody></table> + + + + +<br><h2>Basic Concepts<a name="toc0006"></a></h2> + + + + +<h3>Design of the Library<a name="toc0007"></a></h3> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p><b><nobr>Anti-Grain</nobr> + Geometry</b> is designed as a set of loosely coupled algorithms and +class templates +united with a common idea, so that all the components can be easily +combined. +Also, the template based design allows you to replace any part of the +library without the +necessity to modify a single byte in the existing code.</p></td></tr></tbody></table> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>Also + <b>AGG</b> is designed keeping in mind extensibility and flexibility. +Basically I just wanted +to create a toolkit that would allow me (and anyone else) to add new +fancy +algorithms very easily.</p></td></tr></tbody></table> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p><b>AGG</b> + does not dictate you any style of its use, you are free to use any part + +of it. However, <b>AGG</b> is often associated with a tool for rendering + images in memory. +That is not quite true, but it can be a good starting point in studying. + +The tutorials describe the use of <b>AGG</b> starting from the low level + functionality that +deals with frame buffers and pixels. +Then you will gradually understand how to abstract different parts +of the library and how to use them separately. Remember, the raster +picture +is often not the only thing you want to obtain, you will probably want +to +print your graphics with highest possible quality and in this case you +can +easily combine the “vectorial” part of the library with some API like +Windows GDI, +having a common external interface. +If that API can render multi-polygons with non-zero and even-odd filling + rules +it's all you need to incorporate <b>AGG</b> into your application. For +example, Windows +API PolyPolygon perfectly fits these needs, except certain advanced +things like +gradient filling, Gouraud shading, image transformations, and so on. Or, + as +an alternative, you can use all <b>AGG</b> algorithms producing high +resolution pixel +images and then to send the result to the printer as a pixel map.</p></td></tr></tbody></table> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>Below + is a typical brief scheme of the <b>AGG</b> rendering pipeline. <br> +<a name="TYPICAL_SCHEME"><b></b></a><table align="left"><tbody><tr><td><center><img + src="introduction.agdoc_files/typical_scheme.gif" title="Typical Scheme + of the Rendering Pipeline" border="0"></center></td></tr><tr><td><i><center>Typical + Scheme of the Rendering Pipeline</center></i></td></tr></tbody></table> +<br> +Please note that any component between the “Vertex Source” and +“Screen Output” is not mandatory. It all depends on your particular +needs. For example, +you can use your own rasterizer, based on Windows API. In this case you +won't need +the AGG rasterizer and renderers. Or, if you need to draw only lines, +you can use the +AGG <b>outline</b> rasterizer that has certain restrictions but works +faster. The number of +possibilities is endless.</p></td></tr></tbody></table> + + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>Here: +</p><ul type="disc"> +<li><b>Vertex Source</b> is some object that produces polygons or +polylines as + a set of consecutive 2D vertices with commands like “MoveTo”, +“LineTo”. + It can be a container or some other object that generates vertices on + demand.</li> +<li><b>Coordinate conversion pipeline</b> consists of a number of +coordinate converters. + It always works with vectorial data (X,Y) represented as floating +point numbers + <nobr>(double)</nobr>. For example, it can contain an affine +transformer, outline (stroke) + generator, some marker generator (like arrowheads/arrowtails), dashed + lines + generator, and so on. The pipeline can have branches and you also can + have any + number of different pipelines. You also can write your own converter +and include + it into the pipeline.</li> +<li><b>Scanline Rasterizer</b> converts vectorial data into a number of +horizontal scanlines. + The scanlines usually (but not obligatory) carry information about <b><nobr>Anti-Aliasing</nobr></b> + as + “coverage” values. </li> +<li><b>Renderers</b> render scanlines, sorry for the tautology. The +simplest example is + solid filling. The renderer just adds a color to the scanline and +writes the result + into the rendering buffer. More complex renderers can produce +multi-color result, + like gradients, Gouraud shading, image transformations, patterns, and + so on.</li> +<li><b>Rendering Buffer</b> is a buffer in memory that will be displayed + afterwards. Usually + but not obligatory it contains pixels in format that fits your video +system. For example, + 24 bits <nobr>B-G-R</nobr>, 32 bits <nobr>B-G-R-A</nobr>, or 15 bits <nobr>R-G-B-555</nobr> + for Windows. + But in general, there're no restrictions on pixel formats or color +space if + you write your own low level class that supports that format.</li></ul><p></p></td></tr></tbody></table> + + + +<h3>Colors, Color Spaces, and Pixel Formats<a name="toc0008"></a></h3> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>Colors + in <b>AGG</b> appear only in renderers, that is, when you actually put +some data +to the rendering buffer. In general, there's no general purpose +structure or +class like <b>“color”</b>, instead, <b>AGG</b> always operates with +concrete color space. +There are plenty of color spaces in the world, like RGB, HSV, CMYK, +etc., and +all of them have certain restrictions. For example, the RGB color space +is just a +poor subset of colors that a human eye can recognize. If you look at the + +full <a href="http://www.efg2.com/Lab/Graphics/Colors/Chromaticity.htm"><img + src="introduction.agdoc_files/link.gif" border="0"><b>CIE Chromaticity +Diagram</b></a>, you will see that +the RGB triangle is just a little part of it. +</p></td></tr></tbody></table><a name="CIE_1931"><b></b></a><table +width="640px"><tbody><tr><td><center><img +src="introduction.agdoc_files/cie_1931.jpg" title="CIE Chromaticity +Diagram and the RGB Gamut" border="0"><br><i>CIE Chromaticity Diagram +and the RGB Gamut</i></center></td></tr></tbody></table> +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>In +other words there are plenty +of colors in the real world that cannot be reproduced with RGB, CMYK, +HSV, etc. +Any color space except the one existing in Nature is restrictive. +Thus, it was decided not to introduce such an object like <b>“color”</b> + in order +not to restrict the possibilities in advance. Instead, there are objects + that +operate with concrete color spaces. Currently there are agg::<a +href="http://www.antigrain.com/__code/include/agg_color_rgba.h.html#rgba">rgba</a> + and agg::<a +href="http://www.antigrain.com/__code/include/agg_color_rgba.h.html#rgba8">rgba8</a> + +that operate with the most popular <b>RGB</b> color space (strictly +speaking there's +RGB plus Alpha). The RGB color space is used with different pixel +formats, like +<nobr>24-bit</nobr> RGB or <nobr>32-bit</nobr> RGBA with different order + of color components. +But the common property of all of them is that they are essentially RGB. +Although, <b>AGG</b> doesn't explicitly support any other color spaces, +there is at +least a potential possibility of adding them. It means that all class +and +function templates that depend on the <b>“color”</b> type are +parameterized with the +<b>“ColorT”</b> argument.</p></td></tr></tbody></table> + + + +<h3>Coordinate Units<a name="toc0009"></a></h3> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>Basically, + <b>AGG</b> operates with coordinates of the output device. +On your screen there are pixels. But unlike many other libraries and +APIs +<b>AGG</b> initially supports <b>Subpixel Accuracy</b>. It means that +the coordinates are represented as +<b>doubles</b>, where fractional values actually take effect. +<b>AGG</b> doesn't have an embedded conversion mechanism from <u>world</u> + to <u>screen</u> +coordinates in order not to restrict your freedom. It's very important +where and when +you do that conversion, so, different applications can require different + approaches. +<b>AGG</b> just provides you a transformer of that kind, namely, +that can convert your own <u>view port</u> to the <u>device</u> one. And + it's your responsibility +to include it into the proper place of the pipeline. You can also write +your own +very simple class that will allow you to operate with millimeters, +inches, or any +other physical units.</p></td></tr></tbody></table> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>Internally, + the rasterizers use integer coordinates of the format +24.8 bits, that is, 24 bits for the integer part and 8 bits for the +fractional one. In other words, all the internal coordinates are +multiplied +by 256. If you intend to use <b>AGG</b> in some embedded system that has + inefficient +floating point processing, you still can use the rasterizers with their +integer +interfaces. Although, you won't be able to use the floating point +coordinate pipelines +in this case.</p></td></tr></tbody></table> + + + + +<h3>AGG Building and Coding Notes<a name="toc0010"></a></h3> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p><b><nobr>Anti-Grain</nobr> + Geometry</b> doesn't have any rich and automated environvents to build. + <b>AGG</b> mantra is +<b>“It just compiles and works”</b>. It doesn't have any installation +packages either. Maybe it's not very good from the point of view of +automated +configuring and making of applications (like it's commonly used on +Unix), +but all you need to do is just add <b>AGG</b> source files into your +distribution +package as if they were your files. +As a benefit of this approach, you won't have any problems +with configuration files and endless <b>#ifdef…#elif…#endif</b>. This is + +possible because <b>AGG</b> has absolute minimum of external +dependencies. For Unix +there are the simplest possible <b>Makefiles</b> to build the <b>.a</b> +library, for +Windows there's no library created at all. All the demo examples just +include +the necessary source files. This practice allows for more convenient +debugging +process; in fact, almost all the examples are actually used to implement + +and debug the algorithms. It also advantages stability of the library, +because all +the algorithms suffer very deep testing in the conditions near to +operational. +</p></td></tr></tbody></table><table class="note" width="640px"><tbody><tr><td><b>NOTE</b><br> +If you want to use <b>AGG</b> in Windows Visual C++ environment, please +note that +there's no <b>“stdafx.h”</b> file used. It's <a +href="http://www.microsoft.com/"><img +src="introduction.agdoc_files/link.gif" border="0"><b>Microsoft</b></a> +specific and not +a part of C/C++ standard libraries, but <a +href="http://www.microsoft.com/"><img +src="introduction.agdoc_files/link.gif" border="0"><b>Microsoft</b></a> +just enforces to use it. +To successfully use <b>AGG</b> in Visual C++ projects don't forget to +turn off the +<b>“Precompiled Headers”</b> option for all <b>AGG</b> source files. +Besides, if you +link <b>AGG</b> with static <b>MFC</b> you will probably have +duplicating <code>new</code> and <code>delete</code> +operators when linking. It's not because of <b>AGG</b>, it's because of <b>MFC</b>. +You will have the very same problem when you try to use any other <b>C++</b> +code that calls <code>new/delete</code> and doesn't include <b><nobr>stdafx.h</nobr></b>. +To resolve this situation follow the +<a +href="http://support.microsoft.com/default.aspx?scid=kb;en-us;q148652"><img + src="introduction.agdoc_files/link.gif" border="0"><b>Microsoft +recommendations</b></a> or just search in <a +href="http://www.google.com/"><img +src="introduction.agdoc_files/link.gif" border="0"><b>Google</b></a> for + <b>“<nobr>148652 LNK2005</nobr>”</b>. +</td></tr></tbody></table> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>As +it was mentioned above, <b>AGG</b> uses <b>C++</b> template mechanism +very actively. +However, it uses only well known and proven language constructions. A +good compatibility +is one of the primary aspirations. <b>C++</b> gurus can be suprised that + <b>AGG</b> doesn't use <b>STL</b>, +for example. It's done intentionally, in order not to have extra +dependencies +where the necessity of <b>STL</b> containers is very little. Of course, +it doesn't +prevent you from using <b>STL</b> or any other popular tools in a higher + level. +<b>AGG</b> is designed to have absolute minumum of potential conflicts +with existing <b>C++</b> +libraties, tools and technologies.</p></td></tr></tbody></table> + + + + +<br><h2>About this Manual<a name="toc0011"></a></h2> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>As +it was said before <b>AGG</b> provides many different levels of +functionality, so +that you can use it in many different ways. For example, you may want to + use +<b>AGG</b> rasterizers without the scanline renderers. But for the sake +of +consistency and graduality we will start from the very beginning and +describe +all the functionality with examples. This approach might be slower than +some +“Quick Start”, but it will allow you to understand the conceps of the +design. +It is really useful because you will know how to replace certain classes + and +algorithms with your own, or how to extend the library. Particularly, +the +scanline renderers are platform independent, but not the fastest. You +may want +to write your own, optimized ones, but oriented to some hardware +archtecture, like SSE2.</p></td></tr></tbody></table> + +<br><table style="margin: 0px;" height="1px" width="640px" +bgcolor="#583927" border="0" cellpadding="0" cellspacing="0"><tbody><tr><td></td></tr></tbody></table> +<table width="640px" border="0" cellpadding="0" cellspacing="0"> +<tbody><tr><td><center><span class="authors"> +Copyright <span class="larger">©</span> 2002-2006 +<a href="http://www.antigrain.com/mcseem/index.html"><b>Maxim Shemanarev</b></a> +</span></center></td></tr> +<tr><td><center><span class="authors"> +Web Design and Programming +<a href="http://www.antigrain.com/mcseem/index.html"><b>Maxim Shemanarev</b></a> +</span></center></td></tr> +</tbody></table> +<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br> +<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br> +<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br> +<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br> +</body></html>
\ No newline at end of file diff --git a/docs/aggpas/introduction.agdoc_files/agg.css b/docs/aggpas/introduction.agdoc_files/agg.css new file mode 100644 index 00000000..997d9d07 --- /dev/null +++ b/docs/aggpas/introduction.agdoc_files/agg.css @@ -0,0 +1,239 @@ +BODY +{ + font-family:Verdana, Arial, Tahoma; + font-size:12px; + color:#160801; + background-color:#ffffff; + text-align:justify; + padding:5px; +} + +P, UL, OL, DL +{ + font-family:Verdana, Arial, Tahoma; + font-size:12px; + color:#160801; + margin-bottom:0px; + margin-top:0px; +} + + +.larger +{ + font-size:14px; +} + +LI +{ + padding:3px; +} + +HR +{ + color:#583927; + height:1px; +} + +H1 +{ + font-family:Verdana, Arial, Tahoma; + font-size:28px; + font-weight:bolder; + text-align:center; + color:#583927; + margin:0px; +} + +H1 SPAN.subtitle +{ + font-family:Verdana, Arial, Tahoma; + font-size:18px; + font-weight:lighter; +} + + +H2 +{ + font-family:Verdana, Arial, Tahoma; + font-size:26px; + font-weight:normal; + text-align:left; + color:#583927; +} + +H3 +{ + font-family:Verdana, Arial, Tahoma; + font-size:20px; + font-weight:normal; + text-align:left; + color:#583927; +} + +H4 +{ + font-family:Verdana, Arial, Tahoma; + font-size:16px; + font-weight:bold; + text-align:left; + color:#583927; +} + +H5 +{ + font-family:Verdana, Arial, Tahoma; + font-size:14px; + font-weight:bold; + text-align:left; + color:#583927; +} + +TABLE +{ + margin:5px; +} + +TD +{ + font-family:Verdana, Arial, Tahoma; + font-size:12px; +} + +TH +{ + font-family:Verdana, Arial, Tahoma; + background-color:#d4d4d4; + font-size:12px; +} + + +PRE +{ + padding: 5px; + border: gray 1px solid; + background-color:#f4f4f4; + color:#130f00; + font-family:"courier new", courier,mono; + font-size:12px; + margin:0px; +} + +TT, CODE +{ + font-family:"courier new", courier,mono; + font-size:14px; + color:#000070; +} + +.warning, .warning TD +{ + background-color:#fcf6f6; + color:#793131; + padding:0.5em; + font-family:Verdana, Arial, Tahoma; + font-size:12px; + text-align:justify; +} + +.note, .note TD +{ + background-color:#f0fafa; + color:#506580; + padding:0.5em; + font-family:Verdana, Arial, Tahoma; + font-size:12px; + text-align:justify; +} + +.quote, .quote TD +{ + background-color:#f0fafa; + color:#000540; + padding:0.5em; + font-family:Verdana, Arial, Tahoma; + font-size:12px; + text-align:justify; +} + +.tip, .tip TD +{ + background-color:#fbfff6; + color:#68771e; + padding:0.5em; + font-family:Verdana, Arial, Tahoma; + font-size:12px; + text-align:justify; +} + +.tbl TD +{ + background-color:#f4f4f4; + font-family:Verdana, Arial, Tahoma; + font-size:12px; + text-align:left; + padding:3px; +} + +.toc TD +{ + font-family:Verdana, Arial, Tahoma; + text-align:left; + padding:3px; +} + +.title {font-family:Verdana, Arial, Tahoma;} + +.warning P, +.warning PRE, +.note P, +.note PRE, +.tip P, +.tip PRE {margin:0.3em 0em 0.1em 0em;} + +.warning .code {background-color:#fcf6f6;} +.note .code {background-color:#f0fafa;} +.tip .code {background-color:#fbfff6;} + +A {text-decoration:none; color:#700000;} +A:visited {text-decoration:none; color:#85585d;} +A:link {text-decoration:none;} +A:hover {text-decoration:underline;} + +.topmenu,a.topmenu:visited,a.topmenu:hover,a.topmenu:active,a.topmenu:link +{ + font-family: Arial, Tahoma, Helvetica, sans-serif; + font-size: 11px; + font-weight: bold; + text-decoration: none; + color: #582218; +} + +.mpmenu,a.mpmenu:visited,a.mpmenu:hover,a.mpmenu:active,a.mpmenu:link +{ + font-family: Arial, Tahoma, Helvetica, sans-serif; + font-size: 12px; + font-weight: bold; + text-decoration: none; + color: #582218; +} + +.tah +{ + font-family: Tahoma, Arial, Helvetica, sans-serif; + font-size: 12px; + color: #582218; +} + +.authors +{ + font-size:10px; +} + +span.rem {color:#4c8d00;} +span.kw1 {color:#000d8e;} +span.kw2 {color:#0075ca;} +span.kw3 {color:#004645;} +span.kw4 {color:#673517;} +span.op {color:#4a006d;} +span.str {color:#ab2500;} +span.num {color:#a74c3f;} diff --git a/docs/aggpas/introduction.agdoc_files/agg_logo.gif b/docs/aggpas/introduction.agdoc_files/agg_logo.gif Binary files differnew file mode 100644 index 00000000..ee5c570a --- /dev/null +++ b/docs/aggpas/introduction.agdoc_files/agg_logo.gif diff --git a/docs/aggpas/introduction.agdoc_files/aliased_pix_accuracy.gif b/docs/aggpas/introduction.agdoc_files/aliased_pix_accuracy.gif Binary files differnew file mode 100644 index 00000000..996f1621 --- /dev/null +++ b/docs/aggpas/introduction.agdoc_files/aliased_pix_accuracy.gif diff --git a/docs/aggpas/introduction.agdoc_files/aliased_subpix_accuracy.gif b/docs/aggpas/introduction.agdoc_files/aliased_subpix_accuracy.gif Binary files differnew file mode 100644 index 00000000..4ab4e127 --- /dev/null +++ b/docs/aggpas/introduction.agdoc_files/aliased_subpix_accuracy.gif diff --git a/docs/aggpas/introduction.agdoc_files/anti_aliased.gif b/docs/aggpas/introduction.agdoc_files/anti_aliased.gif Binary files differnew file mode 100644 index 00000000..79d7d595 --- /dev/null +++ b/docs/aggpas/introduction.agdoc_files/anti_aliased.gif diff --git a/docs/aggpas/introduction.agdoc_files/cie_1931.jpg b/docs/aggpas/introduction.agdoc_files/cie_1931.jpg Binary files differnew file mode 100644 index 00000000..dd243e10 --- /dev/null +++ b/docs/aggpas/introduction.agdoc_files/cie_1931.jpg diff --git a/docs/aggpas/introduction.agdoc_files/line_thickness.gif b/docs/aggpas/introduction.agdoc_files/line_thickness.gif Binary files differnew file mode 100644 index 00000000..842e0b62 --- /dev/null +++ b/docs/aggpas/introduction.agdoc_files/line_thickness.gif diff --git a/docs/aggpas/introduction.agdoc_files/link.gif b/docs/aggpas/introduction.agdoc_files/link.gif Binary files differnew file mode 100644 index 00000000..76a532cf --- /dev/null +++ b/docs/aggpas/introduction.agdoc_files/link.gif diff --git a/docs/aggpas/introduction.agdoc_files/qual_gdip_agg.gif b/docs/aggpas/introduction.agdoc_files/qual_gdip_agg.gif Binary files differnew file mode 100644 index 00000000..eafc2260 --- /dev/null +++ b/docs/aggpas/introduction.agdoc_files/qual_gdip_agg.gif diff --git a/docs/aggpas/introduction.agdoc_files/stereo_enlarged.gif b/docs/aggpas/introduction.agdoc_files/stereo_enlarged.gif Binary files differnew file mode 100644 index 00000000..27d30ebe --- /dev/null +++ b/docs/aggpas/introduction.agdoc_files/stereo_enlarged.gif diff --git a/docs/aggpas/introduction.agdoc_files/stereo_small.gif b/docs/aggpas/introduction.agdoc_files/stereo_small.gif Binary files differnew file mode 100644 index 00000000..2d4545c1 --- /dev/null +++ b/docs/aggpas/introduction.agdoc_files/stereo_small.gif diff --git a/docs/aggpas/introduction.agdoc_files/subpixel_accuracy1.gif b/docs/aggpas/introduction.agdoc_files/subpixel_accuracy1.gif Binary files differnew file mode 100644 index 00000000..97a2ce28 --- /dev/null +++ b/docs/aggpas/introduction.agdoc_files/subpixel_accuracy1.gif diff --git a/docs/aggpas/introduction.agdoc_files/subpixel_accuracy2.gif b/docs/aggpas/introduction.agdoc_files/subpixel_accuracy2.gif Binary files differnew file mode 100644 index 00000000..c940508c --- /dev/null +++ b/docs/aggpas/introduction.agdoc_files/subpixel_accuracy2.gif diff --git a/docs/aggpas/introduction.agdoc_files/subpixel_bresenham.gif b/docs/aggpas/introduction.agdoc_files/subpixel_bresenham.gif Binary files differnew file mode 100644 index 00000000..56ca899b --- /dev/null +++ b/docs/aggpas/introduction.agdoc_files/subpixel_bresenham.gif diff --git a/docs/aggpas/introduction.agdoc_files/typical_scheme.gif b/docs/aggpas/introduction.agdoc_files/typical_scheme.gif Binary files differnew file mode 100644 index 00000000..2d548749 --- /dev/null +++ b/docs/aggpas/introduction.agdoc_files/typical_scheme.gif diff --git a/docs/aggpas/line_alignment.agdoc.html b/docs/aggpas/line_alignment.agdoc.html new file mode 100644 index 00000000..c86dab80 --- /dev/null +++ b/docs/aggpas/line_alignment.agdoc.html @@ -0,0 +1,263 @@ +<html><head><title>Anti-Grain Geometry - The Problem of Line Alignment</title> +<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> +<link rel="stylesheet" type="text/css" +href="line_alignment.agdoc_files/agg.css"> +</head><body><a name="PAGE_LINE_ALIGNMENT"><b></b></a> + + +<table style="margin: 0px;" height="1px" width="640px" border="0" +cellpadding="0" cellspacing="0"> +<tbody><tr> +<td bgcolor="#583927"></td> +</tr> +</tbody></table> +<table style="margin: 0px;" width="640px" border="0" cellpadding="0" +cellspacing="0"> +<tbody><tr> +<td> +<table style="margin: 0px;" width="170px" border="0" cellpadding="0" +cellspacing="0"> +<tbody><tr><td><a href="http://antigrain.com/index.html" class="mpmenu">Home/</a></td></tr> +<tr><td><a href="http://antigrain.com/tips/index.html" class="mpmenu">Tips + & Tricks/</a></td></tr> +<tr><td><a href="" class="mpmenu"></a></td></tr> +<tr><td><a href="" class="mpmenu"></a></td></tr> +<tr><td><a href="" class="mpmenu"></a></td></tr> +<tr><td><a href="" class="mpmenu"></a></td></tr> +</tbody></table> +</td> +<td width="1px" bgcolor="#583927"></td> +<td style="text-align: right;" valign="top" width="450px"> +<table style="margin: 0px;" border="0" cellpadding="0" cellspacing="0"> +<tbody><tr> +<td><img src="line_alignment.agdoc_files/agg_logo.gif" border="0"></td> +</tr> +<tr> +<td> +<table style="margin: 0px;" border="0" cellpadding="0" cellspacing="0"> +<tbody><tr height="15px"> +<td> <a class="topmenu" +href="http://antigrain.com/news/index.html">News</a> </td> +<td width="1px" bgcolor="#8e521d"></td> +<td> <a class="topmenu" +href="http://antigrain.com/doc/index.html">Docs</a> </td> +<td width="1px" bgcolor="#8e521d"></td> +<td> <a class="topmenu" +href="http://antigrain.com/download/index.html">Download</a> </td> +<td width="1px" bgcolor="#8e521d"></td> +<td> <a class="topmenu" +href="http://antigrain.com/maillist/index.html">Mailing List</a> </td> +<td width="1px" bgcolor="#8e521d"></td> +<td> <a class="topmenu" +href="http://antigrain.com/cvs/index.html">CVS</a> </td> +</tr> +</tbody></table> +</td> +</tr> +</tbody></table> +</td> +</tr> +</tbody></table> +<table style="margin: 0px;" height="1px" width="640px" bgcolor="#583927" + border="0" cellpadding="0" cellspacing="0"><tbody><tr><td></td></tr></tbody></table> + + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p> +</p></td></tr></tbody></table> + +<table width="640px"><tbody><tr><td><h1>The Problem of Line Alignment<span + class="subtitle"><br>The "half-a-pixel" problem when rendering lines</span></h1></td></tr></tbody></table> + + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p><b><nobr>Anti-Aliasing</nobr></b> + is a tricky thing. If you decided you like <b>AGG</b> and it finally +solves all your problems in 2D graphics, it's a mistake. +Nothing of the kind. The more you worry about the quality +the more problems there are exposed.</p></td></tr></tbody></table> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>Let +us start with a simple rectangle. +</p></td></tr></tbody></table><table width="640px"><tbody><tr><td><center><img + src="line_alignment.agdoc_files/rect1.gif" title="" border="0"><br><i></i></center></td></tr></tbody></table> +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>Here + we have a rectangle with exact integral coordinates (1,1,4,4). +Everything looks fine, but to understand and see how the <b><nobr>Anti-Aliasing</nobr></b> + and <b>Subpixel Accuracy</b> +work let's shift it to 0.5 pixel by X and Y: +</p></td></tr></tbody></table><table width="640px"><tbody><tr><td><center><img + src="line_alignment.agdoc_files/rect2.gif" title="" border="0"><br><i></i></center></td></tr></tbody></table> +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>The +pixels have intensities proportional to the area of the pixel +covered by the rectangle. In practice it means that the rectangle +looks blur. It's not a caprice, it's a necessity because only +in this case we can preserve the <b>visual</b> area covered by the +rectangle the same, regardless of its subpixel position. The +initial rectangle covers 9 pixels. If we just round off the +coordinates, the resulting rectangle can be drawn as 4 pixels and +it can be drawn as 16 pixels, depending on the position and +the rounding rules. So that, the “blurness” is much less evil +than "jitter" because it allows you to keep the image much more +consistent.</p></td></tr></tbody></table> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>Now +let's try to calculate an outline of one pixel width around +this square: +</p></td></tr></tbody></table><table width="640px"><tbody><tr><td><center><img + src="line_alignment.agdoc_files/rect3.gif" title="" border="0"><br><i></i></center></td></tr></tbody></table> +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>This + is an ideal case. In prcatice we cannot draw anything between +pixels, so the result will look even more blur: +</p></td></tr></tbody></table><table width="640px"><tbody><tr><td><center><img + src="line_alignment.agdoc_files/rect4.gif" title="" border="0"><br><i></i></center></td></tr></tbody></table> +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>There + are no fully covered pixels at all and this fact creates the +problem of line alignment. Bad news is that there's no ideal +solution of it, we'll have to sacrifice something. The good news +is there are several partial solutions that can be satisfactory. +First, let's try to add 0.5 to the coordinates of the <b>outline</b>. +Remember, if we add 0.5 to the filled rectangle too, the ones +without outlines will look blur (see above). +</p></td></tr></tbody></table><table width="640px"><tbody><tr><td><center><img + src="line_alignment.agdoc_files/rect5.gif" title="" border="0"><br><i></i></center></td></tr></tbody></table> +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>Looks + perfect while the outline is 100% opaque. If we have a +translucent boundary it will look worse: +</p></td></tr></tbody></table><table width="640px"><tbody><tr><td><center><img + src="line_alignment.agdoc_files/rect6.gif" title="" border="0"><br><i></i></center></td></tr></tbody></table> +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>The +translucency can be <b>implicit</b>, for example, if we draw a +line of 0.5 pixel width, it's simulated with translucency! +It will look better if we shift both, the fill and its outline. +</p></td></tr></tbody></table><table width="640px"><tbody><tr><td><center><img + src="line_alignment.agdoc_files/rect61.gif" title="" border="0"><br><i></i></center></td></tr></tbody></table> +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>But +remember, it will look worse if it's not outlined. Still, +The first solution is to shift everything to 0.5 pixel, which +can be appropriate when you have outlines in all cases.</p></td></tr></tbody></table> + + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>The +second solution is to shift only outlines, keeping +the filled polygons as they are. In this case you must be +sure you always have the outline of at least 1 pixel width. That's +not a good restriction. You can do even better, shifting only +those polygons that have an outline (stroke). But in this case +you can have some inconsistency between polygons with and without +strokes.</p></td></tr></tbody></table> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>The +shifting transformer is very simple:</p></td></tr></tbody></table> + +<table width="640px" border="0" cellpadding="0" cellspacing="0"><tbody><tr><td><pre><span class="kw1">namespace</span> agg +<span class="op">{</span> + <span class="kw1">class</span> trans_shift + <span class="op">{</span> + <span class="kw1">public</span>: + trans_shift<span class="op">(</span><span class="op">)</span> : m_shift<span class="op">(</span><span class="num">0</span><span class="op">.</span><span class="num">0</span><span class="op">)</span> <span class="op">{</span><span class="op">}</span> + trans_shift<span class="op">(</span><span class="kw1">double</span> s<span class="op">)</span> : m_shift<span class="op">(</span>s<span class="op">)</span> <span class="op">{</span><span class="op">}</span> + + <span class="kw1">void</span> shift<span class="op">(</span><span class="kw1">double</span> s<span class="op">)</span> <span class="op">{</span> m_shift <span class="op">=</span> s<span class="op">;</span> <span class="op">}</span> + <span class="kw1">double</span> shift<span class="op">(</span><span class="op">)</span> <span class="kw1">const</span> <span class="op">{</span> <span class="kw1">return</span> m_shift<span class="op">;</span> <span class="op">}</span> + + <span class="kw1">void</span> transform<span class="op">(</span><span class="kw1">double</span><span class="op">*</span> x<span class="op">,</span> <span class="kw1">double</span><span class="op">*</span> y<span class="op">)</span> <span class="kw1">const</span> + <span class="op">{</span> + <span class="op">*</span>x <span class="op">+=</span> m_shift<span class="op">;</span> + <span class="op">*</span>y <span class="op">+=</span> m_shift<span class="op">;</span> + <span class="op">}</span> + <span class="kw1">private</span>: + <span class="kw1">double</span> m_shift<span class="op">;</span> + <span class="op">}</span><span class="op">;</span> +<span class="op">}</span></pre></td></tr></tbody></table><font +style="margin-left: 1em;"><i></i></font> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>And +its use is simple too:</p></td></tr></tbody></table> + +<table width="640px" border="0" cellpadding="0" cellspacing="0"><tbody><tr><td><pre>agg::trans_shift ts<span class="op">(</span><span class="num">0</span><span class="op">.</span><span class="num">5</span><span class="op">)</span><span class="op">;</span> +agg::<a href="http://antigrain.com/__code/include/agg_conv_transform.h.html#conv_transform">conv_transform</a><span class="op"><</span>source_class<span class="op">,</span> agg::trans_shift<span class="op">></span> shift<span class="op">(</span>source<span class="op">,</span> ts<span class="op">)</span><span class="op">;</span> +</pre></td></tr></tbody></table><font style="margin-left: 1em;"><i></i></font> +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>That + is, it's included into the pipeline as yet another transformer. +If you use the affine transformer (most probably you will), you can do +without this additional converter. Just add the following, after the +matrix is formed: +</p></td></tr></tbody></table><table width="640px" border="0" +cellpadding="0" cellspacing="0"><tbody><tr><td><pre>mtx <span class="op">*=</span> agg::trans_affine_translate<span class="op">(</span><span class="num">0</span><span class="op">.</span><span class="num">5</span><span class="op">,</span> <span class="num">0</span><span class="op">.</span><span class="num">5</span><span class="op">)</span><span class="op">;</span></pre></td></tr></tbody></table><font + style="margin-left: 1em;"><i></i></font> +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>In +this case there will be no additional +“performance fee”. Of course, you will have to worry about when and +where to add this shift (see cases above).</p></td></tr></tbody></table> + + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>There + is one more solution and it can be even better. Nobody says that +we need to apply the same shift to all coordinates. In case of our +rectangle there can be <b>inner</b> or <b>outer</b> outline: +</p></td></tr></tbody></table><table width="640px"><tbody><tr><td +style="text-align: center;"><p><img +src="line_alignment.agdoc_files/rect7.gif" title="" border="0"><!----> + <img src="line_alignment.agdoc_files/rect8.gif" + title="" border="0"><!----></p></td></tr></tbody></table> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>You +can achive this with using <a +href="http://antigrain.com/__code/include/agg_conv_contour.h.html#conv_contour">conv_contour</a>, + see also +<a href="http://antigrain.com/demo/index.html#PAGE_DEMO_conv_contour">Demo + conv_contour.cpp</a>.</p></td></tr></tbody></table> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>But +there are some problems too. First of all, the “insideness” +becomes important, while <a +href="http://antigrain.com/__code/include/agg_conv_stroke.h.html#conv_stroke">conv_stroke</a> + doesn't care about it. So that, +you should preserve or detect the orientation of the contours, not +to mention that self-intersecting polygons don't have a univocal +orientation, they can have only a “prevaling” orientation.</p></td></tr></tbody></table> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>The +second problem is where to apply this transformation. It should be +definitely done <b>before</b> stroke converter. But there is a +contradiction with the succeeding affine transformations. Take the +zoom operation, for example. If you want the line widths to be +consistent +with the transformations, you have to use the affine transformer +<b>after</b> the outline is calculated. If it's done before, you can +change +the stroke width respectively, but in this case you breake the +integrity if you have different scaling coefficients by X and Y. +</p></td></tr></tbody></table><table width="640px"><tbody><tr><td><center><img + src="line_alignment.agdoc_files/conv_order.gif" title="" border="0"><br><i></i></center></td></tr></tbody></table> +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>If +you are absolutely sure you will never use different scaling +coefficients by X and Y, you can transform paths before +calculating the outline. In other words, the sequence of the +conversions is important and it can be contadictive. Besides, +you have to decide if you only need to correct the +“0.5 problem” or to have the true <b>inner</b> or <b>outer</b> stroke.</p></td></tr></tbody></table> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>The +conclusion is that there's no ideal solution. But the whole +idea of <b><nobr>Anti-Grain</nobr> Geometry</b> is that it's you who +chooses the neccessary pipelines +and solve your problem-orinted tasks. Thare are no other APIs that +allow you to have this flexibility.</p></td></tr></tbody></table> + +<table style="margin: 0px;" height="1px" width="640px" bgcolor="#583927" + border="0" cellpadding="0" cellspacing="0"><tbody><tr><td></td></tr></tbody></table> +<table width="640px" border="0" cellpadding="0" cellspacing="0"> +<tbody><tr><td><center><span class="authors"> +Copyright <span class="larger">©</span> 2002-2006 +<a href="http://antigrain.com/mcseem/index.html"><b>Maxim Shemanarev</b></a> +</span></center></td></tr> +<tr><td><center><span class="authors"> +Web Design and Programming +<a href="http://antigrain.com/mcseem/index.html"><b>Maxim Shemanarev</b></a> +</span></center></td></tr> +</tbody></table> +<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br> +<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br> +<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br> +<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br> +</body></html>
\ No newline at end of file diff --git a/docs/aggpas/line_alignment.agdoc_files/agg.css b/docs/aggpas/line_alignment.agdoc_files/agg.css new file mode 100644 index 00000000..997d9d07 --- /dev/null +++ b/docs/aggpas/line_alignment.agdoc_files/agg.css @@ -0,0 +1,239 @@ +BODY +{ + font-family:Verdana, Arial, Tahoma; + font-size:12px; + color:#160801; + background-color:#ffffff; + text-align:justify; + padding:5px; +} + +P, UL, OL, DL +{ + font-family:Verdana, Arial, Tahoma; + font-size:12px; + color:#160801; + margin-bottom:0px; + margin-top:0px; +} + + +.larger +{ + font-size:14px; +} + +LI +{ + padding:3px; +} + +HR +{ + color:#583927; + height:1px; +} + +H1 +{ + font-family:Verdana, Arial, Tahoma; + font-size:28px; + font-weight:bolder; + text-align:center; + color:#583927; + margin:0px; +} + +H1 SPAN.subtitle +{ + font-family:Verdana, Arial, Tahoma; + font-size:18px; + font-weight:lighter; +} + + +H2 +{ + font-family:Verdana, Arial, Tahoma; + font-size:26px; + font-weight:normal; + text-align:left; + color:#583927; +} + +H3 +{ + font-family:Verdana, Arial, Tahoma; + font-size:20px; + font-weight:normal; + text-align:left; + color:#583927; +} + +H4 +{ + font-family:Verdana, Arial, Tahoma; + font-size:16px; + font-weight:bold; + text-align:left; + color:#583927; +} + +H5 +{ + font-family:Verdana, Arial, Tahoma; + font-size:14px; + font-weight:bold; + text-align:left; + color:#583927; +} + +TABLE +{ + margin:5px; +} + +TD +{ + font-family:Verdana, Arial, Tahoma; + font-size:12px; +} + +TH +{ + font-family:Verdana, Arial, Tahoma; + background-color:#d4d4d4; + font-size:12px; +} + + +PRE +{ + padding: 5px; + border: gray 1px solid; + background-color:#f4f4f4; + color:#130f00; + font-family:"courier new", courier,mono; + font-size:12px; + margin:0px; +} + +TT, CODE +{ + font-family:"courier new", courier,mono; + font-size:14px; + color:#000070; +} + +.warning, .warning TD +{ + background-color:#fcf6f6; + color:#793131; + padding:0.5em; + font-family:Verdana, Arial, Tahoma; + font-size:12px; + text-align:justify; +} + +.note, .note TD +{ + background-color:#f0fafa; + color:#506580; + padding:0.5em; + font-family:Verdana, Arial, Tahoma; + font-size:12px; + text-align:justify; +} + +.quote, .quote TD +{ + background-color:#f0fafa; + color:#000540; + padding:0.5em; + font-family:Verdana, Arial, Tahoma; + font-size:12px; + text-align:justify; +} + +.tip, .tip TD +{ + background-color:#fbfff6; + color:#68771e; + padding:0.5em; + font-family:Verdana, Arial, Tahoma; + font-size:12px; + text-align:justify; +} + +.tbl TD +{ + background-color:#f4f4f4; + font-family:Verdana, Arial, Tahoma; + font-size:12px; + text-align:left; + padding:3px; +} + +.toc TD +{ + font-family:Verdana, Arial, Tahoma; + text-align:left; + padding:3px; +} + +.title {font-family:Verdana, Arial, Tahoma;} + +.warning P, +.warning PRE, +.note P, +.note PRE, +.tip P, +.tip PRE {margin:0.3em 0em 0.1em 0em;} + +.warning .code {background-color:#fcf6f6;} +.note .code {background-color:#f0fafa;} +.tip .code {background-color:#fbfff6;} + +A {text-decoration:none; color:#700000;} +A:visited {text-decoration:none; color:#85585d;} +A:link {text-decoration:none;} +A:hover {text-decoration:underline;} + +.topmenu,a.topmenu:visited,a.topmenu:hover,a.topmenu:active,a.topmenu:link +{ + font-family: Arial, Tahoma, Helvetica, sans-serif; + font-size: 11px; + font-weight: bold; + text-decoration: none; + color: #582218; +} + +.mpmenu,a.mpmenu:visited,a.mpmenu:hover,a.mpmenu:active,a.mpmenu:link +{ + font-family: Arial, Tahoma, Helvetica, sans-serif; + font-size: 12px; + font-weight: bold; + text-decoration: none; + color: #582218; +} + +.tah +{ + font-family: Tahoma, Arial, Helvetica, sans-serif; + font-size: 12px; + color: #582218; +} + +.authors +{ + font-size:10px; +} + +span.rem {color:#4c8d00;} +span.kw1 {color:#000d8e;} +span.kw2 {color:#0075ca;} +span.kw3 {color:#004645;} +span.kw4 {color:#673517;} +span.op {color:#4a006d;} +span.str {color:#ab2500;} +span.num {color:#a74c3f;} diff --git a/docs/aggpas/line_alignment.agdoc_files/agg_logo.gif b/docs/aggpas/line_alignment.agdoc_files/agg_logo.gif Binary files differnew file mode 100644 index 00000000..ee5c570a --- /dev/null +++ b/docs/aggpas/line_alignment.agdoc_files/agg_logo.gif diff --git a/docs/aggpas/line_alignment.agdoc_files/conv_order.gif b/docs/aggpas/line_alignment.agdoc_files/conv_order.gif Binary files differnew file mode 100644 index 00000000..c928883f --- /dev/null +++ b/docs/aggpas/line_alignment.agdoc_files/conv_order.gif diff --git a/docs/aggpas/line_alignment.agdoc_files/rect1.gif b/docs/aggpas/line_alignment.agdoc_files/rect1.gif Binary files differnew file mode 100644 index 00000000..b149a650 --- /dev/null +++ b/docs/aggpas/line_alignment.agdoc_files/rect1.gif diff --git a/docs/aggpas/line_alignment.agdoc_files/rect2.gif b/docs/aggpas/line_alignment.agdoc_files/rect2.gif Binary files differnew file mode 100644 index 00000000..c256e12e --- /dev/null +++ b/docs/aggpas/line_alignment.agdoc_files/rect2.gif diff --git a/docs/aggpas/line_alignment.agdoc_files/rect3.gif b/docs/aggpas/line_alignment.agdoc_files/rect3.gif Binary files differnew file mode 100644 index 00000000..2daddaa2 --- /dev/null +++ b/docs/aggpas/line_alignment.agdoc_files/rect3.gif diff --git a/docs/aggpas/line_alignment.agdoc_files/rect4.gif b/docs/aggpas/line_alignment.agdoc_files/rect4.gif Binary files differnew file mode 100644 index 00000000..38ca7d2c --- /dev/null +++ b/docs/aggpas/line_alignment.agdoc_files/rect4.gif diff --git a/docs/aggpas/line_alignment.agdoc_files/rect5.gif b/docs/aggpas/line_alignment.agdoc_files/rect5.gif Binary files differnew file mode 100644 index 00000000..4c19dac4 --- /dev/null +++ b/docs/aggpas/line_alignment.agdoc_files/rect5.gif diff --git a/docs/aggpas/line_alignment.agdoc_files/rect6.gif b/docs/aggpas/line_alignment.agdoc_files/rect6.gif Binary files differnew file mode 100644 index 00000000..74526ef1 --- /dev/null +++ b/docs/aggpas/line_alignment.agdoc_files/rect6.gif diff --git a/docs/aggpas/line_alignment.agdoc_files/rect61.gif b/docs/aggpas/line_alignment.agdoc_files/rect61.gif Binary files differnew file mode 100644 index 00000000..e55fad1a --- /dev/null +++ b/docs/aggpas/line_alignment.agdoc_files/rect61.gif diff --git a/docs/aggpas/line_alignment.agdoc_files/rect7.gif b/docs/aggpas/line_alignment.agdoc_files/rect7.gif Binary files differnew file mode 100644 index 00000000..36ed8e29 --- /dev/null +++ b/docs/aggpas/line_alignment.agdoc_files/rect7.gif diff --git a/docs/aggpas/line_alignment.agdoc_files/rect8.gif b/docs/aggpas/line_alignment.agdoc_files/rect8.gif Binary files differnew file mode 100644 index 00000000..ead8c394 --- /dev/null +++ b/docs/aggpas/line_alignment.agdoc_files/rect8.gif diff --git a/docs/aggpas/original_demos.html b/docs/aggpas/original_demos.html new file mode 100644 index 00000000..a8d61b30 --- /dev/null +++ b/docs/aggpas/original_demos.html @@ -0,0 +1,1511 @@ +<html><head><title>Anti-Grain Geometry - Demo Examples</title> +<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> +<link rel="stylesheet" type="text/css" +href="original_demos_files/agg.css"> +</head><body><a name="PAGE_DEMO"><b></b></a> + + +<table style="margin: 0px;" height="1px" width="640px" border="0" +cellpadding="0" cellspacing="0"> +<tbody><tr> +<td bgcolor="#583927"></td> +</tr> +</tbody></table> +<table style="margin: 0px;" width="640px" border="0" cellpadding="0" +cellspacing="0"> +<tbody><tr> +<td> +<table style="margin: 0px;" width="170px" border="0" cellpadding="0" +cellspacing="0"> +<tbody><tr><td><a href="http://www.antigrain.com/index.html" +class="mpmenu">Home/</a></td></tr> +<tr><td><a href="" class="mpmenu"></a></td></tr> +<tr><td><a href="" class="mpmenu"></a></td></tr> +<tr><td><a href="" class="mpmenu"></a></td></tr> +<tr><td><a href="" class="mpmenu"></a></td></tr> +<tr><td><a href="" class="mpmenu"></a></td></tr> +</tbody></table> +</td> +<td width="1px" bgcolor="#583927"></td> +<td style="text-align: right;" valign="top" width="450px"> +<table style="margin: 0px;" border="0" cellpadding="0" cellspacing="0"> +<tbody><tr> +<td><img src="original_demos_files/agg_logo.gif" border="0"></td> +</tr> +<tr> +<td> +<table style="margin: 0px;" border="0" cellpadding="0" cellspacing="0"> +<tbody><tr height="15px"> +<td> <a class="topmenu" +href="http://www.antigrain.com/news/index.html">News</a> </td> +<td width="1px" bgcolor="#8e521d"></td> +<td> <a class="topmenu" +href="http://www.antigrain.com/doc/index.html">Docs</a> </td> +<td width="1px" bgcolor="#8e521d"></td> +<td> <a class="topmenu" +href="http://www.antigrain.com/download/index.html">Download</a> </td> +<td width="1px" bgcolor="#8e521d"></td> +<td> <a class="topmenu" +href="http://www.antigrain.com/maillist/index.html">Mailing List</a> </td> +<td width="1px" bgcolor="#8e521d"></td> +<td> <a class="topmenu" +href="http://www.antigrain.com/cvs/index.html">CVS</a> </td> +</tr> +</tbody></table> +</td> +</tr> +</tbody></table> +</td> +</tr> +</tbody></table> +<table style="margin: 0px;" height="1px" width="640px" bgcolor="#583927" + border="0" cellpadding="0" cellspacing="0"><tbody><tr><td></td></tr></tbody></table> + + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p></p></td></tr></tbody></table> + +<table width="640px"><tbody><tr><td><h1>Demo Examples</h1></td></tr></tbody></table> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>All +the demo examples are in the distribution package, see <a +href="http://www.antigrain.com/download/index.html#PAGE_DOWNLOAD">Download</a>. + +This page contains precompiled executables with screenshots and brief +explanations. It is safe to download and run the executables, there are +no viruses and no any trojan code. Also, there is nothing installed +on your computer, you just download, unpack, run, and see the examples. +However, it's always a good idea to double check everything with your +favorite anti-virus software before running. +If you don't trust it, you can download the sources +(see <a +href="http://www.antigrain.com/download/index.html#PAGE_DOWNLOAD">Download</a>), + compile and run the examples, and of course, +analyse the source code for any possible destructive subroutines. +I have no responsibility if your computer is infected with some +virus program.</p></td></tr></tbody></table> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>The +image examples require file <code>spheres.bmp</code> for Windows +executables, +and <code>spheres.ppm</code> for Linux ones. Download them from here:<br> +<a href="http://www.antigrain.com/spheres.bmp"><img +src="original_demos_files/download.gif" border="0"> (../spheres.bmp)</a><br> +<a href="http://www.antigrain.com/spheres.ppm"><img +src="original_demos_files/download.gif" border="0"> (../spheres.ppm)</a><br> +You can also use any other .BMP or .PPM file of about the same size. +The .BMP file must be of 24 bit TrueColor, the .PPM one must be of type +P6 +(24 bit per pixel RGB). There are two ways to use your own files in +image +demo examples. You can simply call it <code>spheres.bmp</code> or <code>spheres.ppm</code> + +and put them to the directory +where you run the examples, or indicate the name of the file in the +command line, for example, +<code>image_filters.exe my_image.bmp</code></p></td></tr></tbody></table> + + +<table class="tbl" width="640px" border="0" cellpadding="5px" +cellspacing="1px"> +<tbody><tr><th>Screenshot</th><th>Source Code and Description</th><th>Executable</th> +</tr><tr><td><a href="http://www.antigrain.com/demo/examples.jpg"><img +src="original_demos_files/examples_s.jpg" title="Click to enlarge" +border="0"></a></td><td style="text-align: justify;"><b>All examples in +one package</b></td><td><a +href="http://www.antigrain.com/demo/examples.zip"><img +src="original_demos_files/dl_win32.gif" border="0"></a><br> +<a href="http://www.antigrain.com/demo/examples.tar.gz"><img +src="original_demos_files/dl_linux.gif" border="0"></a><br> +<a href="http://www.antigrain.com/demo/examples_sgi.tar.gz"><img +src="original_demos_files/dl_irix64.gif" border="0"></a><br> +<a href="http://www.antigrain.com/demo/examples_sun.tar.gz"><img +src="original_demos_files/dl_sunos.gif" border="0"></a><br> +<a href="http://www.antigrain.com/demo/examples_amiga.tar.gz"><img +src="original_demos_files/dl_amigaos.gif" border="0"></a><br></td></tr> +<tr><td><a href="http://www.antigrain.com/demo/lion.png"><img +src="original_demos_files/lion_s.png" title="Click to enlarge" +border="0"></a></td><td style="text-align: justify;"><a +name="PAGE_DEMO_lion"><b></b></a><code><a +href="http://www.antigrain.com/demo/lion.cpp.html">lion.cpp</a></code> +This is the first example I used to implement and debug the +scanline rasterizer, affine transformer, and basic renderers. +You can rotate and scale the “Lion” with the left mouse button. +Right mouse button adds “skewing” transformations, proportional +to the “X” coordinate. The image is drawn over the old one with +a cetrain opacity value. Change “Alpha” to draw funny looking +“lions”. Change window size to clear the window.</td><td><a +href="http://www.antigrain.com/demo/lion.zip"><img +src="original_demos_files/dl_win32.gif" border="0"></a><br> +<a href="http://www.antigrain.com/demo/lion.tar.gz"><img +src="original_demos_files/dl_linux.gif" border="0"></a><br> +<a href="http://www.antigrain.com/demo/lion_sgi.tar.gz"><img +src="original_demos_files/dl_irix64.gif" border="0"></a><br> +<a href="http://www.antigrain.com/demo/lion_sun.tar.gz"><img +src="original_demos_files/dl_sunos.gif" border="0"></a><br> +<a href="http://www.antigrain.com/demo/lion_amiga.gz"><img +src="original_demos_files/dl_amigaos.gif" border="0"></a><br></td></tr> +<tr><td><a href="http://www.antigrain.com/demo/idea.gif"><img +src="original_demos_files/idea_s.gif" title="Click to enlarge" +border="0"></a></td><td style="text-align: justify;"><a +name="PAGE_DEMO_idea"><b></b></a> +<code><a href="http://www.antigrain.com/demo/idea.cpp.html">idea.cpp</a></code> +The polygons for this “idea” were taken from the book +"Dynamic HTML in Action" by Eric Schurman. An example of using +Microsoft Direct Animation can be found here: <a +href="http://www.antigrain.com/demo/ideaDA.html"><img +src="original_demos_files/link.gif" border="0">ideaDA.html</a>. +If you use Microsoft Internet Explorer you can compare the quality +of rendering in <b>AGG</b> and Microsoft Direct Animation. Note that +even +when you click "Rotate with High Quality", you will see it “jitters”. +It's because there are actually no <b>Subpixel Accuracy</b> used in the +Microsoft Direct Animation. +In the <b>AGG</b> example, there's no jitter even in the “Draft” (low +quality) mode. +You can see the simulated jittering if you turn on the “Roundoff” mode, +in which there integer pixel coordinated are used. As for the +performance, +note, that the image in <b>AGG</b> is rotated with step of 0.01 degree +(initially), +while in the Direct Animation Example the angle step is 0.1 degree.</td><td><a + href="http://www.antigrain.com/demo/idea.zip"><img +src="original_demos_files/dl_win32.gif" border="0"></a><br> +<a href="http://www.antigrain.com/demo/idea.tar.gz"><img +src="original_demos_files/dl_linux.gif" border="0"></a><br> +<a href="http://www.antigrain.com/demo/idea_sgi.tar.gz"><img +src="original_demos_files/dl_irix64.gif" border="0"></a><br> +<a href="http://www.antigrain.com/demo/idea_sun.tar.gz"><img +src="original_demos_files/dl_sunos.gif" border="0"></a><br> +<a href="http://www.antigrain.com/demo/idea_amiga.gz"><img +src="original_demos_files/dl_amigaos.gif" border="0"></a><br></td></tr> +<tr><td><a href="http://www.antigrain.com/demo/lion_outline.gif"><img +src="original_demos_files/lion_outline_s.gif" title="Click to enlarge" +border="0"></a></td><td style="text-align: justify;"><a +name="PAGE_DEMO_lion_outline"><b></b></a> +<code><a href="http://www.antigrain.com/demo/lion_outline.cpp.html">lion_outline.cpp</a></code> +The example demonstrates my new algorithm of drawing <b>Anti-Aliased</b> +lines. The algorithm works about 2.5 times faster than the scanline +rasterizer but has some restrictions, particularly, line joins can +be only of the “miter” type, and when so called <b>miter limit</b> is +exceded, they are not as accurate as generated by the stroke +converter (<a +href="http://www.antigrain.com/__code/include/agg_conv_stroke.h.html#conv_stroke">conv_stroke</a>). + To see the difference, maximize the window +and try to rotate and scale the “lion” with and without using +the scanline rasterizer (a checkbox at the bottom). The difference +in performance is obvious.</td><td><a +href="http://www.antigrain.com/demo/lion_outline.zip"><img +src="original_demos_files/dl_win32.gif" border="0"></a><br> +<a href="http://www.antigrain.com/demo/lion_outline.tar.gz"><img +src="original_demos_files/dl_linux.gif" border="0"></a><br> +<a href="http://www.antigrain.com/demo/lion_outline_sgi.tar.gz"><img +src="original_demos_files/dl_irix64.gif" border="0"></a><br> +<a href="http://www.antigrain.com/demo/lion_outline_sun.tar.gz"><img +src="original_demos_files/dl_sunos.gif" border="0"></a><br> +<a href="http://www.antigrain.com/demo/lion_outline_amiga.gz"><img +src="original_demos_files/dl_amigaos.gif" border="0"></a><br></td></tr> +<tr><td><a href="http://www.antigrain.com/demo/aa_demo.gif"><img +src="original_demos_files/aa_demo_s.gif" title="Click to enlarge" +border="0"></a></td><td style="text-align: justify;"><a +name="PAGE_DEMO_aa_demo"><b></b></a> +<code><a href="http://www.antigrain.com/demo/aa_demo.cpp.html">aa_demo.cpp</a></code> +Demonstration of the <b><nobr>Anti-Aliasing</nobr></b> principle with <b>Subpixel + Accuracy</b>. The triangle is +rendered two times, with its “natural” size (at the bottom-left) +and enlarged. To draw the enlarged version there is a special scanline +renderer was written (see class renderer_enlarged in the source code). +You can drag the whole triangle as well as each vertex of it. Also +change “Gamma” to see how it affects the quality of <b><nobr>Anti-Aliasing</nobr></b>.</td><td><a + href="http://www.antigrain.com/demo/aa_demo.zip"><img +src="original_demos_files/dl_win32.gif" border="0"></a><br> +<a href="http://www.antigrain.com/demo/aa_demo.tar.gz"><img +src="original_demos_files/dl_linux.gif" border="0"></a><br> +<a href="http://www.antigrain.com/demo/aa_demo_sgi.tar.gz"><img +src="original_demos_files/dl_irix64.gif" border="0"></a><br> +<a href="http://www.antigrain.com/demo/aa_demo_sun.tar.gz"><img +src="original_demos_files/dl_sunos.gif" border="0"></a><br> +<a href="http://www.antigrain.com/demo/aa_demo_amiga.gz"><img +src="original_demos_files/dl_amigaos.gif" border="0"></a><br></td></tr> +<tr><td><a href="http://www.antigrain.com/demo/gamma_correction.gif"><img + src="original_demos_files/gamma_correction_s.gif" title="Click to +enlarge" border="0"></a></td><td style="text-align: justify;"><a +name="PAGE_DEMO_gamma_correction"><b></b></a> +<code><a href="http://www.antigrain.com/demo/gamma_correction.cpp.html">gamma_correction.cpp</a></code> +<b><nobr>Anti-Aliasing</nobr></b> is very tricky because everything +depends. Particularly, +having straight linear dependence <b>“pixel coverage”</b> <span +class="larger">→</span> +<b>“brightness”</b> may be not the best. +It depends on the type of display (CRT, LCD), contrast, +<nobr>black-on-white</nobr> vs <nobr>white-on-black</nobr>, it even +depends on your +personal vision. There are no linear dependencies in this World. +This example demonstrates the importance of so called <b>Gamma +Correction</b> in <b><nobr>Anti-Aliasing</nobr></b>. There a traditional + <b>power</b> function is used, +in terms of <b>C++</b> it's <code>brighness = pow(brighness, gamma)</code>. + Change +“Gamma” and see how the quality changes. Note, that if you improve +the quality on the white side, it becomes worse on the black side and +vice versa.</td><td><a +href="http://www.antigrain.com/demo/gamma_correction.zip"><img +src="original_demos_files/dl_win32.gif" border="0"></a><br> +<a href="http://www.antigrain.com/demo/gamma_correction.tar.gz"><img +src="original_demos_files/dl_linux.gif" border="0"></a><br> +<a href="http://www.antigrain.com/demo/gamma_correction_sgi.tar.gz"><img + src="original_demos_files/dl_irix64.gif" border="0"></a><br> +<a href="http://www.antigrain.com/demo/gamma_correction_sun.tar.gz"><img + src="original_demos_files/dl_sunos.gif" border="0"></a><br> +<a href="http://www.antigrain.com/demo/gamma_correction_amiga.gz"><img +src="original_demos_files/dl_amigaos.gif" border="0"></a><br></td></tr> +<tr><td><a href="http://www.antigrain.com/demo/gamma_ctrl.gif"><img +src="original_demos_files/gamma_ctrl_s.gif" title="Click to enlarge" +border="0"></a></td><td style="text-align: justify;"><a +name="PAGE_DEMO_gamma_ctrl"><b></b></a> +<code><a href="http://www.antigrain.com/demo/gamma_ctrl.cpp.html">gamma_ctrl.cpp</a></code> +This is another experiment with gamma correction. +See also <a +href="http://www.antigrain.com/research/gamma_correction/index.html#PAGE_GAMMA_CORRECTION">Gamma + Correction</a>. I presumed that we can do better +than with a traditional power function. So, I created a +special control to have an arbitrary gamma function. The conclusion +is that we can really achieve a better visual result with this control, +but still, in practice, the traditional <b>power function</b> is good +enough +too.</td><td><a href="http://www.antigrain.com/demo/gamma_ctrl.zip"><img + src="original_demos_files/dl_win32.gif" border="0"></a><br> +<a href="http://www.antigrain.com/demo/gamma_ctrl.tar.gz"><img +src="original_demos_files/dl_linux.gif" border="0"></a><br> +<a href="http://www.antigrain.com/demo/gamma_ctrl_sgi.tar.gz"><img +src="original_demos_files/dl_irix64.gif" border="0"></a><br> +<a href="http://www.antigrain.com/demo/gamma_ctrl_sun.tar.gz"><img +src="original_demos_files/dl_sunos.gif" border="0"></a><br> +<a href="http://www.antigrain.com/demo/gamma_ctrl_amiga.gz"><img +src="original_demos_files/dl_amigaos.gif" border="0"></a><br></td></tr> +<tr><td><a href="http://www.antigrain.com/demo/rounded_rect.gif"><img +src="original_demos_files/rounded_rect_s.gif" title="Click to enlarge" +border="0"></a></td><td style="text-align: justify;"><a +name="PAGE_DEMO_rounded_rect"><b></b></a> +<code><a href="http://www.antigrain.com/demo/rounded_rect.cpp.html">rounded_rect.cpp</a></code> +Yet another example dedicated to Gamma Correction. +If you have a CRT monitor: The rectangle looks bad - the rounded corners + are +thicker than its side lines. First try to drag the <b>“subpixel offset”</b> + +control — it simply adds some fractional value to the coordinates. When +dragging +you will see that the rectangle is "blinking". Then increase <b>“Gamma”</b> + +to about 1.5. The result will look almost perfect — the visual thickness + of +the rectangle remains the same. That's good, but turn the checkbox +<b>“White on black”</b> on — what do we see? Our rounded rectangle looks + terrible. +Drag the <b>“subpixel offset”</b> slider — it's blinking as hell. +Now decrease "Gamma" to about 0.6. What do we see now? Perfect result! +If you use an LCD monitor, the good value of gamma will be closer to 1.0 + in +both cases — black on white or white on black. There's no perfection in +this +world, but at least you can control Gamma in <b><nobr>Anti-Grain</nobr> +Geometry</b> :-)</td><td><a +href="http://www.antigrain.com/demo/rounded_rect.zip"><img +src="original_demos_files/dl_win32.gif" border="0"></a><br> +<a href="http://www.antigrain.com/demo/rounded_rect.tar.gz"><img +src="original_demos_files/dl_linux.gif" border="0"></a><br> +<a href="http://www.antigrain.com/demo/rounded_rect_sgi.tar.gz"><img +src="original_demos_files/dl_irix64.gif" border="0"></a><br> +<a href="http://www.antigrain.com/demo/rounded_rect_sun.tar.gz"><img +src="original_demos_files/dl_sunos.gif" border="0"></a><br> +<a href="http://www.antigrain.com/demo/rounded_rect_amiga.gz"><img +src="original_demos_files/dl_amigaos.gif" border="0"></a><br></td></tr> +<tr><td><a href="http://www.antigrain.com/demo/gamma_tuner.png"><img +src="original_demos_files/gamma_tuner_s.png" title="Click to enlarge" +border="0"></a></td><td style="text-align: justify;"><a +name="PAGE_DEMO_gamma_tuner"><b></b></a> +<code><a href="http://www.antigrain.com/demo/gamma_tuner.cpp.html">gamma_tuner.cpp</a></code> +Yet another gamma tuner. Set gamma value with the slider, and then +try to tune your monitor so that the vertical strips would be +almost invisible.</td><td><a +href="http://www.antigrain.com/demo/gamma_tuner.zip"><img +src="original_demos_files/dl_win32.gif" border="0"></a><br></td></tr> +<tr><td><a href="http://www.antigrain.com/demo/rasterizers.gif"><img +src="original_demos_files/rasterizers_s.gif" title="Click to enlarge" +border="0"></a></td><td style="text-align: justify;"><a +name="PAGE_DEMO_rasterizers"><b></b></a> +<code><a href="http://www.antigrain.com/demo/rasterizers.cpp.html">rasterizers.cpp</a></code> +It's a very simple example that was written to compare the performance +between Anti-Aliased and regular polygon filling. It appears that the +most +expensive operation is rendering of horizontal scanlines. So that, +we can use the very same rasterization algorithm to draw regular, +aliased +polygons. Of course, it's possible to write a special version of the +rasterizer +that will work faster, but won't calculate the pixel coverage values. +But +on the other hand, the existing version of the <a +href="http://www.antigrain.com/__code/include/agg_rasterizer_scanline_aa.h.html#rasterizer_scanline_aa">rasterizer_scanline_aa</a> + allows +you to change gamma, and to "dilate" or "shrink" the polygons in range +of <span class="larger">±</span> 1 +pixel. As usual, you can drag the triangles as well as the vertices of +them. +Compare the performance with different shapes and opacity.</td><td><a +href="http://www.antigrain.com/demo/rasterizers.zip"><img +src="original_demos_files/dl_win32.gif" border="0"></a><br> +<a href="http://www.antigrain.com/demo/rasterizers.tar.gz"><img +src="original_demos_files/dl_linux.gif" border="0"></a><br> +<a href="http://www.antigrain.com/demo/rasterizers_sgi.tar.gz"><img +src="original_demos_files/dl_irix64.gif" border="0"></a><br> +<a href="http://www.antigrain.com/demo/rasterizers_sun.tar.gz"><img +src="original_demos_files/dl_sunos.gif" border="0"></a><br> +<a href="http://www.antigrain.com/demo/rasterizers_amiga.gz"><img +src="original_demos_files/dl_amigaos.gif" border="0"></a><br></td></tr> +<tr><td><a href="http://www.antigrain.com/demo/rasterizers2.gif"><img +src="original_demos_files/rasterizers2_s.gif" title="Click to enlarge" +border="0"></a></td><td style="text-align: justify;"><a +name="PAGE_DEMO_rasterizers2"><b></b></a> +<code><a href="http://www.antigrain.com/demo/rasterizers2.cpp.html">rasterizers2.cpp</a></code> +More complex example demostrating different rasterizers. Here you can +see how the +<b>outline</b> rasterizer works, and how to use an image as the line +pattern. This +capability can be very useful to draw geographical maps.</td><td><a +href="http://www.antigrain.com/demo/rasterizers2.zip"><img +src="original_demos_files/dl_win32.gif" border="0"></a><br> +<a href="http://www.antigrain.com/demo/rasterizers2.tar.gz"><img +src="original_demos_files/dl_linux.gif" border="0"></a><br> +<a href="http://www.antigrain.com/demo/rasterizers2_sgi.tar.gz"><img +src="original_demos_files/dl_irix64.gif" border="0"></a><br> +<a href="http://www.antigrain.com/demo/rasterizers2_sun.tar.gz"><img +src="original_demos_files/dl_sunos.gif" border="0"></a><br> +<a href="http://www.antigrain.com/demo/rasterizers2_amiga.gz"><img +src="original_demos_files/dl_amigaos.gif" border="0"></a><br></td></tr> +<tr><td><a href="http://www.antigrain.com/demo/component_rendering.gif"><img + src="original_demos_files/component_rendering_s.gif" title="Click to +enlarge" border="0"></a></td><td style="text-align: justify;"><a +name="PAGE_DEMO_component_rendering"><b></b></a> +<code><a +href="http://www.antigrain.com/demo/component_rendering.cpp.html">component_rendering.cpp</a></code> +<b>AGG</b> has a gray-scale renderer that can use any 8-bit color +channel of an +RGB or RGBA frame buffer. Most likely it will be used to draw gray-scale + +images directly in the alpha-channel.</td><td><a +href="http://www.antigrain.com/demo/component_rendering.zip"><img +src="original_demos_files/dl_win32.gif" border="0"></a><br> +<a href="http://www.antigrain.com/demo/component_rendering.tar.gz"><img +src="original_demos_files/dl_linux.gif" border="0"></a><br> +<a href="http://www.antigrain.com/demo/component_rendering_sgi.tar.gz"><img + src="original_demos_files/dl_irix64.gif" border="0"></a><br> +<a href="http://www.antigrain.com/demo/component_rendering_sun.tar.gz"><img + src="original_demos_files/dl_sunos.gif" border="0"></a><br> +<a href="http://www.antigrain.com/demo/component_rendering_amiga.gz"><img + src="original_demos_files/dl_amigaos.gif" border="0"></a><br></td></tr> +<tr><td><a href="http://www.antigrain.com/demo/polymorphic_renderer.gif"><img + src="original_demos_files/polymorphic_renderer_s.gif" title="Click to +enlarge" border="0"></a></td><td style="text-align: justify;"><a +name="PAGE_DEMO_polymorphic_renderer"><b></b></a> +<code><a +href="http://www.antigrain.com/demo/polymorphic_renderer.cpp.html">polymorphic_renderer.cpp</a></code> +There's nothing looking effective. <b>AGG</b> has renderers for +different pixel formats +in memory, particularly, for different byte order (RGB or BGR). +But the renderers are class templates, where byte order is defined +at the compile time. It's done for the sake of performance and in most +cases it fits all your needs. Still, if you need to switch between +different pixel formats dynamically, you can write a simple polymorphic +class wrapper, like the one in this example.</td><td><a +href="http://www.antigrain.com/demo/polymorphic_renderer.zip"><img +src="original_demos_files/dl_win32.gif" border="0"></a><br> +<a href="http://www.antigrain.com/demo/polymorphic_renderer.tar.gz"><img + src="original_demos_files/dl_linux.gif" border="0"></a><br> +<a href="http://www.antigrain.com/demo/polymorphic_renderer_sgi.tar.gz"><img + src="original_demos_files/dl_irix64.gif" border="0"></a><br> +<a href="http://www.antigrain.com/demo/polymorphic_renderer_sun.tar.gz"><img + src="original_demos_files/dl_sunos.gif" border="0"></a><br> +<a href="http://www.antigrain.com/demo/polymorphic_renderer_amiga.gz"><img + src="original_demos_files/dl_amigaos.gif" border="0"></a><br></td></tr> +<tr><td><a href="http://www.antigrain.com/demo/gouraud.png"><img +src="original_demos_files/gouraud_s.png" title="Click to enlarge" +border="0"></a></td><td style="text-align: justify;"><a +name="PAGE_DEMO_gouraud"><b></b></a> +<code><a href="http://www.antigrain.com/demo/gouraud.cpp.html">gouraud.cpp</a></code> +Gouraud shading. It's a simple method of interpolating colors in a +triangle. +There's no “cube” drawn, there're just 6 triangles. +You define a triangle and colors in its vertices. When rendering, the +colors will be linearly interpolated. But there's a problem that appears + when +drawing adjacent triangles with <b><nobr>Anti-Aliasing</nobr></b>. +Anti-Aliased polygons do not "dock" to +each other correctly, there visual artifacts at the edges appear. I call + it +“the problem of adjacent edges”. <b>AGG</b> has a simple mechanism that +allows you +to get rid of the artifacts, just dilating the polygons and/or changing +the gamma-correction value. But it's tricky, because the values depend +on the opacity of the polygons. In this example you can change the +opacity, +the dilation value and gamma. Also you can drag the Red, Green and Blue +corners of the “cube”.</td><td><a +href="http://www.antigrain.com/demo/gouraud.zip"><img +src="original_demos_files/dl_win32.gif" border="0"></a><br> +<a href="http://www.antigrain.com/demo/gouraud.tar.gz"><img +src="original_demos_files/dl_linux.gif" border="0"></a><br> +<a href="http://www.antigrain.com/demo/gouraud_sgi.tar.gz"><img +src="original_demos_files/dl_irix64.gif" border="0"></a><br> +<a href="http://www.antigrain.com/demo/gouraud_sun.tar.gz"><img +src="original_demos_files/dl_sunos.gif" border="0"></a><br> +<a href="http://www.antigrain.com/demo/gouraud_amiga.gz"><img +src="original_demos_files/dl_amigaos.gif" border="0"></a><br></td></tr> +<tr><td><a href="http://www.antigrain.com/demo/gradients.png"><img +src="original_demos_files/gradients_s.png" title="Click to enlarge" +border="0"></a></td><td style="text-align: justify;"><a +name="PAGE_DEMO_gradients"><b></b></a> +<code><a href="http://www.antigrain.com/demo/gradients.cpp.html">gradients.cpp</a></code> +This “sphere” is rendered with color gradients only. Initially there was + an idea +to compensate so called <a +href="http://www.cquest.utoronto.ca/psych/psy280f/ch3/mb/mb.html"><img +src="original_demos_files/link.gif" border="0">Mach Bands effect</a>. To + do so I added a gradient profile functor. +Then the concept was extended to set a color profile. As a result you +can +render simple geometrical objects in 2D looking like 3D ones. +In this example you can construct your own color profile and select the +gradient +function. There're not so many gradient functions in <b>AGG</b>, but you + can easily +add your own. Also, drag the “gradient” with the left mouse button, +scale and +rotate it with the right one.</td><td><a +href="http://www.antigrain.com/demo/gradients.zip"><img +src="original_demos_files/dl_win32.gif" border="0"></a><br> +<a href="http://www.antigrain.com/demo/gradients.tar.gz"><img +src="original_demos_files/dl_linux.gif" border="0"></a><br> +<a href="http://www.antigrain.com/demo/gradients_sgi.tar.gz"><img +src="original_demos_files/dl_irix64.gif" border="0"></a><br> +<a href="http://www.antigrain.com/demo/gradients_sun.tar.gz"><img +src="original_demos_files/dl_sunos.gif" border="0"></a><br> +<a href="http://www.antigrain.com/demo/gradients_amiga.gz"><img +src="original_demos_files/dl_amigaos.gif" border="0"></a><br></td></tr> +<tr><td><a href="http://www.antigrain.com/demo/gradient_focal.png"><img +src="original_demos_files/gradient_focal_s.png" title="Click to enlarge" + border="0"></a></td><td style="text-align: justify;"><a +name="PAGE_DEMO_gradient_focal"><b></b></a> +<code><a href="http://www.antigrain.com/demo/gradient_focal.cpp.html">gradient_focal.cpp</a></code> +This demo evolved from testing code and performance measurements. +In particular, it shows you how to calculate +the parameters of a radial gradient with a separate focal point, +considering +arbitrary affine transformations. In this example window resizing +transformations are taken into account. It also demonstrates the use +case +of <a +href="http://www.antigrain.com/__code/include/agg_gradient_lut.h.html#gradient_lut">gradient_lut</a> + and gamma correction.</td><td><a +href="http://www.antigrain.com/demo/gradient_focal.zip"><img +src="original_demos_files/dl_win32.gif" border="0"></a><br></td></tr> +<tr><td><a href="http://www.antigrain.com/demo/conv_contour.gif"><img +src="original_demos_files/conv_contour_s.gif" title="Click to enlarge" +border="0"></a></td><td style="text-align: justify;"><a +name="PAGE_DEMO_conv_contour"><b></b></a> +<code><a href="http://www.antigrain.com/demo/conv_contour.cpp.html">conv_contour.cpp</a></code> +One of the converters in <b>AGG</b> is <a +href="http://www.antigrain.com/__code/include/agg_conv_contour.h.html#conv_contour">conv_contour</a>. + It allows you to +extend or shrink polygons. Initially, it was implemented to eliminate +the “problem of adjacent edges” in the <a +href="http://www.antigrain.com/svg/index.html#PAGE_SVG">SVG Viewer</a>, +but it can be +very useful in many other applications, for example, to change +the font weight on the fly. The trick here is that the sign (dilation +or shrinking) depends on the vertex order - clockwise or +counterclockwise. +In the <a +href="http://www.antigrain.com/__code/include/agg_conv_contour.h.html#conv_contour">conv_contour</a> + you can control the behavior. Sometimes you need to +preserve the dilation regardless of the initial orientation, sometimes +it should depend on the orientation. The glyph ‘<b>a</b>’ has +a “hole” whose orientation differs from the main contour. To change +the “weight” correctly, you need to keep the orientation as it is +originally defined. If you turn “Autodetect orientation…” on, +the glyph will be extended or shrinked incorrectly. The radio buttons +control the orientation flad assigned to all polygons. “Close” doesn't +add the flag, “Close CW” and “Close CCW” add “clockwise” or +“counterclockwise” flag respectively. Note, that the actual order +of vertices remains the same, the flag is being added despite of the +real orientation. Try to play with it.</td><td><a +href="http://www.antigrain.com/demo/conv_contour.zip"><img +src="original_demos_files/dl_win32.gif" border="0"></a><br> +<a href="http://www.antigrain.com/demo/conv_contour.tar.gz"><img +src="original_demos_files/dl_linux.gif" border="0"></a><br> +<a href="http://www.antigrain.com/demo/conv_contour_sgi.tar.gz"><img +src="original_demos_files/dl_irix64.gif" border="0"></a><br> +<a href="http://www.antigrain.com/demo/conv_contour_sun.tar.gz"><img +src="original_demos_files/dl_sunos.gif" border="0"></a><br> +<a href="http://www.antigrain.com/demo/conv_contour_amiga.gz"><img +src="original_demos_files/dl_amigaos.gif" border="0"></a><br></td></tr> +<tr><td><a href="http://www.antigrain.com/demo/conv_dash_marker.gif"><img + src="original_demos_files/conv_dash_marker_s.gif" title="Click to +enlarge" border="0"></a></td><td style="text-align: justify;"><a +name="PAGE_DEMO_conv_dash_marker"><b></b></a> +<code><a href="http://www.antigrain.com/demo/conv_dash_marker.cpp.html">conv_dash_marker.cpp</a></code> +The example demonstrates rather a complex pipeline that consists of +diffrerent converters, particularly, of the dash generator, marker +generator, and of course, the stroke converter. There is also a +converter that allows you to draw smooth curves based on polygons, +see <a +href="http://www.antigrain.com/research/bezier_interpolation/index.html#PAGE_BEZIER_INTERPOLATION">Interpolation + with Bezier Curves</a>. You can drag the three vertices of +the “main” triangle.</td><td><a +href="http://www.antigrain.com/demo/conv_dash_marker.zip"><img +src="original_demos_files/dl_win32.gif" border="0"></a><br> +<a href="http://www.antigrain.com/demo/conv_dash_marker.tar.gz"><img +src="original_demos_files/dl_linux.gif" border="0"></a><br> +<a href="http://www.antigrain.com/demo/conv_dash_marker_sgi.tar.gz"><img + src="original_demos_files/dl_irix64.gif" border="0"></a><br> +<a href="http://www.antigrain.com/demo/conv_dash_marker_sun.tar.gz"><img + src="original_demos_files/dl_sunos.gif" border="0"></a><br> +<a href="http://www.antigrain.com/demo/conv_dash_marker_amiga.gz"><img +src="original_demos_files/dl_amigaos.gif" border="0"></a><br></td></tr> +<tr><td><a href="http://www.antigrain.com/demo/conv_stroke.gif"><img +src="original_demos_files/conv_stroke_s.gif" title="Click to enlarge" +border="0"></a></td><td style="text-align: justify;"><a +name="PAGE_DEMO_conv_stroke"><b></b></a> +<code><a href="http://www.antigrain.com/demo/conv_stroke.cpp.html">conv_stroke.cpp</a></code> +Another example that demonstrates the power of the custom pipeline +concept. First, we calculate a thick outline (stroke), then generate +dashes, and then, calculate the outlines (strokes) of the dashes +again. Drag the verices as in the previous example.</td><td><a +href="http://www.antigrain.com/demo/conv_stroke.zip"><img +src="original_demos_files/dl_win32.gif" border="0"></a><br> +<a href="http://www.antigrain.com/demo/conv_stroke.tar.gz"><img +src="original_demos_files/dl_linux.gif" border="0"></a><br> +<a href="http://www.antigrain.com/demo/conv_stroke_sgi.tar.gz"><img +src="original_demos_files/dl_irix64.gif" border="0"></a><br> +<a href="http://www.antigrain.com/demo/conv_stroke_sun.tar.gz"><img +src="original_demos_files/dl_sunos.gif" border="0"></a><br> +<a href="http://www.antigrain.com/demo/conv_stroke_amiga.gz"><img +src="original_demos_files/dl_amigaos.gif" border="0"></a><br></td></tr> +<tr><td><a href="http://www.antigrain.com/demo/mol_view.gif"><img +src="original_demos_files/mol_view_s.gif" title="Click to enlarge" +border="0"></a></td><td style="text-align: justify;"><a +name="PAGE_DEMO_mol_view"><b></b></a> +<code><a href="http://www.antigrain.com/demo/mol_view.cpp.html">mol_view.cpp</a></code> +This is rather a complex but effective example that renders +2D organic molecules from the popular MDL Molecule Format (SDF). +Press the left mouse button to rotate and scale the molecule, +and the right one to drag it. PageUp, PageDown keys switch +between the molecules in the file. Look at the performance, +and note, that the molecules are being drawn from scratch +every time you change anything.<br> +A little note for chemists. There's no ring perception +is done, so that, the double bonds in rings are drawn +incorrectly, but understandable. Also note, that +even very complex molecules with macrocycles, +drawn in limited space still remain consistent +and recognizable.</td><td><a +href="http://www.antigrain.com/demo/mol_view.zip"><img +src="original_demos_files/dl_win32.gif" border="0"></a><br> +<a href="http://www.antigrain.com/demo/mol_view.tar.gz"><img +src="original_demos_files/dl_linux.gif" border="0"></a><br> +<a href="http://www.antigrain.com/demo/mol_view_sgi.tar.gz"><img +src="original_demos_files/dl_irix64.gif" border="0"></a><br> +<a href="http://www.antigrain.com/demo/mol_view_sun.tar.gz"><img +src="original_demos_files/dl_sunos.gif" border="0"></a><br> +<a href="http://www.antigrain.com/demo/mol_view_amiga.gz"><img +src="original_demos_files/dl_amigaos.gif" border="0"></a><br></td></tr> +<tr><td><a href="http://www.antigrain.com/demo/alpha_mask.gif"><img +src="original_demos_files/alpha_mask_s.gif" title="Click to enlarge" +border="0"></a></td><td style="text-align: justify;"><a +name="PAGE_DEMO_alpha_mask"><b></b></a> +<code><a href="http://www.antigrain.com/demo/alpha_mask.cpp.html">alpha_mask.cpp</a></code> +Alpha-mask is a simple method of clipping and masking +polygons to a number of other arbitrary polygons. Alpha mask +is a buffer that is mixed to the scanline container and controls +the <b><nobr>Anti-Aliasing</nobr></b> values in it. It's not the perfect + mechanism of clipping, +but it allows you not only to clip the polygons, but also to +change the opacity in certain areas, i.e., the clipping can be +translucent. Press and drag the left mouse button to scale and +rotate the “lion”, resize the window to grnerate new alpha-mask.</td><td><a + href="http://www.antigrain.com/demo/alpha_mask.zip"><img +src="original_demos_files/dl_win32.gif" border="0"></a><br> +<a href="http://www.antigrain.com/demo/alpha_mask.tar.gz"><img +src="original_demos_files/dl_linux.gif" border="0"></a><br> +<a href="http://www.antigrain.com/demo/alpha_mask_sgi.tar.gz"><img +src="original_demos_files/dl_irix64.gif" border="0"></a><br> +<a href="http://www.antigrain.com/demo/alpha_mask_sun.tar.gz"><img +src="original_demos_files/dl_sunos.gif" border="0"></a><br> +<a href="http://www.antigrain.com/demo/alpha_mask_amiga.gz"><img +src="original_demos_files/dl_amigaos.gif" border="0"></a><br></td></tr> +<tr><td><a href="http://www.antigrain.com/demo/alpha_mask2.jpg"><img +src="original_demos_files/alpha_mask2_s.jpg" title="Click to enlarge" +border="0"></a></td><td style="text-align: justify;"><a +name="PAGE_DEMO_alpha_mask2"><b></b></a> +<code><a href="http://www.antigrain.com/demo/alpha_mask2.cpp.html">alpha_mask2.cpp</a></code> +Another example of alpha-masking. In the previous example +the alpha-mask is applied to the scan line container with +unpacked data (scanline_u), while in this one there a special +adapter of a pixel format renderer is used (<a +href="http://www.antigrain.com/doc/basic_renderers/basic_renderers.agdoc.html#pixfmt_amask_adaptor">pixfmt_amask_adaptor</a>). +It + allows you to use the alpha-mask with all possible primitives +and renderers. Besides, if the alpha-mask buffer is of the same +size as the main rendering buffer (usually it is) we don't have +to perform clipping for the alpha-mask, because all the primitives +are already clipped at the higher level, see class <a +href="http://www.antigrain.com/__code/include/agg_alpha_mask_u8.h.html#amask_no_clip_u8">amask_no_clip_u8</a>. +Press and drag the left mouse button to scale and rotate the “lion” +and generate a new set of other primitives, change the <b>“N”</b> +value to generate a new set of masking ellipses.</td><td><a +href="http://www.antigrain.com/demo/alpha_mask2.zip"><img +src="original_demos_files/dl_win32.gif" border="0"></a><br> +<a href="http://www.antigrain.com/demo/alpha_mask2_amiga.gz"><img +src="original_demos_files/dl_amigaos.gif" border="0"></a><br></td></tr> +<tr><td><a href="http://www.antigrain.com/demo/alpha_mask3.gif"><img +src="original_demos_files/alpha_mask3_s.gif" title="Click to enlarge" +border="0"></a></td><td style="text-align: justify;"><a +name="PAGE_DEMO_alpha_mask3"><b></b></a> +<code><a href="http://www.antigrain.com/demo/alpha_mask3.cpp.html">alpha_mask3.cpp</a></code> +Yet another example of alpha-masking. It simulates arbitrary +polygon clipping similar to <a +href="http://www.antigrain.com/demo/gpc_test.cpp.html">gpc_test.cpp</a>. + Alpha-Masking +allows you to perform only the Intersection (AND) and +Difference (SUB) operations, but works much faster that +<a +href="http://www.antigrain.com/__code/include/agg_conv_gpc.h.html#conv_gpc">conv_gpc</a>. + Actually, there're different compexities and +different dependencies. The performance of <a +href="http://www.antigrain.com/__code/include/agg_conv_gpc.h.html#conv_gpc">conv_gpc</a> + depends on +the number of vertices, while Alpha-Masking depends on the +area of the rendered polygons. Still, with typical screen +resolutions, Alpha-Masking works much faster than <a +href="http://www.cs.man.ac.uk/aig/staff/alan/software/"><img +src="original_demos_files/link.gif" border="0"><b><nobr>General Polygon +Clipper</nobr></b></a>. +Compare the timings between <a +href="http://www.antigrain.com/demo/alpha_mask3.cpp.html">alpha_mask3.cpp</a> + and <a href="http://www.antigrain.com/demo/gpc_test.cpp.html">gpc_test.cpp</a>.</td><td><a + href="http://www.antigrain.com/demo/alpha_mask3.zip"><img +src="original_demos_files/dl_win32.gif" border="0"></a><br> +<a href="http://www.antigrain.com/demo/alpha_mask3_amiga.gz"><img +src="original_demos_files/dl_amigaos.gif" border="0"></a><br></td></tr> +<tr><td><a href="http://www.antigrain.com/demo/circles.gif"><img +src="original_demos_files/circles_s.gif" title="Click to enlarge" +border="0"></a></td><td style="text-align: justify;"><a +name="PAGE_DEMO_circles"><b></b></a> +<code><a href="http://www.antigrain.com/demo/circles.cpp.html">circles.cpp</a></code> +This example just demonstrates that <b>AGG</b> can be used in different +scatter plot apllications. There's a number of small circles drawn. You +can +change the parameters of drawing, watching for the performance and +the number of circles simultaneously rendered. Press the left mouse +button +to generate a new set of points. Press the right mouse +button to make the points randomly change their coordinates. Note, that +the circles are drawn with high quality, possibly translucent, and +with subpixel accuracy.</td><td><a +href="http://www.antigrain.com/demo/circles.zip"><img +src="original_demos_files/dl_win32.gif" border="0"></a><br> +<a href="http://www.antigrain.com/demo/circles.tar.gz"><img +src="original_demos_files/dl_linux.gif" border="0"></a><br> +<a href="http://www.antigrain.com/demo/circles_sgi.tar.gz"><img +src="original_demos_files/dl_irix64.gif" border="0"></a><br> +<a href="http://www.antigrain.com/demo/circles_sun.tar.gz"><img +src="original_demos_files/dl_sunos.gif" border="0"></a><br> +<a href="http://www.antigrain.com/demo/circles_amiga.gz"><img +src="original_demos_files/dl_amigaos.gif" border="0"></a><br></td></tr> +<tr><td><a href="http://www.antigrain.com/demo/graph_test.gif"><img +src="original_demos_files/graph_test_s.gif" title="Click to enlarge" +border="0"></a></td><td style="text-align: justify;"><a +name="PAGE_DEMO_graph_test"><b></b></a> +<img src="original_demos_files/gdip_curves.gif" title="" +style="border-color: rgb(255, 255, 255);" align="right" border="4"><!----> +<code><a href="http://www.antigrain.com/demo/graph_test.cpp.html">graph_test.cpp</a></code> +Yet another example of the "general" kind. It was used mostly +to compare the performance of different steps of rendering in order +to see the weaknesses. The WIn GDI+ analog of it looks worse and +works slower. Try <a +href="http://www.antigrain.com/demo/GDI_graph_test.zip"><img +src="original_demos_files/download.gif" border="0"> (GDI_graph_test.zip)</a> + and compare it with +the <b>AGG</b> one. The most disappointing thing in GDI+ is that it +cannot draw Bezier curves correctly. Run the GDI+ example, choose +menu <b>Image/Bezier curves</b>, expand the window to about 1000x1000 +pixels, +and then gradually change the size of the window. You will see that some +curves miss the destination points (the centers of the node circles). +That looks really ridiculous, so, I overcame my laziness and made an +animated +GIF of 5 screenshots.</td><td><a +href="http://www.antigrain.com/demo/graph_test.zip"><img +src="original_demos_files/dl_win32.gif" border="0"></a><br> +<a href="http://www.antigrain.com/demo/graph_test.tar.gz"><img +src="original_demos_files/dl_linux.gif" border="0"></a><br> +<a href="http://www.antigrain.com/demo/graph_test_sgi.tar.gz"><img +src="original_demos_files/dl_irix64.gif" border="0"></a><br> +<a href="http://www.antigrain.com/demo/graph_test_sun.tar.gz"><img +src="original_demos_files/dl_sunos.gif" border="0"></a><br> +<a href="http://www.antigrain.com/demo/graph_test_amiga.gz"><img +src="original_demos_files/dl_amigaos.gif" border="0"></a><br></td></tr> +<tr><td><a href="http://www.antigrain.com/demo/multi_clip.png"><img +src="original_demos_files/multi_clip_s.gif" title="Click to enlarge" +border="0"></a></td><td style="text-align: justify;"><a +name="PAGE_DEMO_multi_clip"><b></b></a> +<code><a href="http://www.antigrain.com/demo/multi_clip.cpp.html">multi_clip.cpp</a></code> +A testing example that demonstrates clipping to multiple rectangular +regions. It's a low-level (pixel) clipping that can be useful to +draw images clipped to a complex region with orthogonal boundaries. +It can be useful in some window interfaces that use a custom mechanism +to draw window content. The example uses all possible rendering +mechanisms.</td><td><a +href="http://www.antigrain.com/demo/multi_clip.zip"><img +src="original_demos_files/dl_win32.gif" border="0"></a><br> +<a href="http://www.antigrain.com/demo/multi_clip.tar.gz"><img +src="original_demos_files/dl_linux.gif" border="0"></a><br> +<a href="http://www.antigrain.com/demo/multi_clip_sgi.tar.gz"><img +src="original_demos_files/dl_irix64.gif" border="0"></a><br> +<a href="http://www.antigrain.com/demo/multi_clip_sun.tar.gz"><img +src="original_demos_files/dl_sunos.gif" border="0"></a><br> +<a href="http://www.antigrain.com/demo/multi_clip_amiga.gz"><img +src="original_demos_files/dl_amigaos.gif" border="0"></a><br></td></tr> +<tr><td><a href="http://www.antigrain.com/demo/perspective.gif"><img +src="original_demos_files/perspective_s.gif" title="Click to enlarge" +border="0"></a></td><td style="text-align: justify;"><a +name="PAGE_DEMO_perspective"><b></b></a> +<code><a href="http://www.antigrain.com/demo/perspective.cpp.html">perspective.cpp</a></code> +Perspective and bilinear transformations. In general, +these classes can transform an arbitrary quadrangle to another +arbitrary quadrangle (with some restrictions). The example +demonstrates how to transform a rectangle to a quadrangle defined +by 4 vertices. You can drag the 4 corners of the quadrangle, as well +as its boundaries. Note, that the perspective transformations don't +work correctly if the destination quadrangle is concave. Bilinear +thansformations give a different result, but remain valid with any +shape of the destination quadrangle.</td><td><a +href="http://www.antigrain.com/demo/perspective.zip"><img +src="original_demos_files/dl_win32.gif" border="0"></a><br> +<a href="http://www.antigrain.com/demo/perspective.tar.gz"><img +src="original_demos_files/dl_linux.gif" border="0"></a><br> +<a href="http://www.antigrain.com/demo/perspective_sgi.tar.gz"><img +src="original_demos_files/dl_irix64.gif" border="0"></a><br> +<a href="http://www.antigrain.com/demo/perspective_sun.tar.gz"><img +src="original_demos_files/dl_sunos.gif" border="0"></a><br> +<a href="http://www.antigrain.com/demo/perspective_amiga.gz"><img +src="original_demos_files/dl_amigaos.gif" border="0"></a><br></td></tr> +<tr><td><a href="http://www.antigrain.com/demo/simple_blur.gif"><img +src="original_demos_files/simple_blur_s.gif" title="Click to enlarge" +border="0"></a></td><td style="text-align: justify;"><a +name="PAGE_DEMO_simple_blur"><b></b></a> +<code><a href="http://www.antigrain.com/demo/simple_blur.cpp.html">simple_blur.cpp</a></code> +The example demonstrates how to write custom span generators. This one +just applies the simplest “blur” filter 3x3 to a prerendered image. +It calculates the average value of 9 neighbor pixels. +Just press the left mouse button and drag.</td><td><a +href="http://www.antigrain.com/demo/simple_blur.zip"><img +src="original_demos_files/dl_win32.gif" border="0"></a><br> +<a href="http://www.antigrain.com/demo/simple_blur.tar.gz"><img +src="original_demos_files/dl_linux.gif" border="0"></a><br> +<a href="http://www.antigrain.com/demo/simple_blur_sgi.tar.gz"><img +src="original_demos_files/dl_irix64.gif" border="0"></a><br> +<a href="http://www.antigrain.com/demo/simple_blur_sun.tar.gz"><img +src="original_demos_files/dl_sunos.gif" border="0"></a><br> +<a href="http://www.antigrain.com/demo/simple_blur_amiga.gz"><img +src="original_demos_files/dl_amigaos.gif" border="0"></a><br></td></tr> +<tr><td><a href="http://www.antigrain.com/demo/gpc_test.gif"><img +src="original_demos_files/gpc_test_s.gif" title="Click to enlarge" +border="0"></a></td><td style="text-align: justify;"><a +name="PAGE_DEMO_gpc_test"><b></b></a> +<code><a href="http://www.antigrain.com/demo/gpc_test.cpp.html">gpc_test.cpp</a></code> +<a href="http://www.cs.man.ac.uk/aig/staff/alan/software/"><img +src="original_demos_files/link.gif" border="0"><b><nobr>General Polygon +Clipper</nobr></b></a> by Alan Murta is the most reliable implementation + of the polygon +boolean algebra. It implements Bala R. Vatti's algorithm of arbitrary +polygon clipping and allows you to calculate the Union, Intersection, +Difference, and Exclusive OR between two poly-polygons (i.e., polygonal +areas consisted of several contours). <b>AGG</b> has a simple wrapper +class +that can be used in the coordinate conversion pipeline. The +implementation +by Alan Murta has restrictions of using it in commercial software, so +that, +please contact the author to settle the legal issues. The example +demonstrates the use of GPC. You can drag one polygon with the left +mouse button pressed. Note, that all operations are done in the +vectorial +representation of the contours before rendering.</td><td><a +href="http://www.antigrain.com/demo/gpc_test.zip"><img +src="original_demos_files/dl_win32.gif" border="0"></a><br> +<a href="http://www.antigrain.com/demo/gpc_test.tar.gz"><img +src="original_demos_files/dl_linux.gif" border="0"></a><br> +<a href="http://www.antigrain.com/demo/gpc_test_sgi.tar.gz"><img +src="original_demos_files/dl_irix64.gif" border="0"></a><br> +<a href="http://www.antigrain.com/demo/gpc_test_sun.tar.gz"><img +src="original_demos_files/dl_sunos.gif" border="0"></a><br> +<a href="http://www.antigrain.com/demo/gpc_test_amiga.gz"><img +src="original_demos_files/dl_amigaos.gif" border="0"></a><br></td></tr> +<tr><td><a href="http://www.antigrain.com/demo/pattern_fill.gif"><img +src="original_demos_files/pattern_fill_s.gif" title="Click to enlarge" +border="0"></a></td><td style="text-align: justify;"><a +name="PAGE_DEMO_pattern_fill"><b></b></a> +<code><a href="http://www.antigrain.com/demo/pattern_fill.cpp.html">pattern_fill.cpp</a></code> +The example demonstrates how to use arbitrary images as fill patterns. +This span generator is very simple, so, it doesn't allow you to apply +arbitrary transformations to the pattern, i.e., it cannot be used as a +texturing tool. But it works pretty fast and can be useful in some +applications.</td><td><a +href="http://www.antigrain.com/demo/pattern_fill.zip"><img +src="original_demos_files/dl_win32.gif" border="0"></a><br> +<a href="http://www.antigrain.com/demo/pattern_fill.tar.gz"><img +src="original_demos_files/dl_linux.gif" border="0"></a><br> +<a href="http://www.antigrain.com/demo/pattern_fill_sgi.tar.gz"><img +src="original_demos_files/dl_irix64.gif" border="0"></a><br> +<a href="http://www.antigrain.com/demo/pattern_fill_sun.tar.gz"><img +src="original_demos_files/dl_sunos.gif" border="0"></a><br> +<a href="http://www.antigrain.com/demo/pattern_fill_amiga.gz"><img +src="original_demos_files/dl_amigaos.gif" border="0"></a><br></td></tr> +<tr><td><a href="http://www.antigrain.com/demo/raster_text.gif"><img +src="original_demos_files/raster_text_s.gif" title="Click to enlarge" +border="0"></a></td><td style="text-align: justify;"><a +name="PAGE_DEMO_raster_text"><b></b></a> +<code><a href="http://www.antigrain.com/demo/raster_text.cpp.html">raster_text.cpp</a></code> +Classes that render raster text was added in <b>AGG</b> mostly +to prove the concept of the design. They can be used to +draw simple (aliased) raster text. The example demonstrates +how to use text as a custom scanline generator together +with any span generator (in this example it's gradient filling). +The font format is propriatory, but there are some predefined +fonts that are shown in the example.</td><td><a +href="http://www.antigrain.com/demo/raster_text.zip"><img +src="original_demos_files/dl_win32.gif" border="0"></a><br> +<a href="http://www.antigrain.com/demo/raster_text.tar.gz"><img +src="original_demos_files/dl_linux.gif" border="0"></a><br> +<a href="http://www.antigrain.com/demo/raster_text_sgi.tar.gz"><img +src="original_demos_files/dl_irix64.gif" border="0"></a><br> +<a href="http://www.antigrain.com/demo/raster_text_sun.tar.gz"><img +src="original_demos_files/dl_sunos.gif" border="0"></a><br> +<a href="http://www.antigrain.com/demo/raster_text_amiga.gz"><img +src="original_demos_files/dl_amigaos.gif" border="0"></a><br></td></tr> +<tr><td><a href="http://www.antigrain.com/demo/image1.jpg"><img +src="original_demos_files/image1_s.jpg" title="Click to enlarge" +border="0"></a></td><td style="text-align: justify;"><a +name="PAGE_DEMO_image1"><b></b></a> +<code><a href="http://www.antigrain.com/demo/image1.cpp.html">image1.cpp</a></code> +This is the first example with the new "reincarnation" of the image +transformation algorithms. The example allows you to rotate and scale +the image with respect to its center. Also, the image is scaled +when resizing the window.</td><td><a +href="http://www.antigrain.com/demo/image1.zip"><img +src="original_demos_files/dl_win32.gif" border="0"></a><br> +<a href="http://www.antigrain.com/demo/image1.tar.gz"><img +src="original_demos_files/dl_linux.gif" border="0"></a><br> +<a href="http://www.antigrain.com/demo/image1_sgi.tar.gz"><img +src="original_demos_files/dl_irix64.gif" border="0"></a><br> +<a href="http://www.antigrain.com/demo/image1_sun.tar.gz"><img +src="original_demos_files/dl_sunos.gif" border="0"></a><br> +<a href="http://www.antigrain.com/demo/image1_amiga.gz"><img +src="original_demos_files/dl_amigaos.gif" border="0"></a><br></td></tr> +<tr><td><a href="http://www.antigrain.com/demo/image_alpha.png"><img +src="original_demos_files/image_alpha_s.png" title="Click to enlarge" +border="0"></a></td><td style="text-align: justify;"><a +name="PAGE_DEMO_image_alpha"><b></b></a> +<code><a href="http://www.antigrain.com/demo/image_alpha.cpp.html">image_alpha.cpp</a></code> +A very powerful feature that allows you to simulate the alpha-channel +on the basis of some functioon. In this example it's brightness, but +it can be of any complexity. In the example you can form the brightness +function and watch for the translucency. Resize the windows to move the +image over the backgraund.</td><td><a +href="http://www.antigrain.com/demo/image_alpha.zip"><img +src="original_demos_files/dl_win32.gif" border="0"></a><br> +<a href="http://www.antigrain.com/demo/image_alpha.tar.gz"><img +src="original_demos_files/dl_linux.gif" border="0"></a><br> +<a href="http://www.antigrain.com/demo/image_alpha_sgi.tar.gz"><img +src="original_demos_files/dl_irix64.gif" border="0"></a><br> +<a href="http://www.antigrain.com/demo/image_alpha_sun.tar.gz"><img +src="original_demos_files/dl_sunos.gif" border="0"></a><br> +<a href="http://www.antigrain.com/demo/image_alpha_amiga.gz"><img +src="original_demos_files/dl_amigaos.gif" border="0"></a><br></td></tr> +<tr><td><a href="http://www.antigrain.com/demo/image_filters.jpg"><img +src="original_demos_files/image_filters_s.jpg" title="Click to enlarge" +border="0"></a></td><td style="text-align: justify;"><a +name="PAGE_DEMO_image_filters"><b></b></a> +<code><a href="http://www.antigrain.com/demo/image_filters.cpp.html">image_filters.cpp</a></code> +The image transformer algorithm can work with different interpolation +filters, such as Bilinear, Bicubic, Sinc, Blackman. The example +demonstrates the difference in quality between different filters. +When switch the “Run Test” on, the image starts rotating. But +at each step there is the previously rotated image taken, so +the quality degrades. This degradation as well as the performance +depend on the type of the interpolation filter.</td><td><a +href="http://www.antigrain.com/demo/image_filters.zip"><img +src="original_demos_files/dl_win32.gif" border="0"></a><br> +<a href="http://www.antigrain.com/demo/image_filters.tar.gz"><img +src="original_demos_files/dl_linux.gif" border="0"></a><br> +<a href="http://www.antigrain.com/demo/image_filters_sgi.tar.gz"><img +src="original_demos_files/dl_irix64.gif" border="0"></a><br> +<a href="http://www.antigrain.com/demo/image_filters_sun.tar.gz"><img +src="original_demos_files/dl_sunos.gif" border="0"></a><br> +<a href="http://www.antigrain.com/demo/image_filters_amiga.gz"><img +src="original_demos_files/dl_amigaos.gif" border="0"></a><br></td></tr> +<tr><td><a href="http://www.antigrain.com/demo/image_fltr_graph.gif"><img + src="original_demos_files/image_fltr_graph_s.gif" title="Click to +enlarge" border="0"></a></td><td style="text-align: justify;"><a +name="PAGE_DEMO_image_fltr_graph"><b></b></a> +<code><a href="http://www.antigrain.com/demo/image_fltr_graph.cpp.html">image_fltr_graph.cpp</a></code> +Demonstration of the shapes of different interpolation filters. Just +in case if you are curious.</td><td><a +href="http://www.antigrain.com/demo/image_fltr_graph.zip"><img +src="original_demos_files/dl_win32.gif" border="0"></a><br> +<a href="http://www.antigrain.com/demo/image_fltr_graph.tar.gz"><img +src="original_demos_files/dl_linux.gif" border="0"></a><br> +<a href="http://www.antigrain.com/demo/image_fltr_graph_sgi.tar.gz"><img + src="original_demos_files/dl_irix64.gif" border="0"></a><br> +<a href="http://www.antigrain.com/demo/image_fltr_graph_sun.tar.gz"><img + src="original_demos_files/dl_sunos.gif" border="0"></a><br> +<a href="http://www.antigrain.com/demo/image_fltr_graph_amiga.gz"><img +src="original_demos_files/dl_amigaos.gif" border="0"></a><br></td></tr> +<tr><td><a href="http://www.antigrain.com/demo/image_transforms.jpg"><img + src="original_demos_files/image_transforms_s.jpg" title="Click to +enlarge" border="0"></a></td><td style="text-align: justify;"><a +name="PAGE_DEMO_image_transforms"><b></b></a> +<code><a href="http://www.antigrain.com/demo/image_transforms.cpp.html">image_transforms.cpp</a></code> +Affine transformations of the images. The examples demonstrates +how to construct the affine transformer matrix for different +cases. See the “<code>readme!</code>” file for details. Now there are +methods in <a +href="http://www.antigrain.com/__code/include/agg_trans_affine.h.html#trans_affine">trans_affine</a> + that allow you to construct transformations +from an arbitrary parallelogram to another parallelogram. It's very +convenient and easy.</td><td><a +href="http://www.antigrain.com/demo/image_transforms.zip"><img +src="original_demos_files/dl_win32.gif" border="0"></a><br> +<a href="http://www.antigrain.com/demo/image_transforms.tar.gz"><img +src="original_demos_files/dl_linux.gif" border="0"></a><br> +<a href="http://www.antigrain.com/demo/image_transforms_sgi.tar.gz"><img + src="original_demos_files/dl_irix64.gif" border="0"></a><br> +<a href="http://www.antigrain.com/demo/image_transforms_sun.tar.gz"><img + src="original_demos_files/dl_sunos.gif" border="0"></a><br> +<a href="http://www.antigrain.com/demo/image_transforms_amiga.gz"><img +src="original_demos_files/dl_amigaos.gif" border="0"></a><br></td></tr> +<tr><td><a href="http://www.antigrain.com/demo/image_perspective.jpg"><img + src="original_demos_files/image_perspective_s.jpg" title="Click to +enlarge" border="0"></a></td><td style="text-align: justify;"><a +name="PAGE_DEMO_image_perspective"><b></b></a> +<code><a href="http://www.antigrain.com/demo/image_perspective.cpp.html">image_perspective.cpp</a></code> +Image perspective transformations. There are two types of arbitrary +quadrangle transformations, Perspective and Bilinear. The image +transformer always uses reverse transformations, and there is a problem. +The Perspective transformations are perfectly reversible, so they +work correctly with images, but the Bilinear transformer behave +somehow strange. It can transform a rectangle to a quadrangle, but +not vice versa. In this example you can see this effect, when +the edges of the image "sag". I'd highly appreciate if someone +could help me with math for transformations similar to Bilinear ones, +but correctly reversible (i.e., that can transform an arbitrary +quadrangle +to a rectangle). The bilinear transformations are simple, see +<a +href="http://www.antigrain.com/__code/include/agg_trans_bilinear.h.html">agg_trans_bilinear.h</a> + and <a +href="http://www.antigrain.com/__code/include/agg_simul_eq.h.html">agg_simul_eq.h</a></td><td><a + href="http://www.antigrain.com/demo/image_perspective.zip"><img +src="original_demos_files/dl_win32.gif" border="0"></a><br> +<a href="http://www.antigrain.com/demo/image_perspective.tar.gz"><img +src="original_demos_files/dl_linux.gif" border="0"></a><br> +<a href="http://www.antigrain.com/demo/image_perspective_sgi.tar.gz"><img + src="original_demos_files/dl_irix64.gif" border="0"></a><br> +<a href="http://www.antigrain.com/demo/image_perspective_sun.tar.gz"><img + src="original_demos_files/dl_sunos.gif" border="0"></a><br> +<a href="http://www.antigrain.com/demo/image_perspective_amiga.gz"><img +src="original_demos_files/dl_amigaos.gif" border="0"></a><br></td></tr> +<tr><td><a href="http://www.antigrain.com/demo/distortions.png"><img +src="original_demos_files/distortions_s.png" title="Click to enlarge" +border="0"></a></td><td style="text-align: justify;"><a +name="PAGE_DEMO_distortions"><b></b></a> +<code><a href="http://www.antigrain.com/demo/distortions.cpp.html">distortions.cpp</a></code> +To transform an image as well as to define a color gradient you have +to write several declarations. This approach can seem difficult to +handle +(compared with one function call), but it's very flexible. For example, +you can add an arbitrary distortion function. This mechanism is pretty +much +the same in image transformers and color gradients. Try to play with +this +example changing different parameters of the distortions.</td><td><a +href="http://www.antigrain.com/demo/distortions.zip"><img +src="original_demos_files/dl_win32.gif" border="0"></a><br> +<a href="http://www.antigrain.com/demo/distortions.tar.gz"><img +src="original_demos_files/dl_linux.gif" border="0"></a><br> +<a href="http://www.antigrain.com/demo/distortions_sgi.tar.gz"><img +src="original_demos_files/dl_irix64.gif" border="0"></a><br> +<a href="http://www.antigrain.com/demo/distortions_sun.tar.gz"><img +src="original_demos_files/dl_sunos.gif" border="0"></a><br> +<a href="http://www.antigrain.com/demo/distortions_amiga.gz"><img +src="original_demos_files/dl_amigaos.gif" border="0"></a><br></td></tr> +<tr><td><a href="http://www.antigrain.com/demo/lion_lens.gif"><img +src="original_demos_files/lion_lens_s.gif" title="Click to enlarge" +border="0"></a></td><td style="text-align: justify;"><a +name="PAGE_DEMO_lion_lens"><b></b></a> +<code><a href="http://www.antigrain.com/demo/lion_lens.cpp.html">lion_lens.cpp</a></code> +This example exhibits a non-linear transformer that “magnifies” +vertices that fall inside a circle and extends the rest (<a +href="http://www.antigrain.com/__code/include/agg_trans_warp_magnifier.h.html#trans_warp_magnifier">trans_warp_magnifier</a>). + +Non-linear transformations are tricky because straight lines become +curves. +To achieve the correct result we need to divide long line segments into +short ones. The example also demonstrates the use of <a +href="http://www.antigrain.com/__code/include/agg_conv_segmentator.h.html#conv_segmentator">conv_segmentator</a> + that +does this division job. +Drag the center of the “lens” with the left mouse button and change +the “Scale” and “Radius”. The transformer can also shrink away +the image if the scaling value is less than 1. To watch for +an amazing effect, set the scale to the minimum (0.01), decrease +the radius to about 1 and drag the “lens”. You will see it behaves +like a black hole consuming space around it. Move the lens somewhere to +the +side of the window and change the radius. It looks like changing the +event horizon of the “black hole”. There are some more screenshots +of the poor lion: +<a href="http://www.antigrain.com/demo/lion_lens_sad.gif"><img +src="original_demos_files/link.gif" border="0"><b>Sad Lion</b></a>, +<a href="http://www.antigrain.com/demo/lion_lens_cyclop.gif"><img +src="original_demos_files/link.gif" border="0"><b>Cyclop Lion</b></a>, +<a href="http://www.antigrain.com/demo/lion_lens_black_hole.gif"><img +src="original_demos_files/link.gif" border="0"><b>Lion in Trouble</b> +(being eaten by the black hole), +an animated GIF</a>.</td><td><a +href="http://www.antigrain.com/demo/lion_lens.zip"><img +src="original_demos_files/dl_win32.gif" border="0"></a><br> +<a href="http://www.antigrain.com/demo/lion_lens.tar.gz"><img +src="original_demos_files/dl_linux.gif" border="0"></a><br> +<a href="http://www.antigrain.com/demo/lion_lens_sgi.tar.gz"><img +src="original_demos_files/dl_irix64.gif" border="0"></a><br> +<a href="http://www.antigrain.com/demo/lion_lens_sun.tar.gz"><img +src="original_demos_files/dl_sunos.gif" border="0"></a><br> +<a href="http://www.antigrain.com/demo/lion_lens_amiga.gz"><img +src="original_demos_files/dl_amigaos.gif" border="0"></a><br></td></tr> +<tr><td><a href="http://www.antigrain.com/demo/trans_polar.gif"><img +src="original_demos_files/trans_polar_s.gif" title="Click to enlarge" +border="0"></a></td><td style="text-align: justify;"><a +name="PAGE_DEMO_trans_polar"><b></b></a> +<code><a href="http://www.antigrain.com/demo/trans_polar.cpp.html">trans_polar.cpp</a></code> +Another example of non-linear transformations requested by one of my +friends. +Here we render a standard <b>AGG</b> control in its original form (the +slider +in the bottom) and after the transformation. The transformer itself is +not +a part of <b>AGG</b> and just demonstrates how to write custom +transformers (class +<code>trans_polar</code>). Note that because the transformer is +non-linear, we need to use +<a +href="http://www.antigrain.com/__code/include/agg_conv_segmentator.h.html#conv_segmentator">conv_segmentator</a> + first. Try to drag the value of the slider at the bottom +and watch how it's being synchronized in the polar coordinates. Also +change two other parameters (<b>Spiral</b> and <b>Base Y</b>) and +the size of the window. +Don't worry much about the <code>transformed_control</code> class, it's +just an +adaptor used to render the controls with additional transformations. +The use of <code>trans_polar</code> is quite standard: <br> +<pre>agg::trans_polar tr; +agg::<a href="http://www.antigrain.com/__code/include/agg_conv_transform.h.html#conv_transform">conv_transform</a><SomeVertexSource, + trans_polar> tp(some_source, tr); +</pre></td><td><a href="http://www.antigrain.com/demo/trans_polar.zip"><img + src="original_demos_files/dl_win32.gif" border="0"></a><br> +<a href="http://www.antigrain.com/demo/trans_polar_amiga.gz"><img +src="original_demos_files/dl_amigaos.gif" border="0"></a><br></td></tr> +<tr><td><a href="http://www.antigrain.com/demo/scanline_boolean.gif"><img + src="original_demos_files/scanline_boolean_s.gif" title="Click to +enlarge" border="0"></a></td><td style="text-align: justify;"><a +name="PAGE_DEMO_scanline_boolean"><b></b></a> +<code><a href="http://www.antigrain.com/demo/scanline_boolean.cpp.html">scanline_boolean.cpp</a></code> +A new method to perform boolean operations on polygons (<b>Union</b>, +<b>Intersection</b>, <b>XOR</b>, and <b>Difference</b>). It uses the +scanline +approach and in typical screen resolutions works much faster +(about 10 times) than vectorial algorithms like <a +href="http://www.cs.man.ac.uk/aig/staff/alan/software/"><img +src="original_demos_files/link.gif" border="0"><b><nobr>General Polygon +Clipper</nobr></b></a>. It +preserves perfect <b><nobr>Anti-Aliasing</nobr></b> and besides, can +work with translucency. +There are two <b>XOR</b> operations, <b>Linear XOR</b> and +<b>Saddle XOR</b>. The only difference is in the formula +of XORing of the two cells with <b><nobr>Anti-Aliasing</nobr></b>. The +first one is: +<pre>cover = a+b; if(cover > 1) cover = 2.0 - cover;</pre> +<br> +The second uses the classical “Saddle” formula: +<pre>cover = 1.0 - (1.0 - a + a*b) * (1.0 - b + a*b);</pre> +The <b>Linear XOR</b> produces +more correct intersections and works constistently with the +scanline rasterizer algorithm. The <b>Saddle XOR</b> works better +with semi-transparent polygons.</td><td><a +href="http://www.antigrain.com/demo/scanline_boolean.zip"><img +src="original_demos_files/dl_win32.gif" border="0"></a><br> +<a href="http://www.antigrain.com/demo/scanline_boolean_amiga.gz"><img +src="original_demos_files/dl_amigaos.gif" border="0"></a><br></td></tr> +<tr><td><a href="http://www.antigrain.com/demo/scanline_boolean2.gif"><img + src="original_demos_files/scanline_boolean2_s.gif" title="Click to +enlarge" border="0"></a></td><td style="text-align: justify;"><a +name="PAGE_DEMO_scanline_boolean2"><b></b></a> +<code><a href="http://www.antigrain.com/demo/scanline_boolean2.cpp.html">scanline_boolean2.cpp</a></code> +This is another example of using of the scanline boolean algebra. +The example is similar to <a +href="http://www.antigrain.com/demo/index.html#PAGE_DEMO_gpc_test">Demo +gpc_test.cpp</a>. Note that the cost +of the boolean operation with <b><nobr>Anti-Aliasing</nobr></b> is +comparable with rendering +(the rasterization time is not included). Also note that there is +a difference in timings between using of <code>scanline_u</code> and +<code>scanline_p</code>. Most often <code>scanline_u</code> works +faster, but it's +because of much less number of produced spans. Actually, when using +the <code>scanline_u</code> the complexity of the algorithm becomes +proportional +to the <b>area</b> of the polygons, while in <code>scanline_p</code> +it's +proportional to the <b>perimeter</b>. Of course, the binary variant +works much faster than the <b>Anti-Aliased</b> one.</td><td><a +href="http://www.antigrain.com/demo/scanline_boolean2.zip"><img +src="original_demos_files/dl_win32.gif" border="0"></a><br> +<a href="http://www.antigrain.com/demo/scanline_boolean2_amiga.gz"><img +src="original_demos_files/dl_amigaos.gif" border="0"></a><br></td></tr> +<tr><td><a href="http://www.antigrain.com/demo/freetype_test.gif"><img +src="original_demos_files/freetype_test_s.gif" title="Click to enlarge" +border="0"></a></td><td style="text-align: justify;"><a +name="PAGE_DEMO_freetype_test"><b></b></a> +<code><a href="http://www.antigrain.com/demo/freetype_test.cpp.html">freetype_test.cpp</a></code> +This example demonstrates the use of the <a +href="http://www.freetype.org/"><img src="original_demos_files/link.gif" + border="0"><b>FreeType</b></a> font engine with cache. +Cache can keep three types of data, vector path, <b>Anti-Aliased</b> +scanline shape, and monochrome scanline shape. In case of caching +scanline shapes the speed is pretty good and comparable with +Windows hardware accelerated font rendering.</td><td><a +href="http://www.antigrain.com/demo/freetype_test.zip"><img +src="original_demos_files/dl_win32.gif" border="0"></a><br> +<a href="http://www.antigrain.com/demo/freetype_test_amiga.gz"><img +src="original_demos_files/dl_amigaos.gif" border="0"></a><br></td></tr> +<tr><td><a href="http://www.antigrain.com/demo/freetype_test.gif"><img +src="original_demos_files/freetype_test_s.gif" title="Click to enlarge" +border="0"></a></td><td style="text-align: justify;"><a +name="PAGE_DEMO_truetype_test"><b></b></a> +<code><a href="http://www.antigrain.com/demo/truetype_test.cpp.html">truetype_test.cpp</a></code> +The same as the above, but with using Win32 API as the +font engine (<code>GetGlyphOutline()</code>).</td><td><a +href="http://www.antigrain.com/demo/truetype_test.zip"><img +src="original_demos_files/dl_win32.gif" border="0"></a><br></td></tr> +<tr><td><a href="http://www.antigrain.com/demo/trans_curve1.gif"><img +src="original_demos_files/trans_curve1_s.gif" title="Click to enlarge" +border="0"></a></td><td style="text-align: justify;"><a +name="PAGE_DEMO_trans_curve1"><b></b></a> +<code><a href="http://www.antigrain.com/demo/trans_curve1.cpp.html">trans_curve1.cpp</a></code> +This is a "kinda-cool-stuff" demo that performs non-linear +transformations and draws vector text along a curve. +Note that it's not just calculating of the glyph angles +and positions, they are transformed as if they were elastic. +The curve +is calculated as a bicubic spline. The option "Preserve X scale" +makes the converter distribute all the points uniformly along +the curve. If it's unchechked, the scale will be proportional +to the distance between the control points.</td><td><a +href="http://www.antigrain.com/demo/trans_curve1.zip"><img +src="original_demos_files/dl_win32.gif" border="0"></a><br> +<a href="http://www.antigrain.com/demo/trans_curve1_ft_amiga.gz"><img +src="original_demos_files/dl_amigaos.gif" border="0"></a><br></td></tr> +<tr><td><a href="http://www.antigrain.com/demo/trans_curve2.gif"><img +src="original_demos_files/trans_curve2_s.gif" title="Click to enlarge" +border="0"></a></td><td style="text-align: justify;"><a +name="PAGE_DEMO_trans_curve2"><b></b></a> +<code><a href="http://www.antigrain.com/demo/trans_curve2.cpp.html">trans_curve2.cpp</a></code> +Similar to the previous demo, but here the transformer operates +with two arbitrary curves. It requires more calculations, but gives +you more freedom. In other words you will see :-).</td><td><a +href="http://www.antigrain.com/demo/trans_curve2.zip"><img +src="original_demos_files/dl_win32.gif" border="0"></a><br> +<a href="http://www.antigrain.com/demo/trans_curve2_ft_amiga.gz"><img +src="original_demos_files/dl_amigaos.gif" border="0"></a><br></td></tr> +<tr><td><a href="http://www.antigrain.com/demo/aa_test.png"><img +src="original_demos_files/aa_test_s.png" title="Click to enlarge" +border="0"></a></td><td style="text-align: justify;"><a +name="PAGE_DEMO_aa_test"><b></b></a> +<code><a href="http://www.antigrain.com/demo/aa_test.cpp.html">aa_test.cpp</a></code> +A test of <b><nobr>Anti-Aliasing</nobr></b> the same as in <br> +<a href="http://homepage.mac.com/arekkusu/bugs/invariance"><img +src="original_demos_files/link.gif" border="0">http://homepage.mac.com/arekkusu/bugs/invariance</a><br> +The performance of <b>AGG</b> on a typical P-IV 2GHz is: <br> +Points: 37.46K/sec, Lines: 5.04K/sec, Triangles: 7.43K/sec</td><td><a +href="http://www.antigrain.com/demo/aa_test.zip"><img +src="original_demos_files/dl_win32.gif" border="0"></a><br> +<a href="http://www.antigrain.com/demo/aa_test_amiga.gz"><img +src="original_demos_files/dl_amigaos.gif" border="0"></a><br></td></tr> +<tr><td><a href="http://www.antigrain.com/demo/alpha_gradient.png"><img +src="original_demos_files/alpha_gradient_s.png" title="Click to enlarge" + border="0"></a></td><td style="text-align: justify;"><a +name="PAGE_DEMO_alpha_gradient"><b></b></a> +<code><a href="http://www.antigrain.com/demo/alpha_gradient.cpp.html">alpha_gradient.cpp</a></code> +The demo shows how to combine any span generator with alpha-channel +gradient.</td><td><a +href="http://www.antigrain.com/demo/alpha_gradient.zip"><img +src="original_demos_files/dl_win32.gif" border="0"></a><br> +<a href="http://www.antigrain.com/demo/alpha_gradient_amiga.gz"><img +src="original_demos_files/dl_amigaos.gif" border="0"></a><br></td></tr> +<tr><td><a href="http://www.antigrain.com/demo/line_patterns.gif"><img +src="original_demos_files/line_patterns_s.gif" title="Click to enlarge" +border="0"></a></td><td style="text-align: justify;"><a +name="PAGE_DEMO_line_patterns"><b></b></a> +<code><a href="http://www.antigrain.com/demo/line_patterns.cpp.html">line_patterns.cpp</a></code> +The demo shows a very powerful mechanism of using arbitrary images as +line patterns. +The main point of it is that the images are drawn along the path. It +allows you +to draw very fancy looking lines quite easily and very useful in +GIS/cartography +applications. There the bilinear filtering is used, but it's also +possible +to add any other filtering methods, or just use the nearest neighbour +one for the +sake of speed. <br> +Before running this demo make sure that you have files <code>1.bmp</code>…<code>9.bmp</code> + for Win32, +MacOS, AmigaOS, and SDL platforms and <code>1.ppm</code>…<code>9.ppm</code> + for X11. <br> +In the demo you can drag the control points of the curves and observe +that the images are +transformed quite consistently and smoothly. You can also try to replace + the image files +(1…9) with your own. The BMP files must have 24bit colors (TrueColor), +the PPM ones +must be of type "P6". Also, the heigh should not exceed 64 pixels, and +the background +should be white or very close to white. Actually, the algorithm uses +32bit images +with alpha channel, but in this demo alpha is simulated in such a way +that wite +is transparent, black is opaque. The intermediate colors have +intermediate opacity +that is defined by the <code>brightness_to_alpha</code> array.</td><td><a + href="http://www.antigrain.com/demo/line_patterns.zip"><img +src="original_demos_files/dl_win32.gif" border="0"></a><br></td></tr> +<tr><td><a href="http://www.antigrain.com/demo/line_patterns_clip.png"><img + src="original_demos_files/line_patterns_clip_s.png" title="Click to +enlarge" border="0"></a></td><td style="text-align: justify;"><a +name="PAGE_DEMO_line_patterns_clip"><b></b></a> +<code><a +href="http://www.antigrain.com/demo/line_patterns_clip.cpp.html">line_patterns_clip.cpp</a></code> +Demonstrates the mechanism of clipping the polylines and/or polygons +with image patterns. Shows that the clipper maintains correct pattern +repetition along the line, considering clipped parts.</td><td><a +href="http://www.antigrain.com/demo/line_patterns_clip.zip"><img +src="original_demos_files/dl_win32.gif" border="0"></a><br></td></tr> +<tr><td><a href="http://www.antigrain.com/demo/pattern_perspective.jpg"><img + src="original_demos_files/pattern_perspective_s.jpg" title="Click to +enlarge" border="0"></a></td><td style="text-align: justify;"><a +name="PAGE_DEMO_pattern_perspective"><b></b></a> +<code><a +href="http://www.antigrain.com/demo/pattern_perspective.cpp.html">pattern_perspective.cpp</a></code> +Pattern perspective transformations. Essentially it's +the same as <a +href="http://www.antigrain.com/demo/index.html#PAGE_DEMO_image_perspective">Demo + image_perspective.cpp</a>, but working with a repeating pattern. +Can be used for texturing.</td><td><a +href="http://www.antigrain.com/demo/pattern_perspective.zip"><img +src="original_demos_files/dl_win32.gif" border="0"></a><br></td></tr> +<tr><td><a href="http://www.antigrain.com/demo/image_filters2.png"><img +src="original_demos_files/image_filters2_s.png" title="Click to enlarge" + border="0"></a></td><td style="text-align: justify;"><a +name="PAGE_DEMO_image_filters2"><b></b></a> +<code><a href="http://www.antigrain.com/demo/image_filters2.cpp.html">image_filters2.cpp</a></code> +Another example that demonstrates the difference of image filters. It +just +displays a simple 4x4 pixels image with huge zoom. You can see how +different +filters affect the result. Also see how gamma correction works.</td><td><a + href="http://www.antigrain.com/demo/image_filters2.zip"><img +src="original_demos_files/dl_win32.gif" border="0"></a><br></td></tr> +<tr><td><a href="http://www.antigrain.com/demo/image_resample.jpg"><img +src="original_demos_files/image_resample_s.jpg" title="Click to enlarge" + border="0"></a></td><td style="text-align: justify;"><a +name="PAGE_DEMO_image_resample"><b></b></a> +<code><a href="http://www.antigrain.com/demo/image_resample.cpp.html">image_resample.cpp</a></code> +The demonstration of image transformations with resampling. You can +see the difference in quality between regular image transformers and +the ones with resampling. Of course, image tranformations with +resampling +work slower because they provide the best possible quality.</td><td><a +href="http://www.antigrain.com/demo/image_resample.zip"><img +src="original_demos_files/dl_win32.gif" border="0"></a><br></td></tr> +<tr><td><a href="http://www.antigrain.com/demo/pattern_resample.jpg"><img + src="original_demos_files/pattern_resample_s.jpg" title="Click to +enlarge" border="0"></a></td><td style="text-align: justify;"><a +name="PAGE_DEMO_pattern_resample"><b></b></a> +<code><a href="http://www.antigrain.com/demo/image_resample.cpp.html">image_resample.cpp</a></code> +The demonstration of pattern transformations with resampling. The same +as +the above but with texturing patterns.</td><td><a +href="http://www.antigrain.com/demo/pattern_resample.zip"><img +src="original_demos_files/dl_win32.gif" border="0"></a><br></td></tr> +<tr><td><a href="http://www.antigrain.com/demo/compositing.png"><img +src="original_demos_files/compositing_s.png" title="Click to enlarge" +border="0"></a></td><td style="text-align: justify;"><a +name="PAGE_DEMO_compositing"><b></b></a> +<code><a href="http://www.antigrain.com/demo/compositing.cpp.html">compositing.cpp</a></code> +Extended compositing modes fully compatible with +<a +href="http://www.w3.org/TR/2004/WD-SVG12-20041027/rendering.html#comp-op-prop"><img + src="original_demos_files/link.gif" border="0">SVG 1.2</a></td><td><a +href="http://www.antigrain.com/demo/compositing.zip"><img +src="original_demos_files/dl_win32.gif" border="0"></a><br></td></tr> +<tr><td><a href="http://www.antigrain.com/demo/compositing2.png"><img +src="original_demos_files/compositing2_s.png" title="Click to enlarge" +border="0"></a></td><td style="text-align: justify;"><a +name="PAGE_DEMO_compositing2"><b></b></a> +<code><a href="http://www.antigrain.com/demo/compositing2.cpp.html">compositing2.cpp</a></code> +Another demo example with extended compositing modes.</td><td><a +href="http://www.antigrain.com/demo/compositing2.zip"><img +src="original_demos_files/dl_win32.gif" border="0"></a><br></td></tr> +<tr><td><a href="http://www.antigrain.com/demo/bezier_div.png"><img +src="original_demos_files/bezier_div_s.png" title="Click to enlarge" +border="0"></a></td><td style="text-align: justify;"><a +name="PAGE_DEMO_bezier_div"><b></b></a> +<code><a href="http://www.antigrain.com/demo/bezier_div.cpp.html">bezier_div.cpp</a></code> +Demonstration of new methods of Bezier curve approximation. You can +compare +the old, incremental method with adaptive De Casteljau's subdivion. The +new method uses two criteria to stop subdivision: estimation of distance + and +estimation of angle. It gives us perfectly smooth result even for very +sharp +turns and loops.</td><td><a +href="http://www.antigrain.com/demo/bezier_div.zip"><img +src="original_demos_files/dl_win32.gif" border="0"></a><br></td></tr> +<tr><td><a href="http://www.antigrain.com/demo/flash_rasterizer.png"><img + src="original_demos_files/flash_rasterizer_s.png" title="Click to +enlarge" border="0"></a></td><td style="text-align: justify;"><a +name="PAGE_DEMO_flash_rasterizer"><b></b></a> +<code><a href="http://www.antigrain.com/demo/flash_rasterizer.cpp.html">flash_rasterizer.cpp</a></code> +Demonstration of Flash compound shape rasterizer. The rasterizer +accepts vectorial data in a form of Flash paths, that is, with two +fill styles, fill on the left and fill on the right of the path. +Then it produces a number of scanlines with corresponding styles +and requests for the colors and/or gradients, images, etc. The +algorithm takes care of anti-aliasing and perfect stitching +between fill areas.</td><td><a +href="http://www.antigrain.com/demo/flash_rasterizer.zip"><img +src="original_demos_files/dl_win32.gif" border="0"></a><br></td></tr> +<tr><td><a href="http://www.antigrain.com/demo/flash_rasterizer2.png"><img + src="original_demos_files/flash_rasterizer2_s.png" title="Click to +enlarge" border="0"></a></td><td style="text-align: justify;"><a +name="PAGE_DEMO_flash_rasterizer2"><b></b></a> +<code><a href="http://www.antigrain.com/demo/flash_rasterizer2.cpp.html">flash_rasterizer2.cpp</a></code> +Another possible way to render Flash compound shapes. The idea behind +it is prety simple. You just use the regular rasterizer, but in a +mode when it doesn't automatically close the contours. Every compound +shape is decomposed into a number of single shapes that are rasterized +and rendered separately.</td><td><a +href="http://www.antigrain.com/demo/flash_rasterizer2.zip"><img +src="original_demos_files/dl_win32.gif" border="0"></a><br></td></tr> +<tr><td><a href="http://www.antigrain.com/demo/gouraud_mesh.png"><img +src="original_demos_files/gouraud_mesh_s.png" title="Click to enlarge" +border="0"></a></td><td style="text-align: justify;"><a +name="PAGE_DEMO_gouraud_mesh"><b></b></a> +<code><a href="http://www.antigrain.com/demo/gouraud_mesh.cpp.html">gouraud_mesh.cpp</a></code> +Yet another example that demonstrates the power of compound shape +rasterization. +Here we create a mesh of triangles and render them in one pass with +multiple +Gouraud shaders (<a +href="http://www.antigrain.com/__code/include/agg_span_gouraud_rgba.h.html#span_gouraud_rgba">span_gouraud_rgba</a>). + The example demonstrates perfect +<b><nobr>Anti-Aliasing</nobr></b> and perfect triangle stitching +(seamless edges) at the same time.</td><td><a +href="http://www.antigrain.com/demo/gouraud_mesh.zip"><img +src="original_demos_files/dl_win32.gif" border="0"></a><br></td></tr> +<tr><td><a href="http://www.antigrain.com/demo/rasterizer_compound.png"><img + src="original_demos_files/rasterizer_compound_s.png" title="Click to +enlarge" border="0"></a></td><td style="text-align: justify;"><a +name="PAGE_DEMO_rasterizer_compound"><b></b></a> +<code><a +href="http://www.antigrain.com/demo/rasterizer_compound.cpp.html">rasterizer_compound.cpp</a></code> +This simple example demonstrates a rather advanced technique of using +the compound rasterizer. The idea is you assign styles to the polygons +(left=style, right=-1) and rasterize this "multi-styled" compound shape +as a whole. If the polygons in the shape overlap, the greater styles +have +higher priority. That is, the result is as if greater styles were +painted +last, but the geometry is flattened before rendering. It means there are + +no pixels will be painted twice. Then the style are associated with +colors, +gradients, images, etc. in a special style handler. It simulates +Constructive Solid Geometry so that, you can, for example draw a +translucent +fill plus translucent stroke without the overlapped part of the fill +being +visible through the stroke.</td><td><a +href="http://www.antigrain.com/demo/rasterizer_compound.zip"><img +src="original_demos_files/dl_win32.gif" border="0"></a><br></td></tr> +<tr><td><a href="http://www.antigrain.com/demo/blur.png"><img +src="original_demos_files/blur_s.png" title="Click to enlarge" +border="0"></a></td><td style="text-align: justify;"><a +name="PAGE_DEMO_blur"><b></b></a> +<code><a href="http://www.antigrain.com/demo/blur.cpp.html">blur.cpp</a></code> +Now you can blur rendered images rather fast! There two algorithms +are used: <a +href="http://incubator.quasimondo.com/processing/fast_blur_deluxe.php"><img + src="original_demos_files/link.gif" border="0">Stack Blur</a> by Mario +Klingemann and Fast Recursive Gaussian Filter, described +<a +href="http://www.ph.tn.tudelft.nl/Courses/FIP/noframes/fip-Smoothin.html"><img + src="original_demos_files/link.gif" border="0">here</a> +and <a +href="http://www.ph.tn.tudelft.nl/%7Elucas/publications/1995/SP95TYLV/SP95TYLV.pdf"><img + src="original_demos_files/link.gif" border="0">here (PDF)</a>. The +speed of both methods does not depend on the filter radius. +Mario's method works 3-5 times faster; it doesn't produce exactly +Gaussian +response, but pretty fair for most practical purposes. The recursive +filter +uses floating point arithmetic and works slower. But it is true Gaussian + filter, +with theoretically infinite impulse response. The radius (actually +2*sigma value) +can be fractional and the filter produces quite adequate result.</td><td><a + href="http://www.antigrain.com/demo/blur.zip"><img +src="original_demos_files/dl_win32.gif" border="0"></a><br></td></tr> +</tbody></table><font style="margin-left: 1em;"><i></i></font> + + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>…TO +BE CONTINUED +</p></td></tr></tbody></table><table style="margin: 0px;" height="1px" +width="640px" bgcolor="#583927" border="0" cellpadding="0" +cellspacing="0"><tbody><tr><td></td></tr></tbody></table> +<table width="640px" border="0" cellpadding="0" cellspacing="0"> +<tbody><tr><td><center><span class="authors"> +Copyright <span class="larger">©</span> 2002-2006 +<a href="http://www.antigrain.com/mcseem/index.html"><b>Maxim Shemanarev</b></a> +</span></center></td></tr> +<tr><td><center><span class="authors"> +Web Design and Programming +<a href="http://www.antigrain.com/mcseem/index.html"><b>Maxim Shemanarev</b></a> +</span></center></td></tr> +</tbody></table> +<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br> +<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br> +<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br> +<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br> +</body></html>
\ No newline at end of file diff --git a/docs/aggpas/original_demos_files/aa_demo_s.gif b/docs/aggpas/original_demos_files/aa_demo_s.gif Binary files differnew file mode 100644 index 00000000..d0294282 --- /dev/null +++ b/docs/aggpas/original_demos_files/aa_demo_s.gif diff --git a/docs/aggpas/original_demos_files/aa_test_s.png b/docs/aggpas/original_demos_files/aa_test_s.png Binary files differnew file mode 100644 index 00000000..1334e779 --- /dev/null +++ b/docs/aggpas/original_demos_files/aa_test_s.png diff --git a/docs/aggpas/original_demos_files/agg.css b/docs/aggpas/original_demos_files/agg.css new file mode 100644 index 00000000..997d9d07 --- /dev/null +++ b/docs/aggpas/original_demos_files/agg.css @@ -0,0 +1,239 @@ +BODY +{ + font-family:Verdana, Arial, Tahoma; + font-size:12px; + color:#160801; + background-color:#ffffff; + text-align:justify; + padding:5px; +} + +P, UL, OL, DL +{ + font-family:Verdana, Arial, Tahoma; + font-size:12px; + color:#160801; + margin-bottom:0px; + margin-top:0px; +} + + +.larger +{ + font-size:14px; +} + +LI +{ + padding:3px; +} + +HR +{ + color:#583927; + height:1px; +} + +H1 +{ + font-family:Verdana, Arial, Tahoma; + font-size:28px; + font-weight:bolder; + text-align:center; + color:#583927; + margin:0px; +} + +H1 SPAN.subtitle +{ + font-family:Verdana, Arial, Tahoma; + font-size:18px; + font-weight:lighter; +} + + +H2 +{ + font-family:Verdana, Arial, Tahoma; + font-size:26px; + font-weight:normal; + text-align:left; + color:#583927; +} + +H3 +{ + font-family:Verdana, Arial, Tahoma; + font-size:20px; + font-weight:normal; + text-align:left; + color:#583927; +} + +H4 +{ + font-family:Verdana, Arial, Tahoma; + font-size:16px; + font-weight:bold; + text-align:left; + color:#583927; +} + +H5 +{ + font-family:Verdana, Arial, Tahoma; + font-size:14px; + font-weight:bold; + text-align:left; + color:#583927; +} + +TABLE +{ + margin:5px; +} + +TD +{ + font-family:Verdana, Arial, Tahoma; + font-size:12px; +} + +TH +{ + font-family:Verdana, Arial, Tahoma; + background-color:#d4d4d4; + font-size:12px; +} + + +PRE +{ + padding: 5px; + border: gray 1px solid; + background-color:#f4f4f4; + color:#130f00; + font-family:"courier new", courier,mono; + font-size:12px; + margin:0px; +} + +TT, CODE +{ + font-family:"courier new", courier,mono; + font-size:14px; + color:#000070; +} + +.warning, .warning TD +{ + background-color:#fcf6f6; + color:#793131; + padding:0.5em; + font-family:Verdana, Arial, Tahoma; + font-size:12px; + text-align:justify; +} + +.note, .note TD +{ + background-color:#f0fafa; + color:#506580; + padding:0.5em; + font-family:Verdana, Arial, Tahoma; + font-size:12px; + text-align:justify; +} + +.quote, .quote TD +{ + background-color:#f0fafa; + color:#000540; + padding:0.5em; + font-family:Verdana, Arial, Tahoma; + font-size:12px; + text-align:justify; +} + +.tip, .tip TD +{ + background-color:#fbfff6; + color:#68771e; + padding:0.5em; + font-family:Verdana, Arial, Tahoma; + font-size:12px; + text-align:justify; +} + +.tbl TD +{ + background-color:#f4f4f4; + font-family:Verdana, Arial, Tahoma; + font-size:12px; + text-align:left; + padding:3px; +} + +.toc TD +{ + font-family:Verdana, Arial, Tahoma; + text-align:left; + padding:3px; +} + +.title {font-family:Verdana, Arial, Tahoma;} + +.warning P, +.warning PRE, +.note P, +.note PRE, +.tip P, +.tip PRE {margin:0.3em 0em 0.1em 0em;} + +.warning .code {background-color:#fcf6f6;} +.note .code {background-color:#f0fafa;} +.tip .code {background-color:#fbfff6;} + +A {text-decoration:none; color:#700000;} +A:visited {text-decoration:none; color:#85585d;} +A:link {text-decoration:none;} +A:hover {text-decoration:underline;} + +.topmenu,a.topmenu:visited,a.topmenu:hover,a.topmenu:active,a.topmenu:link +{ + font-family: Arial, Tahoma, Helvetica, sans-serif; + font-size: 11px; + font-weight: bold; + text-decoration: none; + color: #582218; +} + +.mpmenu,a.mpmenu:visited,a.mpmenu:hover,a.mpmenu:active,a.mpmenu:link +{ + font-family: Arial, Tahoma, Helvetica, sans-serif; + font-size: 12px; + font-weight: bold; + text-decoration: none; + color: #582218; +} + +.tah +{ + font-family: Tahoma, Arial, Helvetica, sans-serif; + font-size: 12px; + color: #582218; +} + +.authors +{ + font-size:10px; +} + +span.rem {color:#4c8d00;} +span.kw1 {color:#000d8e;} +span.kw2 {color:#0075ca;} +span.kw3 {color:#004645;} +span.kw4 {color:#673517;} +span.op {color:#4a006d;} +span.str {color:#ab2500;} +span.num {color:#a74c3f;} diff --git a/docs/aggpas/original_demos_files/agg_logo.gif b/docs/aggpas/original_demos_files/agg_logo.gif Binary files differnew file mode 100644 index 00000000..ee5c570a --- /dev/null +++ b/docs/aggpas/original_demos_files/agg_logo.gif diff --git a/docs/aggpas/original_demos_files/alpha_gradient_s.png b/docs/aggpas/original_demos_files/alpha_gradient_s.png Binary files differnew file mode 100644 index 00000000..3cefbfe1 --- /dev/null +++ b/docs/aggpas/original_demos_files/alpha_gradient_s.png diff --git a/docs/aggpas/original_demos_files/alpha_mask2_s.jpg b/docs/aggpas/original_demos_files/alpha_mask2_s.jpg Binary files differnew file mode 100644 index 00000000..22e0dba5 --- /dev/null +++ b/docs/aggpas/original_demos_files/alpha_mask2_s.jpg diff --git a/docs/aggpas/original_demos_files/alpha_mask3_s.gif b/docs/aggpas/original_demos_files/alpha_mask3_s.gif Binary files differnew file mode 100644 index 00000000..5070e757 --- /dev/null +++ b/docs/aggpas/original_demos_files/alpha_mask3_s.gif diff --git a/docs/aggpas/original_demos_files/alpha_mask_s.gif b/docs/aggpas/original_demos_files/alpha_mask_s.gif Binary files differnew file mode 100644 index 00000000..8fdc0d8d --- /dev/null +++ b/docs/aggpas/original_demos_files/alpha_mask_s.gif diff --git a/docs/aggpas/original_demos_files/bezier_div_s.png b/docs/aggpas/original_demos_files/bezier_div_s.png Binary files differnew file mode 100644 index 00000000..727d9ecb --- /dev/null +++ b/docs/aggpas/original_demos_files/bezier_div_s.png diff --git a/docs/aggpas/original_demos_files/blur_s.png b/docs/aggpas/original_demos_files/blur_s.png Binary files differnew file mode 100644 index 00000000..fde042c3 --- /dev/null +++ b/docs/aggpas/original_demos_files/blur_s.png diff --git a/docs/aggpas/original_demos_files/circles_s.gif b/docs/aggpas/original_demos_files/circles_s.gif Binary files differnew file mode 100644 index 00000000..8bdbd0eb --- /dev/null +++ b/docs/aggpas/original_demos_files/circles_s.gif diff --git a/docs/aggpas/original_demos_files/component_rendering_s.gif b/docs/aggpas/original_demos_files/component_rendering_s.gif Binary files differnew file mode 100644 index 00000000..073ff485 --- /dev/null +++ b/docs/aggpas/original_demos_files/component_rendering_s.gif diff --git a/docs/aggpas/original_demos_files/compositing2_s.png b/docs/aggpas/original_demos_files/compositing2_s.png Binary files differnew file mode 100644 index 00000000..c5245ea2 --- /dev/null +++ b/docs/aggpas/original_demos_files/compositing2_s.png diff --git a/docs/aggpas/original_demos_files/compositing_s.png b/docs/aggpas/original_demos_files/compositing_s.png Binary files differnew file mode 100644 index 00000000..2f799caf --- /dev/null +++ b/docs/aggpas/original_demos_files/compositing_s.png diff --git a/docs/aggpas/original_demos_files/conv_contour_s.gif b/docs/aggpas/original_demos_files/conv_contour_s.gif Binary files differnew file mode 100644 index 00000000..9ad72f07 --- /dev/null +++ b/docs/aggpas/original_demos_files/conv_contour_s.gif diff --git a/docs/aggpas/original_demos_files/conv_dash_marker_s.gif b/docs/aggpas/original_demos_files/conv_dash_marker_s.gif Binary files differnew file mode 100644 index 00000000..057ce7ab --- /dev/null +++ b/docs/aggpas/original_demos_files/conv_dash_marker_s.gif diff --git a/docs/aggpas/original_demos_files/conv_stroke_s.gif b/docs/aggpas/original_demos_files/conv_stroke_s.gif Binary files differnew file mode 100644 index 00000000..46c3e3a0 --- /dev/null +++ b/docs/aggpas/original_demos_files/conv_stroke_s.gif diff --git a/docs/aggpas/original_demos_files/distortions_s.png b/docs/aggpas/original_demos_files/distortions_s.png Binary files differnew file mode 100644 index 00000000..72664143 --- /dev/null +++ b/docs/aggpas/original_demos_files/distortions_s.png diff --git a/docs/aggpas/original_demos_files/dl_amigaos.gif b/docs/aggpas/original_demos_files/dl_amigaos.gif Binary files differnew file mode 100644 index 00000000..119a522e --- /dev/null +++ b/docs/aggpas/original_demos_files/dl_amigaos.gif diff --git a/docs/aggpas/original_demos_files/dl_irix64.gif b/docs/aggpas/original_demos_files/dl_irix64.gif Binary files differnew file mode 100644 index 00000000..5f89e0c6 --- /dev/null +++ b/docs/aggpas/original_demos_files/dl_irix64.gif diff --git a/docs/aggpas/original_demos_files/dl_linux.gif b/docs/aggpas/original_demos_files/dl_linux.gif Binary files differnew file mode 100644 index 00000000..0185581c --- /dev/null +++ b/docs/aggpas/original_demos_files/dl_linux.gif diff --git a/docs/aggpas/original_demos_files/dl_sunos.gif b/docs/aggpas/original_demos_files/dl_sunos.gif Binary files differnew file mode 100644 index 00000000..106215df --- /dev/null +++ b/docs/aggpas/original_demos_files/dl_sunos.gif diff --git a/docs/aggpas/original_demos_files/dl_win32.gif b/docs/aggpas/original_demos_files/dl_win32.gif Binary files differnew file mode 100644 index 00000000..05aace7e --- /dev/null +++ b/docs/aggpas/original_demos_files/dl_win32.gif diff --git a/docs/aggpas/original_demos_files/download.gif b/docs/aggpas/original_demos_files/download.gif Binary files differnew file mode 100644 index 00000000..fd9367e4 --- /dev/null +++ b/docs/aggpas/original_demos_files/download.gif diff --git a/docs/aggpas/original_demos_files/examples_s.jpg b/docs/aggpas/original_demos_files/examples_s.jpg Binary files differnew file mode 100644 index 00000000..e9d92019 --- /dev/null +++ b/docs/aggpas/original_demos_files/examples_s.jpg diff --git a/docs/aggpas/original_demos_files/flash_rasterizer2_s.png b/docs/aggpas/original_demos_files/flash_rasterizer2_s.png Binary files differnew file mode 100644 index 00000000..51541a67 --- /dev/null +++ b/docs/aggpas/original_demos_files/flash_rasterizer2_s.png diff --git a/docs/aggpas/original_demos_files/flash_rasterizer_s.png b/docs/aggpas/original_demos_files/flash_rasterizer_s.png Binary files differnew file mode 100644 index 00000000..49938cee --- /dev/null +++ b/docs/aggpas/original_demos_files/flash_rasterizer_s.png diff --git a/docs/aggpas/original_demos_files/freetype_test_s.gif b/docs/aggpas/original_demos_files/freetype_test_s.gif Binary files differnew file mode 100644 index 00000000..dec17fb7 --- /dev/null +++ b/docs/aggpas/original_demos_files/freetype_test_s.gif diff --git a/docs/aggpas/original_demos_files/gamma_correction_s.gif b/docs/aggpas/original_demos_files/gamma_correction_s.gif Binary files differnew file mode 100644 index 00000000..5816ebad --- /dev/null +++ b/docs/aggpas/original_demos_files/gamma_correction_s.gif diff --git a/docs/aggpas/original_demos_files/gamma_ctrl_s.gif b/docs/aggpas/original_demos_files/gamma_ctrl_s.gif Binary files differnew file mode 100644 index 00000000..4bd236a5 --- /dev/null +++ b/docs/aggpas/original_demos_files/gamma_ctrl_s.gif diff --git a/docs/aggpas/original_demos_files/gamma_tuner_s.png b/docs/aggpas/original_demos_files/gamma_tuner_s.png Binary files differnew file mode 100644 index 00000000..66f15973 --- /dev/null +++ b/docs/aggpas/original_demos_files/gamma_tuner_s.png diff --git a/docs/aggpas/original_demos_files/gdip_curves.gif b/docs/aggpas/original_demos_files/gdip_curves.gif Binary files differnew file mode 100644 index 00000000..213cf233 --- /dev/null +++ b/docs/aggpas/original_demos_files/gdip_curves.gif diff --git a/docs/aggpas/original_demos_files/gouraud_mesh_s.png b/docs/aggpas/original_demos_files/gouraud_mesh_s.png Binary files differnew file mode 100644 index 00000000..f9b8d60d --- /dev/null +++ b/docs/aggpas/original_demos_files/gouraud_mesh_s.png diff --git a/docs/aggpas/original_demos_files/gouraud_s.png b/docs/aggpas/original_demos_files/gouraud_s.png Binary files differnew file mode 100644 index 00000000..6ca61ab5 --- /dev/null +++ b/docs/aggpas/original_demos_files/gouraud_s.png diff --git a/docs/aggpas/original_demos_files/gpc_test_s.gif b/docs/aggpas/original_demos_files/gpc_test_s.gif Binary files differnew file mode 100644 index 00000000..9a1508e7 --- /dev/null +++ b/docs/aggpas/original_demos_files/gpc_test_s.gif diff --git a/docs/aggpas/original_demos_files/gradient_focal_s.png b/docs/aggpas/original_demos_files/gradient_focal_s.png Binary files differnew file mode 100644 index 00000000..e30a14a5 --- /dev/null +++ b/docs/aggpas/original_demos_files/gradient_focal_s.png diff --git a/docs/aggpas/original_demos_files/gradients_s.png b/docs/aggpas/original_demos_files/gradients_s.png Binary files differnew file mode 100644 index 00000000..4ae8cd9e --- /dev/null +++ b/docs/aggpas/original_demos_files/gradients_s.png diff --git a/docs/aggpas/original_demos_files/graph_test_s.gif b/docs/aggpas/original_demos_files/graph_test_s.gif Binary files differnew file mode 100644 index 00000000..86f232e7 --- /dev/null +++ b/docs/aggpas/original_demos_files/graph_test_s.gif diff --git a/docs/aggpas/original_demos_files/idea_s.gif b/docs/aggpas/original_demos_files/idea_s.gif Binary files differnew file mode 100644 index 00000000..7b52d3cd --- /dev/null +++ b/docs/aggpas/original_demos_files/idea_s.gif diff --git a/docs/aggpas/original_demos_files/image1_s.jpg b/docs/aggpas/original_demos_files/image1_s.jpg Binary files differnew file mode 100644 index 00000000..ce7765af --- /dev/null +++ b/docs/aggpas/original_demos_files/image1_s.jpg diff --git a/docs/aggpas/original_demos_files/image_alpha_s.png b/docs/aggpas/original_demos_files/image_alpha_s.png Binary files differnew file mode 100644 index 00000000..9ab2222c --- /dev/null +++ b/docs/aggpas/original_demos_files/image_alpha_s.png diff --git a/docs/aggpas/original_demos_files/image_filters2_s.png b/docs/aggpas/original_demos_files/image_filters2_s.png Binary files differnew file mode 100644 index 00000000..a404cdf0 --- /dev/null +++ b/docs/aggpas/original_demos_files/image_filters2_s.png diff --git a/docs/aggpas/original_demos_files/image_filters_s.jpg b/docs/aggpas/original_demos_files/image_filters_s.jpg Binary files differnew file mode 100644 index 00000000..c2d48378 --- /dev/null +++ b/docs/aggpas/original_demos_files/image_filters_s.jpg diff --git a/docs/aggpas/original_demos_files/image_fltr_graph_s.gif b/docs/aggpas/original_demos_files/image_fltr_graph_s.gif Binary files differnew file mode 100644 index 00000000..f062e74e --- /dev/null +++ b/docs/aggpas/original_demos_files/image_fltr_graph_s.gif diff --git a/docs/aggpas/original_demos_files/image_perspective_s.jpg b/docs/aggpas/original_demos_files/image_perspective_s.jpg Binary files differnew file mode 100644 index 00000000..fdfb369b --- /dev/null +++ b/docs/aggpas/original_demos_files/image_perspective_s.jpg diff --git a/docs/aggpas/original_demos_files/image_resample_s.jpg b/docs/aggpas/original_demos_files/image_resample_s.jpg Binary files differnew file mode 100644 index 00000000..f6a6a7da --- /dev/null +++ b/docs/aggpas/original_demos_files/image_resample_s.jpg diff --git a/docs/aggpas/original_demos_files/image_transforms_s.jpg b/docs/aggpas/original_demos_files/image_transforms_s.jpg Binary files differnew file mode 100644 index 00000000..1453b24b --- /dev/null +++ b/docs/aggpas/original_demos_files/image_transforms_s.jpg diff --git a/docs/aggpas/original_demos_files/line_patterns_clip_s.png b/docs/aggpas/original_demos_files/line_patterns_clip_s.png Binary files differnew file mode 100644 index 00000000..1115c7ce --- /dev/null +++ b/docs/aggpas/original_demos_files/line_patterns_clip_s.png diff --git a/docs/aggpas/original_demos_files/line_patterns_s.gif b/docs/aggpas/original_demos_files/line_patterns_s.gif Binary files differnew file mode 100644 index 00000000..117b7642 --- /dev/null +++ b/docs/aggpas/original_demos_files/line_patterns_s.gif diff --git a/docs/aggpas/original_demos_files/link.gif b/docs/aggpas/original_demos_files/link.gif Binary files differnew file mode 100644 index 00000000..76a532cf --- /dev/null +++ b/docs/aggpas/original_demos_files/link.gif diff --git a/docs/aggpas/original_demos_files/lion_lens_s.gif b/docs/aggpas/original_demos_files/lion_lens_s.gif Binary files differnew file mode 100644 index 00000000..92a214eb --- /dev/null +++ b/docs/aggpas/original_demos_files/lion_lens_s.gif diff --git a/docs/aggpas/original_demos_files/lion_outline_s.gif b/docs/aggpas/original_demos_files/lion_outline_s.gif Binary files differnew file mode 100644 index 00000000..fa722027 --- /dev/null +++ b/docs/aggpas/original_demos_files/lion_outline_s.gif diff --git a/docs/aggpas/original_demos_files/lion_s.png b/docs/aggpas/original_demos_files/lion_s.png Binary files differnew file mode 100644 index 00000000..feb5cd86 --- /dev/null +++ b/docs/aggpas/original_demos_files/lion_s.png diff --git a/docs/aggpas/original_demos_files/mol_view_s.gif b/docs/aggpas/original_demos_files/mol_view_s.gif Binary files differnew file mode 100644 index 00000000..bf87a2bf --- /dev/null +++ b/docs/aggpas/original_demos_files/mol_view_s.gif diff --git a/docs/aggpas/original_demos_files/multi_clip_s.gif b/docs/aggpas/original_demos_files/multi_clip_s.gif Binary files differnew file mode 100644 index 00000000..5a88ab10 --- /dev/null +++ b/docs/aggpas/original_demos_files/multi_clip_s.gif diff --git a/docs/aggpas/original_demos_files/pattern_fill_s.gif b/docs/aggpas/original_demos_files/pattern_fill_s.gif Binary files differnew file mode 100644 index 00000000..e51bf2c8 --- /dev/null +++ b/docs/aggpas/original_demos_files/pattern_fill_s.gif diff --git a/docs/aggpas/original_demos_files/pattern_perspective_s.jpg b/docs/aggpas/original_demos_files/pattern_perspective_s.jpg Binary files differnew file mode 100644 index 00000000..6e10ea8f --- /dev/null +++ b/docs/aggpas/original_demos_files/pattern_perspective_s.jpg diff --git a/docs/aggpas/original_demos_files/pattern_resample_s.jpg b/docs/aggpas/original_demos_files/pattern_resample_s.jpg Binary files differnew file mode 100644 index 00000000..6ef02ee4 --- /dev/null +++ b/docs/aggpas/original_demos_files/pattern_resample_s.jpg diff --git a/docs/aggpas/original_demos_files/perspective_s.gif b/docs/aggpas/original_demos_files/perspective_s.gif Binary files differnew file mode 100644 index 00000000..9c2aeaac --- /dev/null +++ b/docs/aggpas/original_demos_files/perspective_s.gif diff --git a/docs/aggpas/original_demos_files/polymorphic_renderer_s.gif b/docs/aggpas/original_demos_files/polymorphic_renderer_s.gif Binary files differnew file mode 100644 index 00000000..04311693 --- /dev/null +++ b/docs/aggpas/original_demos_files/polymorphic_renderer_s.gif diff --git a/docs/aggpas/original_demos_files/raster_text_s.gif b/docs/aggpas/original_demos_files/raster_text_s.gif Binary files differnew file mode 100644 index 00000000..015c02d5 --- /dev/null +++ b/docs/aggpas/original_demos_files/raster_text_s.gif diff --git a/docs/aggpas/original_demos_files/rasterizer_compound_s.png b/docs/aggpas/original_demos_files/rasterizer_compound_s.png Binary files differnew file mode 100644 index 00000000..2a4305a7 --- /dev/null +++ b/docs/aggpas/original_demos_files/rasterizer_compound_s.png diff --git a/docs/aggpas/original_demos_files/rasterizers2_s.gif b/docs/aggpas/original_demos_files/rasterizers2_s.gif Binary files differnew file mode 100644 index 00000000..7bc6efb8 --- /dev/null +++ b/docs/aggpas/original_demos_files/rasterizers2_s.gif diff --git a/docs/aggpas/original_demos_files/rasterizers_s.gif b/docs/aggpas/original_demos_files/rasterizers_s.gif Binary files differnew file mode 100644 index 00000000..a69036a5 --- /dev/null +++ b/docs/aggpas/original_demos_files/rasterizers_s.gif diff --git a/docs/aggpas/original_demos_files/rounded_rect_s.gif b/docs/aggpas/original_demos_files/rounded_rect_s.gif Binary files differnew file mode 100644 index 00000000..f5eb207a --- /dev/null +++ b/docs/aggpas/original_demos_files/rounded_rect_s.gif diff --git a/docs/aggpas/original_demos_files/scanline_boolean2_s.gif b/docs/aggpas/original_demos_files/scanline_boolean2_s.gif Binary files differnew file mode 100644 index 00000000..f29b9530 --- /dev/null +++ b/docs/aggpas/original_demos_files/scanline_boolean2_s.gif diff --git a/docs/aggpas/original_demos_files/scanline_boolean_s.gif b/docs/aggpas/original_demos_files/scanline_boolean_s.gif Binary files differnew file mode 100644 index 00000000..80c2947b --- /dev/null +++ b/docs/aggpas/original_demos_files/scanline_boolean_s.gif diff --git a/docs/aggpas/original_demos_files/simple_blur_s.gif b/docs/aggpas/original_demos_files/simple_blur_s.gif Binary files differnew file mode 100644 index 00000000..be6c88bf --- /dev/null +++ b/docs/aggpas/original_demos_files/simple_blur_s.gif diff --git a/docs/aggpas/original_demos_files/trans_curve1_s.gif b/docs/aggpas/original_demos_files/trans_curve1_s.gif Binary files differnew file mode 100644 index 00000000..478f3f4b --- /dev/null +++ b/docs/aggpas/original_demos_files/trans_curve1_s.gif diff --git a/docs/aggpas/original_demos_files/trans_curve2_s.gif b/docs/aggpas/original_demos_files/trans_curve2_s.gif Binary files differnew file mode 100644 index 00000000..7a81795c --- /dev/null +++ b/docs/aggpas/original_demos_files/trans_curve2_s.gif diff --git a/docs/aggpas/original_demos_files/trans_polar_s.gif b/docs/aggpas/original_demos_files/trans_polar_s.gif Binary files differnew file mode 100644 index 00000000..cc750f16 --- /dev/null +++ b/docs/aggpas/original_demos_files/trans_polar_s.gif diff --git a/docs/aggpas/scanlines.agdoc.html b/docs/aggpas/scanlines.agdoc.html new file mode 100644 index 00000000..d85308fe --- /dev/null +++ b/docs/aggpas/scanlines.agdoc.html @@ -0,0 +1,195 @@ +<html><head><title>Anti-Grain Geometry - Scanlines and Scanline +Renderers</title> +<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> +<link rel="stylesheet" type="text/css" +href="scanlines.agdoc_files/agg.css"> +</head><body><a name="PAGE_SCANLINES"><b></b></a> + + +<table style="margin: 0px;" height="1px" width="640px" border="0" +cellpadding="0" cellspacing="0"> +<tbody><tr> +<td bgcolor="#583927"></td> +</tr> +</tbody></table> +<table style="margin: 0px;" width="640px" border="0" cellpadding="0" +cellspacing="0"> +<tbody><tr> +<td> +<table style="margin: 0px;" width="170px" border="0" cellpadding="0" +cellspacing="0"> +<tbody><tr><td><a href="http://www.antigrain.com/index.html" +class="mpmenu">Home/</a></td></tr> +<tr><td><a href="http://www.antigrain.com/doc/index.html" class="mpmenu">Table + of Content/</a></td></tr> +<tr><td><a href="" class="mpmenu"></a></td></tr> +<tr><td><a href="" class="mpmenu"></a></td></tr> +<tr><td><a href="" class="mpmenu"></a></td></tr> +<tr><td><a href="" class="mpmenu"></a></td></tr> +</tbody></table> +</td> +<td width="1px" bgcolor="#583927"></td> +<td style="text-align: right;" valign="top" width="450px"> +<table style="margin: 0px;" border="0" cellpadding="0" cellspacing="0"> +<tbody><tr> +<td><img src="scanlines.agdoc_files/agg_logo.gif" border="0"></td> +</tr> +<tr> +<td> +<table style="margin: 0px;" border="0" cellpadding="0" cellspacing="0"> +<tbody><tr height="15px"> +<td> <a class="topmenu" +href="http://www.antigrain.com/news/index.html">News</a> </td> +<td width="1px" bgcolor="#8e521d"></td> +<td> <a class="topmenu" +href="http://www.antigrain.com/doc/index.html">Docs</a> </td> +<td width="1px" bgcolor="#8e521d"></td> +<td> <a class="topmenu" +href="http://www.antigrain.com/download/index.html">Download</a> </td> +<td width="1px" bgcolor="#8e521d"></td> +<td> <a class="topmenu" +href="http://www.antigrain.com/maillist/index.html">Mailing List</a> </td> +<td width="1px" bgcolor="#8e521d"></td> +<td> <a class="topmenu" +href="http://www.antigrain.com/cvs/index.html">CVS</a> </td> +</tr> +</tbody></table> +</td> +</tr> +</tbody></table> +</td> +</tr> +</tbody></table> +<table style="margin: 0px;" height="1px" width="640px" bgcolor="#583927" + border="0" cellpadding="0" cellspacing="0"><tbody><tr><td></td></tr></tbody></table> + + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p> +</p></td></tr></tbody></table> + +<table width="640px"><tbody><tr><td><h1>Scanlines and Scanline Renderers</h1></td></tr></tbody></table> + +<table class="toc" width="640px"><tbody><tr><td> + <div style="margin-left: 2em; padding: 3px; font-size: 14px;"><a +href="#toc0001"><b>Scanline Containers</b></a> + <div style="margin-left: 2em; font-size: 12px;"><a +href="#toc0002">Introduction</a></div> + <div style="margin-left: 2em; font-size: 12px;"><a +href="#toc0003">Interfaces</a> + <div style="margin-left: 2em; font-size: 12px;"><a +href="#toc0004">Filling Interface (put)</a></div> + <div style="margin-left: 2em; font-size: 12px;"><a +href="#toc0005">Iterating Interface (get)</a></div></div></div> + <div style="margin-left: 2em; padding: 3px; font-size: 14px;"><a +href="#toc0006"><b>Scanline Renderers</b></a></div> + +</td></tr></tbody></table> + + +<h2>Scanline Containers<a name="toc0001"></a></h2> + +<h3>Introduction<a name="toc0002"></a></h3> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>The +low level renderers operate with +simplest data and they are very simple too. In fact, the pixel format +renderers are not the obligatory part of the library and can be +replaced or rewritten. For example, if you have an API with similar +functionality, but hardware accelerated, it will be better to use it +instead of pure software blending (the low level renderers are +essentially alpha-blenders). It's also possible to use Intel SSE/SSE2 +to write optimized renderers. All other rendering functionality in +AGG is based on these simple classes.</p></td></tr></tbody></table> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>To +draw Anti-Aliased primitives one shoud <b>rasterize</b> them first. +The primary rasterization technique in AGG is scanline based. That is, +a polygon is converted into a number of horizontal scanlines and then +the scanlines are being rendered one by one. Again, the scanline +rasterizer is not the only class that can produce scanlines. It can +be some container or even your own super-ultra-mega rasterizer.</p></td></tr></tbody></table> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>To +transfer information from a rasterizer to the scanline renderer +there scanline containers are used. +A scanline consists of a number of horizontal, non-intersecting spans. +All spans must be ordered by X. It means that there is no sorting +operation provided, the order must be perserved when adding spans +to the scanline. If the order is not guaranteed it can result in +undefined behaviour.</p></td></tr></tbody></table> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>In <b>AGG</b> + there are three types of scanline containers: +</p><ul type="disc"> +<li><code>scanline_u</code> - unpacked scaline container</li> +<li><code>scanline_p</code> - packed scanline container</li> +<li><code><a +href="http://www.antigrain.com/__code/include/agg_scanline_bin.h.html#scanline_bin">scanline_bin</a></code> + - container for binary, “aliased” scanlines</li></ul><p></p></td></tr></tbody></table> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>First + two containers can keep <b><nobr>Anti-Aliasing</nobr></b> information, +the third one cannot.</p></td></tr></tbody></table> + +<table class="warning" width="640px"><tbody><tr><td><b>IMPORTANT!</b><br> +All the scanline containers are optimized for speed, not for +memory usage. In fact, it allocates memory for the worst case, +so there is some overhead. It's not critical when you use only +few scanline containers, but it's not a good idea to use an +array of scanlines to store the whole shape because it will take +more memory than the resulting image. +</td></tr></tbody></table> + + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>The +difference between <b>packed</b> and <b>unpacked</b> scanline +containers is that the <b>unpacked</b> scaline always keeps the +coverage values for all pixels including the ones that are +fully covered by a polygon. In the <b>packed</b> scanline +all pixels with the same coverage value are merged into <b>solid</b> +spans. +</p></td></tr></tbody></table><table width="640px"><tbody><tr><td><center><img + src="scanlines.agdoc_files/scanline_u.gif" title="" border="0"><br><i></i></center></td></tr></tbody></table> +<table width="640px"><tbody><tr><td><center><img +src="scanlines.agdoc_files/scanline_p.gif" title="" border="0"><br><i></i></center></td></tr></tbody></table> + +<table width="640px"><tbody><tr><td style="text-align: justify;"><p>It +can seem it's always better to use the packed version, but in +practice it's not so. The scanline_p works faster when rendering +large solid polygons, that is when the area of the polygon is +much larger than the perimeter in the meaning of the number +of pixels. But when renering text it's definitely better to use +the scanline_u because of much less number of processed spans +The difference is about three times and the number of spans +is also important for the overall performance. Besides, in most +of the span generators, such as gradients, Gouraud shader, or +image transformers, the number of spans becomes even more critical, +and so, the scanline_p is not used there.</p></td></tr></tbody></table> + + +<h3>Interfaces<a name="toc0003"></a></h3> + +<h4>Filling Interface (put)<a name="toc0004"></a></h4> + +<h4>Iterating Interface (get)<a name="toc0005"></a></h4> + + +<br><h2>Scanline Renderers<a name="toc0006"></a></h2> + +<br><table style="margin: 0px;" height="1px" width="640px" +bgcolor="#583927" border="0" cellpadding="0" cellspacing="0"><tbody><tr><td></td></tr></tbody></table> +<table width="640px" border="0" cellpadding="0" cellspacing="0"> +<tbody><tr><td><center><span class="authors"> +Copyright <span class="larger">©</span> 2002-2006 +<a href="http://www.antigrain.com/mcseem/index.html"><b>Maxim Shemanarev</b></a> +</span></center></td></tr> +<tr><td><center><span class="authors"> +Web Design and Programming +<a href="http://www.antigrain.com/mcseem/index.html"><b>Maxim Shemanarev</b></a> +</span></center></td></tr> +</tbody></table> +<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br> +<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br> +<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br> +<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br> +</body></html>
\ No newline at end of file diff --git a/docs/aggpas/scanlines.agdoc_files/agg.css b/docs/aggpas/scanlines.agdoc_files/agg.css new file mode 100644 index 00000000..997d9d07 --- /dev/null +++ b/docs/aggpas/scanlines.agdoc_files/agg.css @@ -0,0 +1,239 @@ +BODY +{ + font-family:Verdana, Arial, Tahoma; + font-size:12px; + color:#160801; + background-color:#ffffff; + text-align:justify; + padding:5px; +} + +P, UL, OL, DL +{ + font-family:Verdana, Arial, Tahoma; + font-size:12px; + color:#160801; + margin-bottom:0px; + margin-top:0px; +} + + +.larger +{ + font-size:14px; +} + +LI +{ + padding:3px; +} + +HR +{ + color:#583927; + height:1px; +} + +H1 +{ + font-family:Verdana, Arial, Tahoma; + font-size:28px; + font-weight:bolder; + text-align:center; + color:#583927; + margin:0px; +} + +H1 SPAN.subtitle +{ + font-family:Verdana, Arial, Tahoma; + font-size:18px; + font-weight:lighter; +} + + +H2 +{ + font-family:Verdana, Arial, Tahoma; + font-size:26px; + font-weight:normal; + text-align:left; + color:#583927; +} + +H3 +{ + font-family:Verdana, Arial, Tahoma; + font-size:20px; + font-weight:normal; + text-align:left; + color:#583927; +} + +H4 +{ + font-family:Verdana, Arial, Tahoma; + font-size:16px; + font-weight:bold; + text-align:left; + color:#583927; +} + +H5 +{ + font-family:Verdana, Arial, Tahoma; + font-size:14px; + font-weight:bold; + text-align:left; + color:#583927; +} + +TABLE +{ + margin:5px; +} + +TD +{ + font-family:Verdana, Arial, Tahoma; + font-size:12px; +} + +TH +{ + font-family:Verdana, Arial, Tahoma; + background-color:#d4d4d4; + font-size:12px; +} + + +PRE +{ + padding: 5px; + border: gray 1px solid; + background-color:#f4f4f4; + color:#130f00; + font-family:"courier new", courier,mono; + font-size:12px; + margin:0px; +} + +TT, CODE +{ + font-family:"courier new", courier,mono; + font-size:14px; + color:#000070; +} + +.warning, .warning TD +{ + background-color:#fcf6f6; + color:#793131; + padding:0.5em; + font-family:Verdana, Arial, Tahoma; + font-size:12px; + text-align:justify; +} + +.note, .note TD +{ + background-color:#f0fafa; + color:#506580; + padding:0.5em; + font-family:Verdana, Arial, Tahoma; + font-size:12px; + text-align:justify; +} + +.quote, .quote TD +{ + background-color:#f0fafa; + color:#000540; + padding:0.5em; + font-family:Verdana, Arial, Tahoma; + font-size:12px; + text-align:justify; +} + +.tip, .tip TD +{ + background-color:#fbfff6; + color:#68771e; + padding:0.5em; + font-family:Verdana, Arial, Tahoma; + font-size:12px; + text-align:justify; +} + +.tbl TD +{ + background-color:#f4f4f4; + font-family:Verdana, Arial, Tahoma; + font-size:12px; + text-align:left; + padding:3px; +} + +.toc TD +{ + font-family:Verdana, Arial, Tahoma; + text-align:left; + padding:3px; +} + +.title {font-family:Verdana, Arial, Tahoma;} + +.warning P, +.warning PRE, +.note P, +.note PRE, +.tip P, +.tip PRE {margin:0.3em 0em 0.1em 0em;} + +.warning .code {background-color:#fcf6f6;} +.note .code {background-color:#f0fafa;} +.tip .code {background-color:#fbfff6;} + +A {text-decoration:none; color:#700000;} +A:visited {text-decoration:none; color:#85585d;} +A:link {text-decoration:none;} +A:hover {text-decoration:underline;} + +.topmenu,a.topmenu:visited,a.topmenu:hover,a.topmenu:active,a.topmenu:link +{ + font-family: Arial, Tahoma, Helvetica, sans-serif; + font-size: 11px; + font-weight: bold; + text-decoration: none; + color: #582218; +} + +.mpmenu,a.mpmenu:visited,a.mpmenu:hover,a.mpmenu:active,a.mpmenu:link +{ + font-family: Arial, Tahoma, Helvetica, sans-serif; + font-size: 12px; + font-weight: bold; + text-decoration: none; + color: #582218; +} + +.tah +{ + font-family: Tahoma, Arial, Helvetica, sans-serif; + font-size: 12px; + color: #582218; +} + +.authors +{ + font-size:10px; +} + +span.rem {color:#4c8d00;} +span.kw1 {color:#000d8e;} +span.kw2 {color:#0075ca;} +span.kw3 {color:#004645;} +span.kw4 {color:#673517;} +span.op {color:#4a006d;} +span.str {color:#ab2500;} +span.num {color:#a74c3f;} diff --git a/docs/aggpas/scanlines.agdoc_files/agg_logo.gif b/docs/aggpas/scanlines.agdoc_files/agg_logo.gif Binary files differnew file mode 100644 index 00000000..ee5c570a --- /dev/null +++ b/docs/aggpas/scanlines.agdoc_files/agg_logo.gif diff --git a/docs/aggpas/scanlines.agdoc_files/scanline_p.gif b/docs/aggpas/scanlines.agdoc_files/scanline_p.gif Binary files differnew file mode 100644 index 00000000..5fbc368c --- /dev/null +++ b/docs/aggpas/scanlines.agdoc_files/scanline_p.gif diff --git a/docs/aggpas/scanlines.agdoc_files/scanline_u.gif b/docs/aggpas/scanlines.agdoc_files/scanline_u.gif Binary files differnew file mode 100644 index 00000000..8c811b93 --- /dev/null +++ b/docs/aggpas/scanlines.agdoc_files/scanline_u.gif |