📄 dw_image.c
字号:
if (link_pressed == link_released) { gtk_signal_emit (GTK_OBJECT (widget), image_signals[LINK_CLICKED], link_released, link_x, link_y, event, &return_val2); return return_val1 || return_val2; } return return_val1; } return FALSE;}/* * Standard Dw function. */static gboolean Dw_image_motion_notify (DwWidget *widget, gint32 x, gint32 y, GdkEventMotion *event){ DwImage *image = DW_IMAGE (widget); gint link, link_old, link_x, link_y; gboolean return_val = FALSE; link_old = image->hover_link; Dw_image_find_link (image, x, y, &link, &link_x, &link_y); image->hover_link = link; /* In case of a ISMAP image, the signal has to be emitted always */ if (link_x != -1 || link != link_old) { gtk_signal_emit (GTK_OBJECT (widget), image_signals[LINK_ENTERED], link, link_x, link_y, &return_val); return return_val; } else return (link != -1);}/* * Find a link given a coordinate location relative to the window. */static void Dw_image_find_link (DwImage *image, gint x, gint y, gint *link, gint *link_x, gint *link_y){ DwStyle *style; DwWidget *widget = DW_WIDGET (image); *link_x = -1; *link_y = -1; if (image->map_list && image->usemap_url) { *link = Dw_image_map_list_find_link (image->map_list, image->usemap_url, x - p_Dw_style_box_offset_x (widget->style), y - p_Dw_style_box_offset_y (widget->style)); if (*link != -1) return; } if (image->ismap && (style = DW_WIDGET(image)->style) && style->x_link != -1) { *link = style->x_link; *link_x = x - p_Dw_style_box_offset_x (widget->style); *link_y = y - p_Dw_style_box_offset_y (widget->style); return; } *link = -1;}/* * Set or resize a image. */void a_Dw_image_size (DwImage *image, gint width, gint height){ gint Resize = (image->width != width || image->height != height); image->width = width; image->height = height; if (Resize) p_Dw_widget_queue_resize (DW_WIDGET (image), 0, TRUE); if (image->buffer) /* if a_Dw_image_set_buffer has been called before */ Dw_image_scale (image);}/* * Called after the RGB line buffer has been copied into the full * image buffer. Uses for drawing and scaling. */void a_Dw_image_draw_row (DwImage *image, gint Width, gint Height, gint x, gint y){ DwWidget *widget = DW_WIDGET (image); gint dy1, dy2; _MSG("a_Dw_image_draw_row: x=%d y=%d\n", x, y); g_return_if_fail (image->buffer != NULL); if (image->scaled_buffer) { Dw_image_scale_row (image, y); dy1 = Dw_image_scaled_y (image, y); dy2 = Dw_image_scaled_y (image, y + 1); p_Dw_widget_queue_draw_area(widget, x, dy1 + p_Dw_style_box_offset_y(widget->style), widget->allocation.width, dy2 - dy1); } else p_Dw_widget_queue_draw_area (widget, x, y + p_Dw_style_box_offset_y (widget->style), widget->allocation.width, 1);}/* * Set the widget buffer to reference the dicache entry buffer */void a_Dw_image_set_buffer (DwImage *image, guchar *ImageBuffer, DilloUrl *url, gint version){ image->buffer = ImageBuffer; image->url = url; image->version = version; if (image->width > 0 && image->height > 0) /* if a_Dw_image_set_size has been called before */ Dw_image_scale (image);}/* * Sets image as server side image map. */void a_Dw_image_set_ismap (DwImage *image){ image->ismap = TRUE;}/* * Sets image as client side image map. */void a_Dw_image_set_usemap (DwImage *image, DwImageMapList *map_list, DilloUrl *usemap_url){ image->map_list = map_list; if (image->usemap_url) a_Url_free (image->usemap_url); image->usemap_url = usemap_url ? a_Url_dup (usemap_url) : NULL;}/* * Scale the whole image: Compare buffer size with allocation, and, if * necessary, allocate a second buffer and scale all rows. */static void Dw_image_scale (DwImage *image){ int w, h, y; DwWidget *widget; if (image->scaled_buffer) { g_free (image->scaled_buffer); image->scaled_buffer = NULL; } widget = DW_WIDGET (image); w = DW_WIDGET_CONTENT_WIDTH(widget); h = DW_WIDGET_CONTENT_HEIGHT(widget); /* Zero or negative sizes? Ignore. */ if (w <= 0 || h <= 0) return; if (image->width != w || image->height != h) { /* scaled image */ image->scaled_buffer = g_malloc (3 * w * h); for (y = 0; y < image->height; y++) Dw_image_scale_row (image, y); }}/* * Scale one row. y_src is the row in the dicache buffer. */static void Dw_image_scale_row (DwImage *image, gint y_src){ DwWidget *widget; guchar *src, *dest, *dest1; gint w_src, w_dest, x_src, x_dest, y_dest1, y_dest2, y_dest, delta; widget = DW_WIDGET (image); w_src = image->width; w_dest = DW_WIDGET_CONTENT_WIDTH(widget); y_dest1 = Dw_image_scaled_y (image, y_src); y_dest2 = Dw_image_scaled_y (image, y_src + 1); src = image->buffer + 3 * y_src * w_src; if (y_dest1 != y_dest2) { dest1 = image->scaled_buffer + 3 * y_dest1 * w_dest; if (w_src == w_dest) memcpy (dest1, src, 3 * w_src); else if (w_dest > w_src) { delta = w_src / 2; x_src = 0; x_dest = 0; while (x_dest < w_dest) { memcpy (dest1 + 3 * x_dest, src + 3 * x_src, 3); x_dest++; delta += w_src; while (delta > w_dest) { delta -= w_dest; x_src++; } } } else { delta = w_dest / 2; x_src = 0; x_dest = 0; while (x_src < w_src) { memcpy (dest1 + 3 * x_dest, src + 3 * x_src, 3); x_src++; delta += w_dest; while (delta > w_src) { delta -= w_src; x_dest++; } } } /* The other lines are simply copied. */ for (y_dest = y_dest1 + 1; y_dest < y_dest2; y_dest++) { dest = image->scaled_buffer + 3 * y_dest * w_dest; memcpy (dest, dest1, 3 * w_dest); } }}/* * Image Maps *//* * Initialize a DwImageMapList. The memory has to be allocated before. */void a_Dw_image_map_list_init (DwImageMapList *list){ list->num_maps = 0; list->num_maps_max = 8; list->maps = g_new (DwImageMap, list->num_maps_max); list->num_shapes = 0; list->num_shapes_max = 8; list->shapes = g_new (DwImageMapShape, list->num_shapes_max);}/* * Free the content of a DwImageMapList. The memory for the list is * not freed. */void a_Dw_image_map_list_free (DwImageMapList *list){ gint i; for (i = 0; i < list->num_maps; i++) a_Url_free (list->maps[i].url); g_free (list->maps); for (i = 0; i < list->num_shapes; i++) if (list->shapes[i].type == DW_IMAGE_MAP_SHAPE_POLY) gdk_region_destroy (list->shapes[i].data.poly); g_free (list->shapes);}/* * Add a new map to the list. Next added shapes will belong to this * map. */void a_Dw_image_map_list_add_map (DwImageMapList *list, DilloUrl *url){ list->num_maps++; a_List_add (list->maps, list->num_maps, list->num_maps_max); list->maps[list->num_maps - 1].url = a_Url_dup (url); list->maps[list->num_maps - 1].start_shape = list->num_shapes;}void a_Dw_image_map_list_add_shape (DwImageMapList *list, gint type, gint link, GdkPoint *points, gint num_points){ gboolean correct_args; DwImageMapShape *shape; switch (type) { case DW_IMAGE_MAP_SHAPE_RECT: correct_args = (num_points >= 2); break; case DW_IMAGE_MAP_SHAPE_CIRCLE: correct_args = (num_points >= 1 && points[1].x != 0); break; case DW_IMAGE_MAP_SHAPE_POLY: correct_args = (num_points >= 3); break; default: correct_args = FALSE; } if (correct_args) { list->num_shapes++; a_List_add (list->shapes, list->num_shapes, list->num_shapes_max); shape = &list->shapes[list->num_shapes - 1]; shape->type = type; shape->link = link; switch (type) { case DW_IMAGE_MAP_SHAPE_RECT: shape->data.rect.left = points[0].x; shape->data.rect.top = points[0].y; shape->data.rect.right = points[1].x; shape->data.rect.bottom = points[1].y; break; case DW_IMAGE_MAP_SHAPE_CIRCLE: shape->data.circle.x = points[0].x; shape->data.circle.y = points[0].y; shape->data.circle.r2 = points[1].x * points[1].x; break; case DW_IMAGE_MAP_SHAPE_POLY: shape->data.poly = gdk_region_polygon (points, num_points, GDK_WINDING_RULE); break; } }}/* * Find a link in an image map. */static gint Dw_image_map_list_find_link (DwImageMapList *list, DilloUrl *url, gint x, gint y){ gint i, j, start, end, dx, dy; DwImageMapShape *shape; for (i = 0; i < list->num_maps; i++) { if (a_Url_cmp (list->maps[i].url, url) == 0 && URL_STRCAMP_EQ(URL_FRAGMENT_(list->maps[i].url),URL_FRAGMENT_(url))){ /* map found */ start = list->maps[i].start_shape; if (i == list->num_maps - 1) end = list->num_shapes; else end = list->maps[i + 1].start_shape; for (j = start; j < end; j++) { shape = &list->shapes[j]; switch (shape->type) { case DW_IMAGE_MAP_SHAPE_CIRCLE: dx = shape->data.circle.x - x; dy = shape->data.circle.y - y; if (shape->data.circle.r2 >= (dx*dx + dy*dy)) return shape->link; break; case DW_IMAGE_MAP_SHAPE_RECT: if (x > shape->data.rect.left && x < shape->data.rect.right && y > shape->data.rect.top && y < shape->data.rect.bottom) return shape->link; break; case DW_IMAGE_MAP_SHAPE_POLY: if (gdk_region_point_in (shape->data.poly, x, y)) return shape->link; break; } } /* no shape found */ return -1; } } /* no map found */ return -1;}static DwIterator *Dw_image_iterator (DwWidget *widget, gint32 mask, gboolean at_end){ DwIterator *it; DwImage *image = DW_IMAGE (widget); if (image->alt_text) { it = p_Dw_widget_text_iterator (widget, mask, at_end, image->alt_text); if (it) it->highlight = Dw_image_iterator_highlight; return it; } else return NULL;}static void Dw_image_iterator_highlight (DwIterator *it, gint start, gint end, DwHighlightLayer layer){ if (it->content.type == DW_CONTENT_TEXT) { /* The whole image is highlighted, as soon as something is selected at * all. */ DW_IMAGE(it->widget)->selected[layer] = (start != -1 && start != end); p_Dw_widget_queue_draw (it->widget); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -