⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 z186.html

📁 GTK+_ Gnome Application Development
💻 HTML
📖 第 1 页 / 共 3 页
字号:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"><html>  <head>    <title>      Drawing Methods    </title>    <meta name="GENERATOR" content=    "Modular DocBook HTML Stylesheet Version 1.45">    <link rel="HOME" title="GTK+ / Gnome Application Development"    href="ggad.html">    <link rel="UP" title="Writing a GnomeCanvasItem" href=     "cha-canvasitem.html">    <link rel="PREVIOUS" title="Writing a GnomeCanvasItem" href=     "cha-canvasitem.html">    <link rel="NEXT" title="Other Methods" href="z192.html">  </head>  <body bgcolor="#FFFFFF" text="#000000" link="#0000FF" vlink=   "#840084" alink="#0000FF">    <div class="NAVHEADER">      <table width="100%" border="0" bgcolor="#ffffff" cellpadding=       "1" cellspacing="0">        <tr>          <th colspan="4" align="center">            <font color="#000000" size="2">GTK+ / Gnome Application            Development</font>          </th>        </tr>        <tr>          <td width="25%" bgcolor="#ffffff" align="left">            <a href="cha-canvasitem.html"><font color="#0000ff"            size="2"><b>&lt;&lt;&lt; Previous</b></font></a>          </td>          <td width="25%" colspan="2" bgcolor="#ffffff" align=           "center">            <font color="#0000ff" size="2"><b><a href="ggad.html">            <font color="#0000ff" size="2"><b>            Home</b></font></a></b></font>          </td>          <td width="25%" bgcolor="#ffffff" align="right">            <a href="z192.html"><font color="#0000ff" size="2"><b>            Next &gt;&gt;&gt;</b></font></a>          </td>        </tr>      </table>    </div>    <div class="SECT1">      <h1 class="SECT1">        <a name="Z186">Drawing Methods</a>      </h1>      <p>        The most important task of any canvas item is rendering        itself onto the canvas. Rendering is a two-stage process        for efficiency reasons. The first stage, implemented in a        <span class="STRUCTNAME">GnomeCanvasItem</span>'s <span        class="STRUCTNAME">update</span> method, is guaranteed to        happen only once per item per rendering cycle; the idea is        to do any expensive affine transformations or other        calculations in the update method. In the second stage, the        canvas item renders itself to some region on the screen.        The <span class="STRUCTNAME">render</span> method        implements stage two for antialiased items, while the <span        class="STRUCTNAME">draw</span> method implements stage two        for GDK items. An item's render or draw method may be        invoked multiple times during a canvas repaint.      </p>      <p>        Rendering occurs in a one-shot idle function. That is,        whenever the canvas receives an expose event or otherwise        determines that a redraw is needed, it adds an idle        function which removes itself after a single invocation.        (An idle function runs when no GTK+ events are pending and        the flow of execution is in the GTK+ main loop---see <a        href="sec-mainloop.html">the section called <i>The Main        Loop</i> in the chapter called <i>GTK+ Basics</i></a> for        details.) The canvas maintains a list of redraw regions and        adds to it whenever a redraw request is received, so it        knows which areas to repaint when the idle handler is        finally invoked.      </p>      <p>        Canvas items carry a flag indicating whether they need to        be updated. Whenever a canvas item "changes" (for example,        if you set a new fill color for <span class="STRUCTNAME">        GnomeCanvasRect</span>), it will call <tt class="FUNCTION">        gnome_canvas_item_request_update()</tt> to set the "update        needed" flag for itself and the groups that contain it, up        to and including the root canvas group. (The <tt class=         "CLASSNAME">GnomeCanvas</tt> widget is only aware of a        single canvas item, the root group---all other items are        handled recursively when methods are invoked on the root        group.) In its one-shot idle function, the canvas invokes        the update method of the root canvas item if its update        flag is set, then clears the flag so the update method will        not be run next time. The <span class="STRUCTNAME">        GnomeCanvasGroup</span> update method does the same for        each child item.      </p>      <p>        Once all canvas items have been updated, the rendering        process begins. The canvas creates an RGB or <span class=         "STRUCTNAME">GdkPixmap</span> buffer, converts its list of        redraw regions into a list of buffer-sized rectangles, then        invokes the render or draw method of the root canvas group        once per rectangle. After each rectangle is rendered, the        buffer is copied to the screen.      </p>      <div class="SECT2">        <h2 class="SECT2">          <a name="Z187">The Update Method</a>        </h2>        <p>          The update method is primarily used by antialiased canvas          items. <tt class="APPLICATION">libart_lgpl</tt> can          prebuild a vector path to be rendered, performing          clipping and affine transformation in advance. The render          method stamps the pre-assembled path into the RGB buffer.        </p>        <p>          The update method is one of the two that <span class=           "STRUCTNAME">GnomeCanvasRect</span> and <span class=           "STRUCTNAME">GnomeCanvasEllipse</span> have to implement          differently. Here is the <span class="STRUCTNAME">          GnomeCanvasRect</span> implementation:        </p>        <table border="0" bgcolor="#E0E0E0" width="100%">          <tr>            <td><pre class="PROGRAMLISTING">&#13;static voidgnome_canvas_rect_update (GnomeCanvasItem *item, double affine[6],                           ArtSVP *clip_path, gint flags){  GnomeCanvasRE *re;  ArtVpath vpath[11];  ArtVpath *vpath2;  double x0, y0, x1, y1;  double dx, dy;  double halfwidth;  int i;  gnome_canvas_re_update_shared (item, affine, clip_path, flags);  re = GNOME_CANVAS_RE (item);  if (item-&gt;canvas-&gt;aa) {    x0 = re-&gt;x1;    y0 = re-&gt;y1;    x1 = re-&gt;x2;    y1 = re-&gt;y2;    gnome_canvas_item_reset_bounds (item);    if (re-&gt;fill_set) {      vpath[0].code = ART_MOVETO;      vpath[0].x = x0;      vpath[0].y = y0;      vpath[1].code = ART_LINETO;      vpath[1].x = x0;      vpath[1].y = y1;      vpath[2].code = ART_LINETO;      vpath[2].x = x1;      vpath[2].y = y1;      vpath[3].code = ART_LINETO;      vpath[3].x = x1;      vpath[3].y = y0;      vpath[4].code = ART_LINETO;      vpath[4].x = x0;      vpath[4].y = y0;      vpath[5].code = ART_END;      vpath[5].x = 0;      vpath[5].y = 0;      vpath2 = art_vpath_affine_transform (vpath, affine);      gnome_canvas_item_update_svp_clip (item, &amp;re-&gt;fill_svp, art_svp_from_vpath (vpath2), clip_path);      art_free (vpath2);    } else      gnome_canvas_item_update_svp (item, &amp;re-&gt;fill_svp, NULL);    if (re-&gt;outline_set) {      if (re-&gt;width_pixels)        halfwidth = re-&gt;width * 0.5;      else        halfwidth = re-&gt;width * item-&gt;canvas-&gt;pixels_per_unit * 0.5;      if (halfwidth &lt; 0.25)        halfwidth = 0.25;      i = 0;      vpath[i].code = ART_MOVETO;      vpath[i].x = x0 - halfwidth;      vpath[i].y = y0 - halfwidth;      i++;      vpath[i].code = ART_LINETO;      vpath[i].x = x0 - halfwidth;      vpath[i].y = y1 + halfwidth;      i++;      vpath[i].code = ART_LINETO;      vpath[i].x = x1 + halfwidth;      vpath[i].y = y1 + halfwidth;      i++;      vpath[i].code = ART_LINETO;      vpath[i].x = x1 + halfwidth;      vpath[i].y = y0 - halfwidth;      i++;      vpath[i].code = ART_LINETO;      vpath[i].x = x0 - halfwidth;      vpath[i].y = y0 - halfwidth;      i++;      if (x1 - halfwidth &gt; x0 + halfwidth &amp;&amp;          y1 - halfwidth &gt; y0 + halfwidth) {        vpath[i].code = ART_MOVETO;        vpath[i].x = x0 + halfwidth;        vpath[i].y = y0 + halfwidth;        i++;        vpath[i].code = ART_LINETO;        vpath[i].x = x1 - halfwidth;        vpath[i].y = y0 + halfwidth;        i++;        vpath[i].code = ART_LINETO;        vpath[i].x = x1 - halfwidth;        vpath[i].y = y1 - halfwidth;        i++;        vpath[i].code = ART_LINETO;        vpath[i].x = x0 + halfwidth;        vpath[i].y = y1 - halfwidth;        i++;        vpath[i].code = ART_LINETO;        vpath[i].x = x0 + halfwidth;        vpath[i].y = y0 + halfwidth;        i++;      }      vpath[i].code = ART_END;      vpath[i].x = 0;      vpath[i].y = 0;      vpath2 = art_vpath_affine_transform (vpath, affine);      gnome_canvas_item_update_svp_clip (item, &amp;re-&gt;outline_svp, art_svp_from_vpath (vpath2), clip_path);      art_free (vpath2);    } else      gnome_canvas_item_update_svp (item, &amp;re-&gt;outline_svp, NULL);  } else {    get_bounds (re, &amp;x0, &amp;y0, &amp;x1, &amp;y1);    gnome_canvas_update_bbox (item, x0, y0, x1, y1);  }}      </pre>            </td>          </tr>        </table>        <p>          As you can see, the first thing this function does is          invoke an update function shared by <span class=           "STRUCTNAME">GnomeCanvasRect</span> and <span class=           "STRUCTNAME">GnomeCanvasEllipse</span>; here is that          function:        </p>        <table border="0" bgcolor="#E0E0E0" width="100%">          <tr>            <td><pre class="PROGRAMLISTING">&#13;static voidgnome_canvas_re_update_shared (GnomeCanvasItem *item, double *affine,                                ArtSVP *clip_path, int flags){  GnomeCanvasRE *re;  re = GNOME_CANVAS_RE (item);  if (re_parent_class-&gt;update)    (* re_parent_class-&gt;update) (item, affine, clip_path, flags);  if (!item-&gt;canvas-&gt;aa) {    set_gc_foreground (re-&gt;fill_gc, re-&gt;fill_pixel);    set_gc_foreground (re-&gt;outline_gc, re-&gt;outline_pixel);    set_stipple (re-&gt;fill_gc, &amp;re-&gt;fill_stipple,                  re-&gt;fill_stipple, TRUE);    set_stipple (re-&gt;outline_gc, &amp;re-&gt;outline_stipple,                  re-&gt;outline_stipple, TRUE);    set_outline_gc_width (re);  } }      </pre>            </td>          </tr>        </table>        <p>          There is a lot of code involved here; the update method          is almost always the most complicated one, since it does          all the work of preparing to render a canvas item. Also,          the update method is different for GDK and antialiased          mode; notice the code which depends on the <span class=           "STRUCTNAME">item-&gt;canvas-&gt;aa</span> flag.        </p>        <p>          The first thing <span class="STRUCTNAME">          GnomeCanvasRE</span> does during an update is invoke the          update method of its parent class. The <span class=           "STRUCTNAME">GnomeCanvasItem</span> default update method          does nothing whatsoever in Gnome 1.0, but it is good          practice to chain up for future robustness. Then, <span          class="STRUCTNAME">GnomeCanvasRE</span> calls a series of          utility routines to fill in its graphics contexts with          their correct values. These are straightforward          functions, so their implementations are omitted here.        </p>        <p>          Next <tt class="FUNCTION">gnome_canvas_rect_update()</tt>          continues with <span class="STRUCTNAME">          GnomeCanvasRect</span>-specific details. Several tasks          are accomplished:        </p>        <ul>          <li>            <p>              The bounding box of the canvas item is updated. Every              canvas item has an associated bounding box; the <span              class="STRUCTNAME">GnomeCanvasGroup</span> draw and              render methods use this box to determine which items              are in the redraw region. The bounding box must be              updated in both GDK and antialiased mode.            </p>          </li>          <li>            <p>              In antialiased mode, a <i class="FIRSTTERM">sorted              vector path</i> is created. A sorted vector path is              simply a series of drawing instructions, similar to              primitive PostScript operations, that <tt class=               "APPLICATION">libart_lgpl</tt> can render to an RGB

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -