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

📄 dw_image.c

📁 浏览器的源代码,可移植到嵌入式设备.
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * 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 "msg.h"#include "dw_image.h"#include "dw_gtk_viewport.h"#include "prefs.h"#include "dw_marshal.h"#include "list.h"#include "dicache.h"#include "debug.h"#include <gdk/gdk.h>#include <gtk/gtk.h>#include <stdio.h>#include <string.h>static void Dw_image_init               (DwImage *image);static void Dw_image_class_init         (DwImageClass *klass);static void Dw_image_destroy            (GtkObject *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,                                         DwRectangle *area,                                         GdkEventExpose *event);static gboolean Dw_image_button_press   (DwWidget *widget,                                         gint32 x,                                         gint32 y,                                         GdkEventButton *event);static gboolean Dw_image_button_release (DwWidget *widget,                                         gint32 x,                                         gint32 y,                                         GdkEventButton *event);static gboolean Dw_image_motion_notify  (DwWidget *widget,                                         gint32 x,                                         gint32 y,                                         GdkEventMotion *event);static gboolean Dw_image_enter_notify   (DwWidget *widget,                                         DwWidget *last_widget,                                         GdkEventMotion *event);static gboolean Dw_image_leave_notify   (DwWidget *widget,                                         DwWidget *next_widget,                                         GdkEventMotion *event);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_row          (DwImage *image, gint y_dest);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;/* * Standard Gtk+ function. */GtkType a_Dw_image_get_type (void){   static GtkType type = 0;   if (!type) {      GtkTypeInfo info = {         "DwImage",         sizeof (DwImage),         sizeof (DwImageClass),         (GtkClassInitFunc) Dw_image_class_init,         (GtkObjectInitFunc) Dw_image_init,         (GtkArgSetFunc) NULL,         (GtkArgGetFunc) NULL,         (GtkClassInitFunc) NULL      };      type = gtk_type_unique (DW_TYPE_WIDGET, &info);   }   return type;}/* * Standard Gtk+ function. */DwWidget* a_Dw_image_new (DwImageType type, const gchar *alt_text){   GtkObject *object;   DwImage *image;   object = gtk_object_new (DW_TYPE_IMAGE, NULL);   DBG_OBJ_CREATE (object, "DwImage");   image = DW_IMAGE(object);   image->alt_text = g_strdup (alt_text);   return DW_WIDGET (object);}/* * Standard Gtk+ 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->buffer = NULL;   image->scaled_buffer = NULL;   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 Gtk+ function. */static void Dw_image_class_init (DwImageClass *klass){   GtkObjectClass *object_class;   DwWidgetClass *widget_class;   parent_class = gtk_type_class (DW_TYPE_WIDGET);   object_class = (GtkObjectClass*)klass;   object_class->destroy = Dw_image_destroy;   image_signals[LINK_ENTERED] =      gtk_signal_new ("link_entered",                      GTK_RUN_LAST,                      object_class->type,                      GTK_SIGNAL_OFFSET (DwImageClass, link_entered),                      p_Dw_marshal_link_enter,                      GTK_TYPE_BOOL,                      3, GTK_TYPE_INT, GTK_TYPE_INT, GTK_TYPE_INT);   image_signals[LINK_PRESSED] =      gtk_signal_new ("link_pressed",                      GTK_RUN_LAST,                      object_class->type,                      GTK_SIGNAL_OFFSET (DwImageClass, link_pressed),                      p_Dw_marshal_link_button,                      GTK_TYPE_BOOL,                      4, GTK_TYPE_INT, GTK_TYPE_INT, GTK_TYPE_INT,                      GTK_TYPE_GDK_EVENT);   image_signals[LINK_RELEASED] =      gtk_signal_new ("link_released",                      GTK_RUN_LAST,                      object_class->type,                      GTK_SIGNAL_OFFSET (DwImageClass, link_released),                      p_Dw_marshal_link_button,                      GTK_TYPE_BOOL,                      4, GTK_TYPE_INT, GTK_TYPE_INT, GTK_TYPE_INT,                      GTK_TYPE_GDK_EVENT);   image_signals[LINK_CLICKED] =      gtk_signal_new ("link_clicked",                      GTK_RUN_LAST,                      object_class->type,                      GTK_SIGNAL_OFFSET (DwImageClass, link_clicked),                      p_Dw_marshal_link_button,                      GTK_TYPE_BOOL,                      4, GTK_TYPE_INT, GTK_TYPE_INT, GTK_TYPE_INT,                      GTK_TYPE_GDK_EVENT);   gtk_object_class_add_signals (object_class, image_signals, LAST_SIGNAL);   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 Gtk+ function. */static void Dw_image_destroy (GtkObject *object){   DwImage *image = DW_IMAGE (object);   if (image->usemap_url)      a_Url_free (image->usemap_url);   if (image->url)      a_Dicache_unref (image->url, image->version);   g_free (image->alt_text);   g_free (image->scaled_buffer);   GTK_OBJECT_CLASS(parent_class)->destroy (object);}/* * Standard Dw function. */static void Dw_image_size_request (DwWidget *widget,                                   DwRequisition *requisition){   DwImage *image;   image = DW_IMAGE (widget);   if (image->buffer != NULL ||       (image->alt_text == NULL || image->alt_text[0] == '\0')) {      requisition->width = image->width;      requisition->ascent = image->height;      requisition->descent = 0;   } else {      if (image->alt_text_width == -1)         image->alt_text_width =            gdk_string_width (widget->style->font->font, image->alt_text);      requisition->width = image->alt_text_width;      requisition->ascent = widget->style->font->font->ascent;      requisition->descent = widget->style->font->font->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->buffer != NULL && image->width > 0 && image->height > 0)      Dw_image_scale (image);}/* * Standard Dw function. */static void Dw_image_draw (DwWidget *widget,                           DwRectangle *area,                           GdkEventExpose *event){   gint32 vx, vy;   DwRectangle content, intersection;   GdkGC *gc;   DwImage *image = DW_IMAGE (widget);   guchar *buffer, *bstart;   int i;   gboolean selected = FALSE;   if (image->buffer) {      p_Dw_widget_draw_widget_box (widget, 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);         gc = widget->style->color->gc;         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)) );         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 {      if (image->alt_text && image->alt_text[0]) {         if (image->alt_text_width == -1)            image->alt_text_width =               gdk_string_width (widget->style->font->font, image->alt_text);         if (widget->allocation.width < image->alt_text_width ||             widget->allocation.ascent + widget->allocation.descent             < widget->style->font->font->ascent             + widget->style->font->font->descent)            p_Dw_widget_will_clip (widget);         p_Dw_widget_draw_widget_box (widget, area, FALSE);         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);      }   }   for (i = 0; i < DW_HIGHLIGHT_NUM_LAYERS && !selected; i++)      selected = image->selected[i];   if (selected)      p_Dw_widget_draw_selected (widget, area);}/* * Standard Dw function. */static gboolean Dw_image_enter_notify (DwWidget *widget,                                       DwWidget *last_widget,                                       GdkEventMotion *event){   return FALSE;}/* * Standard Dw function. */static gboolean Dw_image_leave_notify (DwWidget *widget,                                       DwWidget *next_widget,                                       GdkEventMotion *event){   DwImage *image = DW_IMAGE (widget);   gboolean return_val = FALSE;   if (image->hover_link != -1) {      image->hover_link = -1;      gtk_signal_emit (GTK_OBJECT (widget), image_signals[LINK_ENTERED],                       -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,                                       GdkEventButton *event){   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)      gtk_signal_emit (GTK_OBJECT (widget), image_signals[LINK_PRESSED],                       image->pressed_link, link_x, link_y, event,                       &return_val);   return return_val;}/* * Standard Dw function. */static gboolean Dw_image_button_release (DwWidget *widget,                                         gint32 x,                                         gint32 y,                                         GdkEventButton *event){   DwImage *image = DW_IMAGE (widget);   gint link_pressed, link_released, link_x, link_y;   gboolean return_val1 = FALSE, return_val2 = FALSE;   link_pressed = image->pressed_link;   Dw_image_find_link (image, x, y, &link_released, &link_x, &link_y);   image->pressed_link = -1;   if (link_released >= 0) {      gtk_signal_emit (GTK_OBJECT (widget), image_signals[LINK_RELEASED],                       link_released, link_x, link_y, event, &return_val1);

⌨️ 快捷键说明

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