📄 dw_image.c
字号:
/* * File: dw_image.c * * Copyright (C) 2001 Sebastian Geerken <S.Geerken@ping.de>, * Jorge Arellano Cid <jcid@dillo.org> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. */#include <stdio.h>#include <string.h>#include "msg.h"#include "dw_image.h"#include "dw_viewport.h"#include "prefs.h"#include "dw_marshal.h"#include "list.h"#if 0#include "dicache.h"#endifstatic void Dw_image_init (DwImage *image);static void Dw_image_class_init (DwImageClass *klass);static void Dw_image_finalize (GObject *object);static void Dw_image_size_request (DwWidget *widget, DwRequisition *requisition);static void Dw_image_size_allocate (DwWidget *widget, DwAllocation *allocation);static void Dw_image_draw (DwWidget *widget, HDC hdc, DwRectangle *area);static gboolean Dw_image_button_press (DwWidget *widget, gint32 x, gint32 y, DWORD flags);static gboolean Dw_image_button_release (DwWidget *widget, gint32 x, gint32 y, DWORD flags);static gboolean Dw_image_motion_notify (DwWidget *widget, gint32 x, gint32 y, DWORD flags);static gboolean Dw_image_enter_notify (DwWidget *widget, DwWidget *last_widget, DWORD flags);static gboolean Dw_image_leave_notify (DwWidget *widget, DwWidget *next_widget, DWORD flags);static DwIterator* Dw_image_iterator (DwWidget *widget, gint32 mask, gboolean at_end);static void Dw_image_iterator_highlight (DwIterator *it, gint start, gint end, DwHighlightLayer layer);static void Dw_image_find_link (DwImage *image, gint x, gint y, gint *link, gint *link_x, gint *link_y);static void Dw_image_scale (DwImage *image);static gint Dw_image_map_list_find_link (DwImageMapList *list, DilloUrl *url, gint x, gint y);#define Dw_image_scaled_y(image, y_src) \ ( (y_src) * ( ((DwWidget*)(image))->allocation.ascent + \ ((DwWidget*)(image))->allocation.descent - \ p_Dw_style_box_diff_height ( ((DwWidget*)(image))->style ) ) \ / ((DwImage*)(image))->height )enum{ LINK_ENTERED, LINK_PRESSED, LINK_RELEASED, LINK_CLICKED, LAST_SIGNAL};static guint image_signals[LAST_SIGNAL] = { 0 };static DwWidgetClass *parent_class;static BLOCKHEAP my_cliprc_heap;/* * Standard GObject function. */GType a_Dw_image_get_type (void){ static GType type = 0; if (!type) { static const GTypeInfo info = { sizeof (DwImageClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) Dw_image_class_init, (GClassFinalizeFunc) NULL, (gconstpointer) NULL, sizeof (DwImage), 0, (GInstanceInitFunc) Dw_image_init }; type = g_type_register_static (DW_TYPE_WIDGET, "DwImage", &info, 0); } return type;}/* * Standard GObject function. */DwWidget* a_Dw_image_new (DwImageType type, const gchar *tooltip, const gchar *alt_text){ GObject *object; DwImage *image; object = g_object_new (DW_TYPE_IMAGE, NULL); image = DW_IMAGE(object);#if 0 if (tooltip && tooltip[0] && prefs.show_tooltip) image->tooltip = a_Dw_tooltip_new (tooltip);#endif image->alt_text = alt_text ? g_strdup (alt_text) : NULL; return DW_WIDGET (object);}/* * Standard GObject function. */static void Dw_image_init (DwImage *image){ int i; image->url = NULL; image->width = 0; image->height = 0; image->alt_text_width = -1; /* not yet calculated */ image->bmp = NULL; image->scaled_bmp = NULL;#if 0 image->tooltip = NULL;#endif image->alt_text = NULL; image->usemap_url = NULL; image->ismap = FALSE; for (i = 0; i < DW_HIGHLIGHT_NUM_LAYERS; i++) image->selected[i] = FALSE;}/* * Standard GObject function. */static void Dw_image_class_init (DwImageClass *klass){ GObjectClass *object_class; DwWidgetClass *widget_class; InitFreeClipRectList (&my_cliprc_heap, 100); parent_class = g_type_class_peek_parent (klass); object_class = (GObjectClass*)klass; object_class->finalize = Dw_image_finalize; image_signals[LINK_ENTERED] = g_signal_new ("link_entered", G_OBJECT_CLASS_TYPE (klass), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (DwImageClass, link_entered), NULL, NULL, p_Dw_marshal_link_enter, G_TYPE_BOOLEAN, 3, G_TYPE_INT, G_TYPE_INT, G_TYPE_INT); image_signals[LINK_PRESSED] = g_signal_new ("link_pressed", G_OBJECT_CLASS_TYPE (klass), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (DwImageClass, link_pressed), NULL, NULL, p_Dw_marshal_link_button, G_TYPE_BOOLEAN, 4, G_TYPE_INT, G_TYPE_INT, G_TYPE_INT, G_TYPE_UINT); image_signals[LINK_RELEASED] = g_signal_new ("link_released", G_OBJECT_CLASS_TYPE (klass), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (DwImageClass, link_released), NULL, NULL, p_Dw_marshal_link_button, G_TYPE_BOOLEAN, 4, G_TYPE_INT, G_TYPE_INT, G_TYPE_INT, G_TYPE_UINT); image_signals[LINK_CLICKED] = g_signal_new ("link_clicked", G_OBJECT_CLASS_TYPE (klass), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (DwImageClass, link_clicked), NULL, NULL, p_Dw_marshal_link_button, G_TYPE_BOOLEAN, 4, G_TYPE_INT, G_TYPE_INT, G_TYPE_INT, G_TYPE_UINT); widget_class = (DwWidgetClass*)klass; widget_class->size_request = Dw_image_size_request; widget_class->size_allocate = Dw_image_size_allocate; widget_class->draw = Dw_image_draw; widget_class->button_press_event = Dw_image_button_press; widget_class->button_release_event = Dw_image_button_release; widget_class->motion_notify_event = Dw_image_motion_notify; widget_class->enter_notify_event = Dw_image_enter_notify; widget_class->leave_notify_event = Dw_image_leave_notify; widget_class->iterator = Dw_image_iterator;}/* * Standard GObject function. */static void Dw_image_finalize (GObject *object){ DwImage *image = DW_IMAGE (object); printf ("Enter Dw_image_finalize\n");#if 0 if (image->tooltip) a_Dw_tooltip_destroy (image->tooltip);#endif if (image->bmp) { UnloadBitmap (image->bmp); g_free (image->bmp); } if (image->scaled_bmp) { UnloadBitmap (image->scaled_bmp); g_free (image->scaled_bmp); } if (image->usemap_url) a_Url_free (image->usemap_url);#if 0 if (image->url) a_Dicache_unref (image->url, image->version);#endif if (image->alt_text) g_free (image->alt_text); G_OBJECT_CLASS(parent_class)->finalize (object);}/* * Standard Dw function. */static void Dw_image_size_request (DwWidget *widget, DwRequisition *requisition){ DwImage *image; image = DW_IMAGE (widget); if (image->bmp != NULL || (image->alt_text == NULL || image->alt_text[0] == '\0')) { requisition->width = image->width; requisition->ascent = image->height; requisition->descent = 0; } else { SIZE ext; FONTMETRICS fm; GetFontMetrics (widget->style->font->font, &fm); SelectFont (HDC_SCREEN, widget->style->font->font); if (image->alt_text_width == -1) { GetTextExtent (HDC_SCREEN, image->alt_text, -1, &ext); image->alt_text_width = ext.cx; } requisition->width = image->alt_text_width; requisition->ascent = fm.ascent; requisition->descent = fm.descent; } requisition->width += p_Dw_style_box_diff_width (widget->style); requisition->ascent += p_Dw_style_box_offset_y (widget->style); requisition->descent += p_Dw_style_box_rest_height (widget->style);}/* * Standard Dw function. */static void Dw_image_size_allocate (DwWidget *widget, DwAllocation *allocation){ DwImage *image; /* if image is moved only */ if (allocation->width == widget->allocation.width && allocation->ascent + allocation->descent == DW_WIDGET_HEIGHT(widget)) return; /* this is also done in a_Dw_widget_size_allocate, but Dw_image_scale needs this. */ widget->allocation = *allocation; image = DW_IMAGE (widget); if (image->bmp != NULL && image->width > 0 && image->height > 0) Dw_image_scale (image);}/* * Standard Dw function. */static void Dw_image_draw (DwWidget *widget, HDC hdc, DwRectangle *area){ gint32 vx, vy; DwRectangle content, intersection; DwImage *image = DW_IMAGE (widget);#if 0 guchar *buffer, *bstart;#endif int i; gboolean selected = FALSE; if (image->bmp) { p_Dw_widget_draw_widget_box (widget, hdc, area, FALSE); content.x = p_Dw_style_box_offset_x (widget->style); content.y = p_Dw_style_box_offset_y (widget->style); content.width = DW_WIDGET_CONTENT_WIDTH(widget); content.height = DW_WIDGET_CONTENT_HEIGHT(widget); if (p_Dw_rectangle_intersect (area, &content, &intersection)) { vx = p_Dw_widget_x_world_to_viewport (widget, widget->allocation.x); vy = p_Dw_widget_y_world_to_viewport (widget, widget->allocation.y);#if 0 if (image->scaled_buffer) buffer = image->scaled_buffer; else buffer = image->buffer; bstart = buffer + 3 * ( intersection.x - p_Dw_style_box_offset_x (widget->style)+ content.width * (intersection.y - p_Dw_style_box_offset_y (widget->style)) ); gc = widget->style->color->gc; gdk_draw_rgb_image ( DW_WIDGET_WINDOW (widget), gc, vx + intersection.x, vy + intersection.y, intersection.width, intersection.height, GDK_RGB_DITHER_MAX, bstart, content.width * 3);#else FillBoxWithBitmapPart (hdc, vx + intersection.x, vy + intersection.y, intersection.width, intersection.height, 0, 0, image->scaled_bmp ? image->scaled_bmp : image->bmp, intersection.x - p_Dw_style_box_offset_x (widget->style), intersection.y - p_Dw_style_box_offset_y (widget->style));#endif } } else { if (image->alt_text && image->alt_text[0]) { SIZE ext; FONTMETRICS fm; SelectFont (hdc, widget->style->font->font); GetFontMetrics (widget->style->font->font, &fm); if (image->alt_text_width == -1) { GetTextExtent (hdc, image->alt_text, -1, &ext); image->alt_text_width = ext.cx; } if (widget->allocation.width < image->alt_text_width || widget->allocation.ascent + widget->allocation.descent < fm.ascent + fm.descent) p_Dw_widget_will_clip (widget); p_Dw_widget_draw_widget_box (widget, hdc, area, FALSE);#if 0 gdk_draw_string (DW_WIDGET_WINDOW (widget), widget->style->font->font, widget->style->color->gc, p_Dw_widget_x_world_to_viewport (widget, widget->allocation.x), p_Dw_widget_y_world_to_viewport (widget, widget->allocation.y) + widget->style->font->font->ascent, image->alt_text);#else TextOut (hdc, p_Dw_widget_x_world_to_viewport (widget, widget->allocation.x), p_Dw_widget_y_world_to_viewport (widget, widget->allocation.y) + fm.ascent, image->alt_text);#endif } } for (i = 0; i < DW_HIGHLIGHT_NUM_LAYERS && !selected; i++) selected = image->selected[i]; if (selected) p_Dw_widget_draw_selected (widget, hdc, area);}/* * Standard Dw function. */static gboolean Dw_image_enter_notify (DwWidget *widget, DwWidget *last_widget, DWORD flags){#if 0 DwImage *image = DW_IMAGE (widget); if (image->tooltip) a_Dw_tooltip_on_enter (image->tooltip);#endif return FALSE;}/* * Standard Dw function. */static gboolean Dw_image_leave_notify (DwWidget *widget, DwWidget *next_widget, DWORD flags){ DwImage *image = DW_IMAGE (widget); gboolean return_val = FALSE;#if 0 if (image->tooltip) a_Dw_tooltip_on_leave (image->tooltip);#endif if (image->hover_link != -1) { image->hover_link = -1; g_signal_emit (G_OBJECT (widget), image_signals[LINK_ENTERED], 0, -1, -1, -1, &return_val); return return_val; } return FALSE;}/* * Standard Dw function. */static gboolean Dw_image_button_press (DwWidget *widget, gint32 x, gint32 y, DWORD flags){ DwImage *image = DW_IMAGE (widget); gint link_x, link_y; gboolean return_val = FALSE; Dw_image_find_link (image, x, y, &image->pressed_link, &link_x, &link_y); if (image->pressed_link >= 0) g_signal_emit (G_OBJECT (widget), image_signals[LINK_PRESSED], 0, image->pressed_link, link_x, link_y, flags, &return_val);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -