Gtk4-tutorial/docs/sec24.html

342 lines
25 KiB
HTML
Raw Normal View History

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="generator" content="pandoc" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
<title>GTK 4 tutorial</title>
<style>
code{white-space: pre-wrap;}
span.smallcaps{font-variant: small-caps;}
span.underline{text-decoration: underline;}
div.column{display: inline-block; vertical-align: top; width: 50%;}
div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;}
ul.task-list{list-style: none;}
pre{overflow: visible;}
pre > code.sourceCode { white-space: pre; position: relative; }
pre > code.sourceCode > span { display: inline-block; line-height: 1.25; }
pre > code.sourceCode > span:empty { height: 1.2em; }
code.sourceCode > span { color: inherit; text-decoration: inherit; }
div.sourceCode { margin: 1em 0; }
pre.sourceCode { margin: 0; }
@media screen {
div.sourceCode { overflow: auto; }
}
@media print {
pre > code.sourceCode { white-space: pre-wrap; }
pre > code.sourceCode > span { text-indent: -5em; padding-left: 5em; }
}
pre.numberSource code
{ counter-reset: source-line 0; }
pre.numberSource code > span
{ position: relative; left: -4em; counter-increment: source-line; }
pre.numberSource code > span > a:first-child::after
{ content: counter(source-line);
position: relative; left: -1em; text-align: right; vertical-align: baseline;
border: none; display: inline-block;
-webkit-touch-callout: none; -webkit-user-select: none;
-khtml-user-select: none; -moz-user-select: none;
-ms-user-select: none; user-select: none;
padding: 0 4px; width: 4em;
color: #aaaaaa;
}
pre.numberSource { margin-left: 3em; border-left: 1px solid #aaaaaa; padding-left: 4px; }
div.sourceCode
{ }
@media screen {
pre > code.sourceCode > span > a:first-child::before { text-decoration: underline; }
}
code span.al { color: #ff0000; font-weight: bold; } /* Alert */
code span.an { color: #60a0b0; font-weight: bold; font-style: italic; } /* Annotation */
code span.at { color: #7d9029; } /* Attribute */
code span.bn { color: #40a070; } /* BaseN */
code span.bu { } /* BuiltIn */
code span.cf { color: #007020; font-weight: bold; } /* ControlFlow */
code span.ch { color: #4070a0; } /* Char */
code span.cn { color: #880000; } /* Constant */
code span.co { color: #60a0b0; font-style: italic; } /* Comment */
code span.cv { color: #60a0b0; font-weight: bold; font-style: italic; } /* CommentVar */
code span.do { color: #ba2121; font-style: italic; } /* Documentation */
code span.dt { color: #902000; } /* DataType */
code span.dv { color: #40a070; } /* DecVal */
code span.er { color: #ff0000; font-weight: bold; } /* Error */
code span.ex { } /* Extension */
code span.fl { color: #40a070; } /* Float */
code span.fu { color: #06287e; } /* Function */
code span.im { } /* Import */
code span.in { color: #60a0b0; font-weight: bold; font-style: italic; } /* Information */
code span.kw { color: #007020; font-weight: bold; } /* Keyword */
code span.op { color: #666666; } /* Operator */
code span.ot { color: #007020; } /* Other */
code span.pp { color: #bc7a00; } /* Preprocessor */
code span.sc { color: #4070a0; } /* SpecialChar */
code span.ss { color: #bb6688; } /* SpecialString */
code span.st { color: #4070a0; } /* String */
code span.va { color: #19177c; } /* Variable */
code span.vs { color: #4070a0; } /* VerbatimString */
code span.wa { color: #60a0b0; font-weight: bold; font-style: italic; } /* Warning */
div.sourceCode { margin: 10px; padding: 16px 10px 8px 10px; border: 2px solid silver; background-color: ghostwhite; overflow-x:scroll}
pre:not(.sourceCode) { margin: 10px; padding: 16px 10px 8px 10px; border: 2px solid silver; background-color: ghostwhite; overflow-x:scroll}
table {margin-left: auto; margin-right: auto; border-collapse: collapse; border: 1px solid;}
th {padding: 2px 6px; border: 1px solid; background-color: ghostwhite;}
td {padding: 2px 6px; border: 1px solid;}
img {display: block; margin-left: auto; margin-right: auto;}
figcaption {text-align: center;}
</style>
</head>
<body style="padding-top: 70px;">
<div class="container">
<nav class="navbar fixed-top navbar-expand-lg navbar-dark bg-primary">
<div class="container-fluid">
<span class="navbar-brand">Gtk4 tutorial</span>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav me-auto mb-2 mb-lg-0">
<li class="nav-item">
<a class="nav-link" href="index.html">Home</a>
</li>
<li class="nav-item">
<a class="nav-link" href="sec23.html">Prev: section23</a>
</li>
<li class="nav-item">
<a class="nav-link" href="sec25.html">Next: section25</a>
</li>
</ul>
</div>
</div>
</nav>
<h1 id="gtkdrawingarea-and-cairo">GtkDrawingArea and Cairo</h1>
2023-07-23 04:49:22 +02:00
<p>If you want to draw shapes or paint images dynamically on the screen,
use the GtkDrawingArea widget.</p>
<p>GtkDrawingArea provides a cairo drawing context. You can draw images
with cairo library functions. This section describes:</p>
<ol type="1">
2023-07-23 04:49:22 +02:00
<li>Cairo, but briefly</li>
<li>GtkDrawingArea, with a very simple example.</li>
</ol>
<h2 id="cairo">Cairo</h2>
2023-07-23 04:49:22 +02:00
<p>Cairo is a drawing library for two dimensional graphics. There are a
lot of documents on <a href="https://www.cairographics.org/">Cairos
website</a>. If you arent familiar with Cairo, it is worth reading the
<a href="https://www.cairographics.org/tutorial/">tutorial</a>.</p>
<p>The following is an introduction to the Cairo library. First, you
need to know surfaces, sources, masks, destinations, cairo context and
transformations.</p>
<ul>
<li>A surface represents an image. It is like a canvas. We can draw
shapes and images with different colors on surfaces.</li>
<li>The source pattern, or simply source, is like paint, which will be
transferred to destination surface by cairo functions.</li>
<li>The mask describes the area to be used in the copy;</li>
<li>The destination is a target surface;</li>
<li>The cairo context manages the transfer from source to destination,
through mask with its functions; For example, <code>cairo_stroke</code>
is a function to draw a path to the destination by the transfer.</li>
<li>A transformation can be applied before the transfer completes. The
transformation which is applied is called affine, which is a
mathematical term meaning transofrmations that preserve straight lines.
2023-07-23 04:49:22 +02:00
Scaling, rotating, reflecting, shearing and translating are examples of
affine transformations. They are mathematically represented by matrix
multiplication and vector addition. In this section we dont use it,
instead we will only use the identity transformation. This means that
the coordinates in the source and mask are the same as the coordinates
in destination.</li>
</ul>
<figure>
<img src="image/cairo.png" alt="Stroke a rectangle" />
<figcaption aria-hidden="true">Stroke a rectangle</figcaption>
</figure>
<p>The instruction is as follows:</p>
<ol type="1">
<li>Create a surface. This will be the destination.</li>
<li>Create a cairo context with the surface, the surface will be the
destination of the context.</li>
<li>Create a source pattern within the context.</li>
<li>Create paths, which are lines, rectangles, arcs, texts or more
complicated shapes in the mask.</li>
<li>Use a drawing operator such as <code>cairo_stroke</code> to transfer
the paint in the source to the destination.</li>
<li>Save the destination surface to a file if necessary.</li>
</ol>
<p>Heres a simple example program that draws a small square and saves
it as a png file. The path of the file is
<code>src/misc/cairo.c</code>.</p>
<div class="sourceCode" id="cb1"><pre
class="sourceCode numberSource C numberLines"><code class="sourceCode c"><span id="cb1-1"><a href="#cb1-1"></a><span class="pp">#include </span><span class="im">&lt;cairo.h&gt;</span></span>
<span id="cb1-2"><a href="#cb1-2"></a></span>
<span id="cb1-3"><a href="#cb1-3"></a><span class="dt">int</span></span>
<span id="cb1-4"><a href="#cb1-4"></a>main <span class="op">(</span><span class="dt">int</span> argc<span class="op">,</span> <span class="dt">char</span> <span class="op">**</span>argv<span class="op">)</span></span>
<span id="cb1-5"><a href="#cb1-5"></a><span class="op">{</span></span>
<span id="cb1-6"><a href="#cb1-6"></a> cairo_surface_t <span class="op">*</span>surface<span class="op">;</span></span>
<span id="cb1-7"><a href="#cb1-7"></a> cairo_t <span class="op">*</span>cr<span class="op">;</span></span>
<span id="cb1-8"><a href="#cb1-8"></a> <span class="dt">int</span> width <span class="op">=</span> <span class="dv">100</span><span class="op">;</span></span>
<span id="cb1-9"><a href="#cb1-9"></a> <span class="dt">int</span> height <span class="op">=</span> <span class="dv">100</span><span class="op">;</span></span>
<span id="cb1-10"><a href="#cb1-10"></a> <span class="dt">int</span> square_size <span class="op">=</span> <span class="fl">40.0</span><span class="op">;</span></span>
<span id="cb1-11"><a href="#cb1-11"></a></span>
<span id="cb1-12"><a href="#cb1-12"></a> <span class="co">/* Create surface and cairo */</span></span>
<span id="cb1-13"><a href="#cb1-13"></a> surface <span class="op">=</span> cairo_image_surface_create <span class="op">(</span>CAIRO_FORMAT_RGB24<span class="op">,</span> width<span class="op">,</span> height<span class="op">);</span></span>
<span id="cb1-14"><a href="#cb1-14"></a> cr <span class="op">=</span> cairo_create <span class="op">(</span>surface<span class="op">);</span></span>
<span id="cb1-15"><a href="#cb1-15"></a></span>
<span id="cb1-16"><a href="#cb1-16"></a> <span class="co">/* Drawing starts here. */</span></span>
<span id="cb1-17"><a href="#cb1-17"></a> <span class="co">/* Paint the background white */</span></span>
<span id="cb1-18"><a href="#cb1-18"></a> cairo_set_source_rgb <span class="op">(</span>cr<span class="op">,</span> <span class="fl">1.0</span><span class="op">,</span> <span class="fl">1.0</span><span class="op">,</span> <span class="fl">1.0</span><span class="op">);</span></span>
<span id="cb1-19"><a href="#cb1-19"></a> cairo_paint <span class="op">(</span>cr<span class="op">);</span></span>
<span id="cb1-20"><a href="#cb1-20"></a> <span class="co">/* Draw a black rectangle */</span></span>
<span id="cb1-21"><a href="#cb1-21"></a> cairo_set_source_rgb <span class="op">(</span>cr<span class="op">,</span> <span class="fl">0.0</span><span class="op">,</span> <span class="fl">0.0</span><span class="op">,</span> <span class="fl">0.0</span><span class="op">);</span></span>
<span id="cb1-22"><a href="#cb1-22"></a> cairo_set_line_width <span class="op">(</span>cr<span class="op">,</span> <span class="fl">2.0</span><span class="op">);</span></span>
<span id="cb1-23"><a href="#cb1-23"></a> cairo_rectangle <span class="op">(</span>cr<span class="op">,</span></span>
<span id="cb1-24"><a href="#cb1-24"></a> width<span class="op">/</span><span class="fl">2.0</span> <span class="op">-</span> square_size<span class="op">/</span><span class="dv">2</span><span class="op">,</span></span>
<span id="cb1-25"><a href="#cb1-25"></a> height<span class="op">/</span><span class="fl">2.0</span> <span class="op">-</span> square_size<span class="op">/</span><span class="dv">2</span><span class="op">,</span></span>
<span id="cb1-26"><a href="#cb1-26"></a> square_size<span class="op">,</span></span>
<span id="cb1-27"><a href="#cb1-27"></a> square_size<span class="op">);</span></span>
<span id="cb1-28"><a href="#cb1-28"></a> cairo_stroke <span class="op">(</span>cr<span class="op">);</span></span>
<span id="cb1-29"><a href="#cb1-29"></a></span>
<span id="cb1-30"><a href="#cb1-30"></a> <span class="co">/* Write the surface to a png file and clean up cairo and surface. */</span></span>
<span id="cb1-31"><a href="#cb1-31"></a> cairo_surface_write_to_png <span class="op">(</span>surface<span class="op">,</span> <span class="st">&quot;rectangle.png&quot;</span><span class="op">);</span></span>
<span id="cb1-32"><a href="#cb1-32"></a> cairo_destroy <span class="op">(</span>cr<span class="op">);</span></span>
<span id="cb1-33"><a href="#cb1-33"></a> cairo_surface_destroy <span class="op">(</span>surface<span class="op">);</span></span>
<span id="cb1-34"><a href="#cb1-34"></a></span>
<span id="cb1-35"><a href="#cb1-35"></a> <span class="cf">return</span> <span class="dv">0</span><span class="op">;</span></span>
<span id="cb1-36"><a href="#cb1-36"></a><span class="op">}</span></span></code></pre></div>
<ul>
<li>1: Includes the header file of Cairo.</li>
<li>6: <code>cairo_surface_t</code> is the type of a surface.</li>
<li>7: <code>cairo_t</code> is the type of a cairo context.</li>
<li>8-10: <code>width</code> and <code>height</code> are the size of
<code>surface</code>. <code>square_size</code> is the size of a square
to be drawn on the surface.</li>
<li>13: <code>cairo_image_surface_create</code> creates an image
surface. <code>CAIRO_FORMAT_RGB24</code> is a constant which means that
each pixel has red, green and blue data, and each data point is an 8
bits number (for 24 bits in total). Modern displays have this type of
color depth. Width and height are in pixels and given as integers.</li>
<li>14: Creates cairo context. The surface given as an argument will be
the destination of the context.</li>
<li>18: <code>cairo_set_source_rgb</code> creates a source pattern,
2023-07-23 04:49:22 +02:00
which is a solid white paint. The second to fourth arguments are red,
green and blue color values respectively, and they are of type float.
The values are between zero (0.0) and one (1.0). Black is (0.0,0.0,0.0)
and white is (1.0,1.0,1.0).</li>
<li>19: <code>cairo_paint</code> copies everywhere in the source to
destination. The destination is filled with white pixels with this
command.</li>
<li>21: Sets the source color to black.</li>
2023-07-23 04:49:22 +02:00
<li>22: <code>cairo_set_line_width</code> sets the width of lines. In
this case, the line width is set to be two pixels and will end up that
same size. (It is because the transformation is identity. If the
transformation isnt identity, for example scaling with the factor
three, the actual width in destination will be six (2x3=6) pixels.)</li>
<li>23: Draws a rectangle (square) on the mask. The square is located at
the center.</li>
2023-07-23 04:49:22 +02:00
<li>24: <code>cairo_stroke</code> transfers the source to destination
through the rectangle in the mask.</li>
2023-07-23 04:49:22 +02:00
<li>31: Outputs the image to a png file <code>rectangle.png</code>.</li>
<li>32: Destroys the context. At the same time the source is
destroyed.</li>
2023-07-23 04:49:22 +02:00
<li>33: Destroys the surface.</li>
</ul>
<p>To compile this, change your current directory to
<code>src/misc</code> and type the following.</p>
<pre><code>$ gcc `pkg-config --cflags cairo` cairo.c `pkg-config --libs cairo`</code></pre>
2023-07-23 04:49:22 +02:00
<p>s <img src="image/rectangle.png" alt="rectangle.png" /></p>
<p>See the <a href="https://www.cairographics.org/">Cairos website</a>
for further information.</p>
<h2 id="gtkdrawingarea">GtkDrawingArea</h2>
<p>The following is a very simple example.</p>
<div class="sourceCode" id="cb3"><pre
class="sourceCode numberSource C numberLines"><code class="sourceCode c"><span id="cb3-1"><a href="#cb3-1"></a><span class="pp">#include </span><span class="im">&lt;gtk/gtk.h&gt;</span></span>
<span id="cb3-2"><a href="#cb3-2"></a></span>
<span id="cb3-3"><a href="#cb3-3"></a><span class="dt">static</span> <span class="dt">void</span></span>
<span id="cb3-4"><a href="#cb3-4"></a>draw_function <span class="op">(</span>GtkDrawingArea <span class="op">*</span>area<span class="op">,</span> cairo_t <span class="op">*</span>cr<span class="op">,</span> <span class="dt">int</span> width<span class="op">,</span> <span class="dt">int</span> height<span class="op">,</span> gpointer user_data<span class="op">)</span> <span class="op">{</span></span>
<span id="cb3-5"><a href="#cb3-5"></a> <span class="dt">int</span> square_size <span class="op">=</span> <span class="fl">40.0</span><span class="op">;</span></span>
<span id="cb3-6"><a href="#cb3-6"></a></span>
<span id="cb3-7"><a href="#cb3-7"></a> cairo_set_source_rgb <span class="op">(</span>cr<span class="op">,</span> <span class="fl">1.0</span><span class="op">,</span> <span class="fl">1.0</span><span class="op">,</span> <span class="fl">1.0</span><span class="op">);</span> <span class="co">/* white */</span></span>
<span id="cb3-8"><a href="#cb3-8"></a> cairo_paint <span class="op">(</span>cr<span class="op">);</span></span>
<span id="cb3-9"><a href="#cb3-9"></a> cairo_set_line_width <span class="op">(</span>cr<span class="op">,</span> <span class="fl">2.0</span><span class="op">);</span></span>
<span id="cb3-10"><a href="#cb3-10"></a> cairo_set_source_rgb <span class="op">(</span>cr<span class="op">,</span> <span class="fl">0.0</span><span class="op">,</span> <span class="fl">0.0</span><span class="op">,</span> <span class="fl">0.0</span><span class="op">);</span> <span class="co">/* black */</span></span>
<span id="cb3-11"><a href="#cb3-11"></a> cairo_rectangle <span class="op">(</span>cr<span class="op">,</span></span>
<span id="cb3-12"><a href="#cb3-12"></a> width<span class="op">/</span><span class="fl">2.0</span> <span class="op">-</span> square_size<span class="op">/</span><span class="dv">2</span><span class="op">,</span></span>
<span id="cb3-13"><a href="#cb3-13"></a> height<span class="op">/</span><span class="fl">2.0</span> <span class="op">-</span> square_size<span class="op">/</span><span class="dv">2</span><span class="op">,</span></span>
<span id="cb3-14"><a href="#cb3-14"></a> square_size<span class="op">,</span></span>
<span id="cb3-15"><a href="#cb3-15"></a> square_size<span class="op">);</span></span>
<span id="cb3-16"><a href="#cb3-16"></a> cairo_stroke <span class="op">(</span>cr<span class="op">);</span></span>
<span id="cb3-17"><a href="#cb3-17"></a><span class="op">}</span></span>
<span id="cb3-18"><a href="#cb3-18"></a></span>
<span id="cb3-19"><a href="#cb3-19"></a><span class="dt">static</span> <span class="dt">void</span></span>
<span id="cb3-20"><a href="#cb3-20"></a>app_activate <span class="op">(</span>GApplication <span class="op">*</span>app<span class="op">,</span> gpointer user_data<span class="op">)</span> <span class="op">{</span></span>
<span id="cb3-21"><a href="#cb3-21"></a> GtkWidget <span class="op">*</span>win <span class="op">=</span> gtk_application_window_new <span class="op">(</span>GTK_APPLICATION <span class="op">(</span>app<span class="op">));</span></span>
<span id="cb3-22"><a href="#cb3-22"></a> GtkWidget <span class="op">*</span>area <span class="op">=</span> gtk_drawing_area_new <span class="op">();</span></span>
<span id="cb3-23"><a href="#cb3-23"></a></span>
<span id="cb3-24"><a href="#cb3-24"></a> gtk_window_set_title <span class="op">(</span>GTK_WINDOW <span class="op">(</span>win<span class="op">),</span> <span class="st">&quot;da1&quot;</span><span class="op">);</span></span>
<span id="cb3-25"><a href="#cb3-25"></a> gtk_drawing_area_set_draw_func <span class="op">(</span>GTK_DRAWING_AREA <span class="op">(</span>area<span class="op">),</span> draw_function<span class="op">,</span> NULL<span class="op">,</span> NULL<span class="op">);</span></span>
<span id="cb3-26"><a href="#cb3-26"></a> gtk_window_set_child <span class="op">(</span>GTK_WINDOW <span class="op">(</span>win<span class="op">),</span> area<span class="op">);</span></span>
<span id="cb3-27"><a href="#cb3-27"></a></span>
<span id="cb3-28"><a href="#cb3-28"></a> gtk_window_present <span class="op">(</span>GTK_WINDOW <span class="op">(</span>win<span class="op">));</span></span>
<span id="cb3-29"><a href="#cb3-29"></a><span class="op">}</span></span>
<span id="cb3-30"><a href="#cb3-30"></a></span>
<span id="cb3-31"><a href="#cb3-31"></a><span class="pp">#define APPLICATION_ID &quot;com.github.ToshioCP.da1&quot;</span></span>
<span id="cb3-32"><a href="#cb3-32"></a></span>
<span id="cb3-33"><a href="#cb3-33"></a><span class="dt">int</span></span>
<span id="cb3-34"><a href="#cb3-34"></a>main <span class="op">(</span><span class="dt">int</span> argc<span class="op">,</span> <span class="dt">char</span> <span class="op">**</span>argv<span class="op">)</span> <span class="op">{</span></span>
<span id="cb3-35"><a href="#cb3-35"></a> GtkApplication <span class="op">*</span>app<span class="op">;</span></span>
<span id="cb3-36"><a href="#cb3-36"></a> <span class="dt">int</span> stat<span class="op">;</span></span>
<span id="cb3-37"><a href="#cb3-37"></a></span>
<span id="cb3-38"><a href="#cb3-38"></a> app <span class="op">=</span> gtk_application_new <span class="op">(</span>APPLICATION_ID<span class="op">,</span> G_APPLICATION_DEFAULT_FLAGS<span class="op">);</span></span>
<span id="cb3-39"><a href="#cb3-39"></a> g_signal_connect <span class="op">(</span>app<span class="op">,</span> <span class="st">&quot;activate&quot;</span><span class="op">,</span> G_CALLBACK <span class="op">(</span>app_activate<span class="op">),</span> NULL<span class="op">);</span></span>
<span id="cb3-40"><a href="#cb3-40"></a> stat <span class="op">=</span>g_application_run <span class="op">(</span>G_APPLICATION <span class="op">(</span>app<span class="op">),</span> argc<span class="op">,</span> argv<span class="op">);</span></span>
<span id="cb3-41"><a href="#cb3-41"></a> g_object_unref <span class="op">(</span>app<span class="op">);</span></span>
<span id="cb3-42"><a href="#cb3-42"></a> <span class="cf">return</span> stat<span class="op">;</span></span>
<span id="cb3-43"><a href="#cb3-43"></a><span class="op">}</span></span></code></pre></div>
<p>The function <code>main</code> is almost same as before. The two
functions <code>app_activate</code> and <code>draw_function</code> are
important in this example.</p>
2023-01-05 12:41:02 +01:00
<ul>
<li>22: Creates a GtkDrawingArea instance.</li>
<li>25: Sets a drawing function of the widget. GtkDrawingArea widget
2023-07-23 04:49:22 +02:00
uses the function <code>draw_function</code> to draw the contents of
itself whenever its necessary. For example, when a user drag a mouse
pointer and resize a top-level window, GtkDrawingArea also changes the
size. Then, the whole window needs to be redrawn. For the information of
<code>gtk_drawing_area_set_draw_func</code>, see <a
href="https://docs.gtk.org/gtk4/method.DrawingArea.set_draw_func.html">Gtk
API Reference gtk_drawing_area_set_draw_func</a>.</li>
2023-01-05 12:41:02 +01:00
</ul>
<p>The drawing function has five parameters.</p>
<div class="sourceCode" id="cb4"><pre class="sourceCode c"><code class="sourceCode c"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> drawing_function <span class="op">(</span>GtkDrawingArea <span class="op">*</span>drawing_area<span class="op">,</span> cairo_t <span class="op">*</span>cr<span class="op">,</span> <span class="dt">int</span> width<span class="op">,</span> <span class="dt">int</span> height<span class="op">,</span></span>
<span id="cb4-2"><a href="#cb4-2" aria-hidden="true" tabindex="-1"></a> gpointer user_data<span class="op">);</span></span></code></pre></div>
<p>The first parameter is the GtkDrawingArea widget. You cant change
any properties, for example <code>content-width</code> or
<code>content-height</code>, in this function. The second parameter is a
cairo context given by the widget. The destination surface of the
context is connected to the contents of the widget. What you draw to
this surface will appear in the widget on the screen. The third and
fourth parameters are the size of the destination surface. Now, look at
the program again.</p>
<ul>
<li>3-17: The drawing function.</li>
<li>7-8: Sets the source to be white and paint the destination
white.</li>
<li>9: Sets the line width to be 2.</li>
<li>10: Sets the source to be black.</li>
<li>11-15: Adds a rectangle to the mask.</li>
<li>16: Draws the rectangle with black color to the destination.</li>
</ul>
<p>The program is src/misc/da1.c. Compile and run it, then a window with
a black rectangle (square) appears. Try resizing the window. The square
always appears at the center of the window because the drawing function
is invoked each time the window is resized.</p>
<figure>
<img src="image/da1.png" alt="Square in the window" />
<figcaption aria-hidden="true">Square in the window</figcaption>
</figure>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin="anonymous"></script>
</body>
</html>