?? z186.html
字號:
buffer. </p> </li> <li> <p> In antialiased mode, the <span class="STRUCTNAME"> affine</span> and <span class="STRUCTNAME"> clip_path</span> arguments to the update method are used to transform the sorted vector path; thus the affine and clip path are implicitly stored for use in the render method. If you do not use <tt class= "APPLICATION">libart_lgpl</tt>'s sorted vector paths in your own canvas items, you must arrange some other way to ensure the affine and clip are taken into account when you render. </p> </li> <li> <p> In both modes, a redraw is requested for both the region the item used to occupy, <i class="EMPHASIS"> and</i> the region the item will now occupy. </p> </li> </ul> <p> Much of this work takes place behind the scenes in utility functions from <tt class="FILENAME"> libgnomeui/gnome-canvas-util.h</tt>. <tt class= "FUNCTION">gnome_canvas_update_bbox()</tt> sets the item's new bounding box and requests a redraw on both the old and new bounding boxes; it is used in GDK mode. (<tt class="FUNCTION">gnome_canvas_update_bbox()</tt> expects canvas pixel coordinates; <tt class="FUNCTION"> get_bounds()</tt> is a trivial function which computes the rectangle's bounds in canvas pixel coordinates.) </p> <p> So you know what's happening behind the scenes, here is the implementation of <tt class="FUNCTION"> gnome_canvas_update_bbox()</tt>: </p> <table border="0" bgcolor="#E0E0E0" width="100%"> <tr> <td><pre class="PROGRAMLISTING"> voidgnome_canvas_update_bbox (GnomeCanvasItem *item, int x1, int y1, int x2, int y2){ gnome_canvas_request_redraw (item->canvas, item->x1, item->y1, item->x2, item->y2); item->x1 = x1; item->y1 = y1; item->x2 = x2; item->y2 = y2; gnome_canvas_request_redraw (item->canvas, item->x1, item->y1, item->x2, item->y2);} </pre> </td> </tr> </table> <p> Of course you're free to do the equivalent yourself, this is merely a convenience function. </p> <p> In GDK mode, that's about all that happens; we update the bounds and then return. Antialiased mode is a bit more complex, but essentially the same tasks are performed. First, <tt class="FUNCTION"> gnome_canvas_item_reset_bounds()</tt> sets the item's bounds back to an empty rectangle. Then, two sorted vector paths are prepared; one for the solid part of the rectangle (if any), and one for the rectangle's outline (if any). The same procedure is followed each time. First, a vector path for <tt class="APPLICATION"> libart_lgpl</tt> is prepared; next, the path is affine transformed; then <tt class="FUNCTION"> gnome_canvas_item_update_svp_clip()</tt> is used to request a redraw on the old path, free the old path, clip the new path, request a redraw on the new one, and save the new one for use in rendering. If the rectangle's fill or outline has been turned off, a redraw is requested on the old vector path, but no new path is created. </p> <p> To give you a clearer idea what is happening, here is the implementation of <tt class="FUNCTION"> gnome_canvas_item_update_svp_clip()</tt>: </p> <table border="0" bgcolor="#E0E0E0" width="100%"> <tr> <td><pre class="PROGRAMLISTING"> voidgnome_canvas_item_update_svp_clip (GnomeCanvasItem *item, ArtSVP **p_svp, ArtSVP *new_svp, ArtSVP *clip_svp){ ArtSVP *clipped_svp; if (clip_svp != NULL) { clipped_svp = art_svp_intersect (new_svp, clip_svp); art_svp_free (new_svp); } else { clipped_svp = new_svp; } gnome_canvas_item_update_svp (item, p_svp, clipped_svp);} </pre> </td> </tr> </table> <p> and <tt class="FUNCTION"> gnome_canvas_item_update_svp()</tt>: </p> <table border="0" bgcolor="#E0E0E0" width="100%"> <tr> <td><pre class="PROGRAMLISTING"> voidgnome_canvas_item_update_svp (GnomeCanvasItem *item, ArtSVP **p_svp, ArtSVP *new_svp){ ArtDRect bbox; gnome_canvas_update_svp (item->canvas, p_svp, new_svp); if (new_svp) { bbox.x0 = item->x1; bbox.y0 = item->y1; bbox.x1 = item->x2; bbox.y1 = item->y2; art_drect_svp_union (&bbox, new_svp); item->x1 = bbox.x0; item->y1 = bbox.y0; item->x2 = bbox.x1; item->y2 = bbox.y1; }} </pre> </td> </tr> </table> <p> and then <tt class="FUNCTION"> gnome_canvas_update_svp()</tt>: </p> <table border="0" bgcolor="#E0E0E0" width="100%"> <tr> <td><pre class="PROGRAMLISTING"> voidgnome_canvas_update_svp (GnomeCanvas *canvas, ArtSVP **p_svp, ArtSVP *new_svp){ ArtSVP *old_svp; ArtSVP *diff; ArtUta *repaint_uta; old_svp = *p_svp; if (old_svp != NULL && new_svp != NULL) { repaint_uta = art_uta_from_svp (old_svp); gnome_canvas_request_redraw_uta (canvas, repaint_uta); repaint_uta = art_uta_from_svp (new_svp); gnome_canvas_request_redraw_uta (canvas, repaint_uta); } else if (old_svp != NULL) { repaint_uta = art_uta_from_svp (old_svp); art_svp_free (old_svp); gnome_canvas_request_redraw_uta (canvas, repaint_uta); } *p_svp = new_svp;} </pre> </td> </tr> </table> <p> Again, all of these are in <tt class="FILENAME"> libgnomeui/gnome-canvas-util.h</tt> for any canvas item to use. Ignore the implementation details; the idea is simply to see what work is being done. The code may be easier to understand if you know that an <span class= "STRUCTNAME">ArtDRect</span> is a "rectangle defined with doubles," from <tt class="APPLICATION">libart_lgpl</tt>, and that an <span class="STRUCTNAME">ArtUta</span> is a "microtile array," basically a list of small regions. (The antialiased canvas tracks the redraw region in a fairly sophisticated way. Note that the "U" in "<span class="STRUCTNAME">Uta</span>" is supposed to suggest the greek letter symbolizing "micro," it does not stand for a word beginning with "U".) </p> <div class="SECT3"> <h3 class="SECT3"> <a name="Z188">Requesting Updates</a> </h3> <p> It is the canvas item's responsibility to request an update or redraw when the properties of the item are changed and the screen should be refreshed. This is straightforward. For example, here is a snippet of code from <tt class="FUNCTION"> gnome_canvas_re_set_arg()</tt>, which sets the <span class="STRUCTNAME">"y2"</span> argument: </p> <table border="0" bgcolor="#E0E0E0" width="100%"> <tr> <td><pre class="PROGRAMLISTING"> case ARG_Y2: re->y2 = GTK_VALUE_DOUBLE (*arg); gnome_canvas_item_request_update (item); break; </pre> </td> </tr> </table> <p> Since <span class="STRUCTNAME">"y2"</span> modifies the shape of the rectangle, the path must be recreated and an update is necessary. Note that <tt class="FUNCTION"> gnome_canvas_item_request_update()</tt> simply sets a flag and installs an idle handler if none is pending, so it can be called many times without a performance penalty. </p> <p> Not all changes require an update; a redraw may be sufficient, or perhaps the argument is unrelated to the display. It depends on the canvas item and what exactly is being changed. </p> </div> </div> <div class="SECT2"> <h2 class="SECT2"> <a name="Z189">The Render Method (Antialiased Mode)</a> </h2> <p> The render method is shared between <span class= "STRUCTNAME">GnomeCanvasRect</span> and <span class= "STRUCTNAME">GnomeCanvasEllipse</span>; all it does is stamp the two paths created in the update method into the RGB buffer: </p> <table border="0" bgcolor="#E0E0E0" width="100%"> <tr> <td><pre class="PROGRAMLISTING"> static voidgnome_canvas_re_render (GnomeCanvasItem *item, GnomeCanvasBuf *buf){ GnomeCanvasRE *re; guint32 fg_color, bg_color; re = GNOME_CANVAS_RE (item); if (re->fill_svp != NULL) { gnome_canvas_render_svp (buf, re->fill_svp, re->fill_color); } if (re->outline_svp != NULL) { gnome_canvas_render_svp (buf, re->outline_svp, re->outline_color); }} </pre> </td> </tr> </table> <p> As you can see, most of the work takes place in <tt class="FUNCTION">gnome_canvas_render_svp()</tt>, another function from <tt class="FILENAME"> libgnomeui/gnome-canvas-util.h</tt>; here is its implementation: </p> <table border="0" bgcolor="#E0E0E0" width="100%"> <tr> <td><pre class="PROGRAMLISTING"> voidgnome_canvas_render_svp (GnomeCanvasBuf *buf, ArtSVP *svp, guint32 rgba){ guint32 fg_color, bg_color; if (buf->is_bg) { bg_color = buf->bg_color; fg_color = rgba >> 8; art_rgb_svp_aa (svp, buf->rect.x0, buf->rect.y0, buf->rect.x1, buf->rect.y1, fg_color, bg_color, buf->buf, buf->buf_rowstride, NULL); buf->is_bg = 0; buf->is_buf = 1; } else { art_rgb_svp_alpha (svp, buf->rect.x0, buf->rect.y0, buf->rect.x1, buf->rect.y1, rgba, buf->buf, buf->buf_rowstride, NULL); }} </pre> </td> </tr> </table> <p>
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -