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

📄 dw_page.c

📁 嵌入式浏览器Dillo源码
💻 C
📖 第 1 页 / 共 4 页
字号:
/* * File: dw_page.c * * Copyright (C) 1997 Raph Levien <raph@acm.org> * Copyright (C) 1999 Luca Rota <drake@freemail.it> * * 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. *//* * This module contains the Dw_page widget, which is the "back end" to * Web text widgets including html. */#include <ctype.h>#include <string.h>#include <stdio.h>#include <gtk/gtk.h>#include "list.h"#include "dw_page.h"#include "dw_marshal.h"#include "dw_gtk_viewport.h"#include "prefs.h"//#define DEBUG_LEVEL 2#include "debug.h"static void Dw_page_init          (DwPage *page);static void Dw_page_class_init    (DwPageClass *klass);static void Dw_page_destroy       (GtkObject *object);static void Dw_page_size_request      (DwWidget *widget,                                      DwRequisition *requisition);static void Dw_page_get_extremes      (DwWidget *widget,                                       DwExtremes *extremes);static void Dw_page_size_allocate     (DwWidget *widget,                                       DwAllocation *allocation);static void Dw_page_mark_change       (DwWidget *widget,                                       gint ref);static void Dw_page_set_width         (DwWidget *widget,                                       gint32 width);static void Dw_page_set_ascent        (DwWidget *widget,                                       gint32 ascent);static void Dw_page_set_descent       (DwWidget *widget,                                       gint32 descent);static void Dw_page_draw              (DwWidget *page,                                       DwRectangle *area,                                       GdkEventExpose *event);static gint Dw_page_button_press      (DwWidget *widget,                                       gint32 x,                                       gint32 y,                                       GdkEventButton *event);static gint Dw_page_button_release    (DwWidget *widget,                                       gint32 x,                                       gint32 y,                                       GdkEventButton *event);static gint Dw_page_motion_notify     (DwWidget *widget,                                       gint32 x,                                       gint32 y,                                       GdkEventMotion *event);static gint Dw_page_leave_notify      (DwWidget *widget,                                       DwWidget *next_widget,                                       GdkEventMotion *event);static void Dw_page_add               (DwContainer *container,                                       DwWidget *widget);static void Dw_page_remove            (DwContainer *container,                                       DwWidget *widget);static void Dw_page_forall            (DwContainer *container,                                       DwCallback callback,                                       gpointer callback_data);static gint Dw_page_findtext          (DwContainer *container,                                       gpointer FP, gpointer KP,                                       gchar *NewKey);static void Dw_page_rewrap            (DwPage *page);/* * Returns the x offset (the indentation plus any offset needed for * centering or right justification) for the line. The offset returned * is relative to the page *content* (i.e. without border etc.). */#define Dw_page_line_x_offset(page, line) \   ( (page)->inner_padding + (line)->left_offset + \     ((line) == (page)->lines ? (page)->line1_offset : 0) )/* * Like Dw_style_box_offset_x, but relative to the allocation (i.e. * including border etc.). */#define Dw_page_line_total_x_offset(page, line) \   ( Dw_page_line_x_offset (page, line) + \     p_Dw_style_box_offset_x (((DwWidget*)(page))->style) )enum{   LINK_ENTERED,   LINK_PRESSED,   LINK_RELEASED,   LINK_CLICKED,   LAST_SIGNAL};static DwContainerClass *parent_class;static guint page_signals[LAST_SIGNAL] = { 0 };/* * Return the type of DwPage */GtkType a_Dw_page_get_type (void){   static GtkType type = 0;   if (!type) {      GtkTypeInfo info = {         "DwPage",         sizeof (DwPage),         sizeof (DwPageClass),         (GtkClassInitFunc) Dw_page_class_init,         (GtkObjectInitFunc) Dw_page_init,         (GtkArgSetFunc) NULL,         (GtkArgGetFunc) NULL,         (GtkClassInitFunc) NULL      };      type = gtk_type_unique (DW_TYPE_CONTAINER, &info);   }   return type;}/* * Create a new DwPage */DwWidget* a_Dw_page_new (void){   GtkObject *object;   object = gtk_object_new (DW_TYPE_PAGE, NULL);   return DW_WIDGET (object);}/* * Initialize a DwPage */static void Dw_page_init (DwPage *page){   DW_WIDGET_SET_FLAGS (page, DW_USES_HINTS);   page->list_item = FALSE;   page->inner_padding = 0;   page->line1_offset = 0;   /*    * The initial sizes of page->lines and page->words should not be    * too high, since this will waste much memory with tables    * containing many small cells. The few more calls to realloc    * should not decrease the speed considerably.    * (Current setting is for minimal memory usage. An interesting fact    * is that high values decrease speed due to memory handling overhead!)    * todo: Some tests would be useful.    */   page->num_lines_max = 1; /* 2 */   page->num_lines = 0;   page->lines = NULL;      /* g_new(DwPageLine, page->num_lines_max); */   page->num_words_max = 1; /* 8 */   page->num_words = 0;   page->words = NULL;      /* g_new(DwPageWord, page->num_words_max); */   page->last_line_width = 0;   page->wrap_ref = -1;   page->hover_link = -1;   /* random values */   page->avail_width = 100;   page->avail_ascent = 100;   page->avail_descent = 0;}/* * Initialize the DwPage's class */static void Dw_page_class_init (DwPageClass *klass){   GtkObjectClass *object_class;   DwWidgetClass *widget_class;   DwContainerClass *container_class;   object_class = (GtkObjectClass*) klass;   widget_class = (DwWidgetClass*) klass;   container_class = (DwContainerClass*) klass;   parent_class = gtk_type_class (DW_TYPE_CONTAINER);   /* todo: the link_xxx signals should return boolean values, which are    * then returned by the event signal function of DwPage. But I don't    * know that much about Gtk+ signals :-(    * --SG    */   page_signals[LINK_ENTERED] =      gtk_signal_new ("link_entered",                      GTK_RUN_FIRST,                      object_class->type,                      GTK_SIGNAL_OFFSET (DwPageClass, link_entered),                      p_Dw_marshal_link_enter,                      GTK_TYPE_NONE,                      3, GTK_TYPE_INT, GTK_TYPE_INT, GTK_TYPE_INT);   page_signals[LINK_PRESSED] =      gtk_signal_new ("link_pressed",                      GTK_RUN_FIRST,                      object_class->type,                      GTK_SIGNAL_OFFSET (DwPageClass, link_pressed),                      p_Dw_marshal_link_button,                      GTK_TYPE_NONE,                      4, GTK_TYPE_INT, GTK_TYPE_INT, GTK_TYPE_INT,                      GTK_TYPE_GDK_EVENT);   page_signals[LINK_RELEASED] =      gtk_signal_new ("link_released",                      GTK_RUN_FIRST,                      object_class->type,                      GTK_SIGNAL_OFFSET (DwPageClass, link_released),                      p_Dw_marshal_link_button,                      GTK_TYPE_NONE,                      4, GTK_TYPE_INT, GTK_TYPE_INT, GTK_TYPE_INT,                      GTK_TYPE_GDK_EVENT);   page_signals[LINK_CLICKED] =      gtk_signal_new ("link_clicked",                      GTK_RUN_FIRST,                      object_class->type,                      GTK_SIGNAL_OFFSET (DwPageClass, link_clicked),                      p_Dw_marshal_link_button,                      GTK_TYPE_NONE,                      4, GTK_TYPE_INT, GTK_TYPE_INT, GTK_TYPE_INT,                      GTK_TYPE_GDK_EVENT);   gtk_object_class_add_signals (object_class, page_signals, LAST_SIGNAL);   object_class->destroy = Dw_page_destroy;   widget_class->size_request = Dw_page_size_request;   widget_class->get_extremes = Dw_page_get_extremes;   widget_class->size_allocate = Dw_page_size_allocate;   widget_class->mark_size_change = Dw_page_mark_change;   widget_class->mark_extremes_change = Dw_page_mark_change;   widget_class->set_width = Dw_page_set_width;   widget_class->set_ascent = Dw_page_set_ascent;   widget_class->set_descent = Dw_page_set_descent;   widget_class->draw = Dw_page_draw;   widget_class->button_press_event = Dw_page_button_press;   widget_class->button_release_event = Dw_page_button_release;   widget_class->motion_notify_event = Dw_page_motion_notify;   widget_class->leave_notify_event = Dw_page_leave_notify;   container_class->add = Dw_page_add;   container_class->remove = Dw_page_remove;   container_class->forall = Dw_page_forall;   container_class->findtext = Dw_page_findtext;   klass->link_entered = NULL;   klass->link_pressed = NULL;   klass->link_released = NULL;   klass->link_clicked = NULL;}/* * Destroy the page (standard Gtk+ function) */static void Dw_page_destroy (GtkObject *object){   DwPage *page = DW_PAGE (object);   DwPageWord *word;   gint i;   DEBUG_MSG(10, "Dw_page_destroy\n");   for (i = 0; i < page->num_words; i++) {      word = &page->words[i];      if (word->content_type == DW_PAGE_CONTENT_WIDGET)         gtk_object_unref(GTK_OBJECT(word->content.widget));      else if (word->content_type == DW_PAGE_CONTENT_TEXT)         g_free(word->content.text);      else if (word->content_type == DW_PAGE_CONTENT_ANCHOR)         g_free(word->content.anchor);      a_Dw_style_unref (word->style);      a_Dw_style_unref (word->space_style);   }   g_free (page->lines);   g_free (page->words);   /* Make sure we don't own widgets anymore. Necessary before call of      parent_class->destroy. */   page->num_words = 0;   page->num_lines = 0;   (* GTK_OBJECT_CLASS(parent_class)->destroy) (object);}/* * Standard Dw function * * The ascent of a page is the ascent of the first line, plus * padding/border/margin. This can be used to align the first lines * of several pages in a horizontal line. */static void Dw_page_size_request (DwWidget *widget,                                  DwRequisition *requisition){   DwPage *page = DW_PAGE (widget);   DwPageLine *last_line;   gint height;   Dw_page_rewrap(page);   if (page->num_lines > 0) {      last_line = &page->lines[page->num_lines - 1];      requisition->width =         MAX (last_line->max_line_width, page->last_line_width);      /* Note: the break_space of the last line is ignored, so breaks         at the end of a page are not visible. */      height =         last_line->top + last_line->ascent + last_line->descent +         p_Dw_style_box_rest_height (widget->style);      requisition->ascent = page->lines[0].top + page->lines[0].ascent;      requisition->descent = height - requisition->ascent;   } else {      requisition->width = page->last_line_width;      requisition->ascent = p_Dw_style_box_offset_y (widget->style);      requisition->descent = p_Dw_style_box_rest_height (widget->style);   }   requisition->width +=      page->inner_padding + p_Dw_style_box_diff_width (widget->style);   if (requisition->width < page->avail_width)      requisition->width = page->avail_width;}/* * Get the extremes of a word within a page. */static void Dw_page_get_word_extremes (DwPageWord *word,                                       DwExtremes *extremes){   if (word->content_type == DW_PAGE_CONTENT_WIDGET) {      if (DW_WIDGET_USES_HINTS (word->content.widget))         a_Dw_widget_get_extremes (word->content.widget, extremes);      else {         if (DW_STYLE_IS_PERCENTAGE (word->content.widget->style->width)) {            extremes->min_width = 0;            if (DW_WIDGET_HAS_CONTENT (word->content.widget))               extremes->max_width = DW_INFINITY;            else               extremes->max_width = 0;         } else if (DW_STYLE_IS_LENGTH (word->content.widget->style->width)) {            extremes->min_width = extremes->max_width =               DW_STYLE_GET_LENGTH(word->content.widget->style->width,                                   word->style->font);         } else            a_Dw_widget_get_extremes (word->content.widget, extremes);      }   } else {      extremes->min_width = word->size.width;      extremes->max_width = word->size.width;   }}/* * Standard Dw function */static void Dw_page_get_extremes (DwWidget *widget,                                  DwExtremes *extremes){   DwPage *page = DW_PAGE (widget);   DwExtremes word_extremes;   DwPageLine *line;   DwPageWord *word;   gint word_index, line_index;   gint32 par_min, par_max;   gboolean nowrap;   DEBUG_MSG (4, "Dw_page_get_extremes\n");   if (page->num_lines == 0) {      /* empty page */      extremes->min_width = 0;

⌨️ 快捷键说明

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