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

📄 dw_page.c

📁 微型浏览器
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * 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.  */#define TRACE_GTK_METHODS#undef NO_WINDOW#define HUGE_WINDOW#define DW_PAGE_MAX_WINDOW_SIZE 32760#include <ctype.h>#include <string.h>#include <stdio.h>#include <gtk/gtk.h>#include "list.h"#include "dw_page.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_size_allocate(DwWidget * widget, DwAllocation * allocation);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 void Dw_page_realize(DwWidget * widget);static void Dw_page_unrealize(DwWidget * widget);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 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 void Dw_page_real_link_entered(DwPage * page, const char *url);static void Dw_page_rewrap(DwPage * page);static gint Dw_page_line_x_offset(DwPage * page, DwPageLine * line);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,		};		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){	page->num_lines_max = 16;	page->num_lines = 0;	page->lines = g_new(DwPageLine, page->num_lines_max);	page->num_words_max = 512;	page->num_words = 0;	page->current_word = 0;	page->words = g_new(DwPageWord, page->num_words_max);	page->num_links_max = 16;	page->num_links = 0;	page->links = g_new(DwPageLink, page->num_links_max);	page->last_line_max_width = 0;	page->hover_link = -1;	/* end stuff from gtk_page_init. */	page->link_color    = 0x0000ff; /* blue */	page->visited_color = 0x736f6e; /* gray */	page->bgnd_color    = 0xffffff; /* white */	page->x_click = -1;	page->current_map = 0;	page->num_shapes = 0;	page->num_shapes_max = 8;	/* not a critical value */	page->shapes = g_new(DwPageShape, page->num_shapes_max);	/* random values */	page->avail_width = 100;	page->avail_ascent = 100;	page->avail_descent = 0;	page->wrapped_width = 100;	/* todo: ??? */	page->wrapped_ascent = 100;	page->wrapped_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), gtk_marshal_NONE__POINTER, GTK_TYPE_NONE, 1, GTK_TYPE_POINTER);	page_signals[LINK_PRESSED] = gtk_signal_new("link_pressed", GTK_RUN_FIRST, object_class->type, GTK_SIGNAL_OFFSET(DwPageClass, link_pressed), gtk_marshal_NONE__POINTER_POINTER, GTK_TYPE_NONE, 2, GTK_TYPE_POINTER, 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), gtk_marshal_NONE__POINTER_POINTER, GTK_TYPE_NONE, 2, GTK_TYPE_POINTER, 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), gtk_marshal_NONE__POINTER_POINTER, GTK_TYPE_NONE, 2, GTK_TYPE_POINTER, 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->size_allocate = Dw_page_size_allocate;	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->realize = Dw_page_realize;	widget_class->unrealize = Dw_page_unrealize;	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;	container_class->add = Dw_page_add;	container_class->remove = Dw_page_remove;	container_class->forall = Dw_page_forall;	klass->link_entered = Dw_page_real_link_entered;	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;	DwPageWord *word;	gint word_index;	gint link_index;	page = DW_PAGE(object);	for (word_index = 0; word_index < page->num_words; word_index++) {		word = &page->words[word_index];		if (word->content_type == DW_PAGE_CONTENT_WIDGET)			gtk_object_destroy(GTK_OBJECT(word->content.widget.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);	}	g_free(page->lines);	page->num_words = 0;	/* make sure we don't own widgets anymore */	g_free(page->shapes);	for (link_index = 0; link_index < page->num_links; link_index++) {		g_free(page->links[link_index].url);		g_free(page->links[link_index].alt);	}	g_free(page->links);	(*(GTK_OBJECT_CLASS(parent_class)->destroy)) (object);}/* * Standard Dw function */static void Dw_page_size_request(DwWidget * widget, DwRequisition * requisition){	DwPage *page;	DwPageWord *word;	gboolean must_rewrap = FALSE;	int word_index;	page = DW_PAGE(widget);	/* Rewrapping is only necessary, when the viewport size has changed,	 * or a child widget needs resizing. In a third case, when new words have	 * been added, there is no need to call Dw_page_rewrap.	 *	 * The code can be optimized: If in the first case the width did not	 * change, and there are no child widgets with a relative height,	 * rewrapping is neither necessary.	 */	if (page->wrapped_width != page->avail_width || page->wrapped_ascent != page->avail_ascent || page->wrapped_descent != page->avail_descent) {		must_rewrap = TRUE;		/*g_print(">>>    Dw_page_size_request: new size\n"); */	} else {		for (word_index = 0; !must_rewrap && word_index < page->num_words; word_index++) {			word = &page->words[word_index];			if (word->content_type == DW_PAGE_CONTENT_WIDGET && DW_WIDGET_NEEDS_RESIZE(word->content.widget.widget))				must_rewrap = TRUE;		}		/*if (must_rewrap)		   g_print(">>>    Dw_page_size_request: children\n"); */	}	if (must_rewrap) {		Dw_page_rewrap(page);		page->wrapped_width = page->avail_width;		page->wrapped_ascent = page->avail_ascent;		page->wrapped_descent = page->avail_descent;	}	requisition->width = page->real_width;	if (page->num_lines > 0)		requisition->ascent = page->lines[page->num_lines - 1].y_top + page->lines[page->num_lines - 1].y_ascent + page->lines[page->num_lines - 1].y_descent;	else		requisition->ascent = 0;	/* todo: requisition->descent could get a useful value (as in TeX),	   but I don't have any idea where this will really be needed ;-) */	requisition->descent = 0;}/* * Standard Dw function */static void Dw_page_size_allocate(DwWidget * widget, DwAllocation * allocation){	DwPage *page;	int line_index, word_index;	DwPageLine *line;	DwPageWord *word;	int x_cursor;	DwAllocation child_allocation;	page = DW_PAGE(widget);	//g_print ("Dw_page_size_allocate\n");	for (line_index = 0; line_index < page->num_lines; line_index++) {		line = &(page->lines[line_index]);		x_cursor = Dw_page_line_x_offset(page, line);		for (word_index = line->first_word; word_index < line->last_word; word_index++) {			word = &(page->words[word_index]);			if (word->content_type == DW_PAGE_CONTENT_WIDGET) {				/*g_print ("   %20s: (%d, %d)\n",				   gtk_type_name (GTK_OBJECT_TYPE				   (word->content.widget.widget)),				   x_cursor, line->y_top); */				/* todo: justification within the line is done here! */				child_allocation.x = x_cursor + widget->allocation.x;				/* align=top:				   child_allocation.y = line->y_top + widget->allocation.y;				 */				/* align=bottom (base line) */				child_allocation.y = line->y_top + widget->allocation.y + (line->y_ascent - word->y_ascent);				child_allocation.width = word->x_size;				child_allocation.ascent = word->y_ascent;				child_allocation.descent = word->y_descent;				a_Dw_widget_size_allocate(word->content.widget.widget, &child_allocation);			}			x_cursor += (word->x_size + word->x_space);		}	}	widget->allocation = *allocation;}/* * Standard Dw function */static void Dw_page_set_width(DwWidget * widget, gint32 width){	DwPage *page;	page = DW_PAGE(widget);	//g_print (">>> Dw_page_set_width: %d -> %d\n", page->avail_width, width);	if (page->avail_width != width) {		page->avail_width = width;		Dw_widget_queue_resize(widget);	}}/* * Standard Dw function */static void Dw_page_set_ascent(DwWidget * widget, gint32 ascent){	DwPage *page;	page = DW_PAGE(widget);	//g_print (">>> Dw_page_set_ascent: %d -> %d\n", page->avail_ascent, ascent);	if (page->avail_ascent != ascent) {		page->avail_ascent = ascent;		Dw_widget_queue_resize(widget);	}}/* * Standard Dw function */static void Dw_page_set_descent(DwWidget * widget, gint32 descent){	DwPage *page;	page = DW_PAGE(widget);	//g_print (">>> Dw_page_set_descent: %d -> %d\n", page->avail_descent,	//descent);	if (page->avail_descent != descent) {		page->avail_descent = descent;		Dw_widget_queue_resize(widget);	}}/* * Standard Dw function */static void Dw_page_realize(DwWidget * widget){	DwPage *page = DW_PAGE(widget);	page->hand_cursor = gdk_cursor_new(GDK_HAND2);}/* * Standard Dw function */static void Dw_page_unrealize(DwWidget * widget){	DwPage *page = DW_PAGE(widget);	gdk_cursor_destroy(page->hand_cursor);}/* * Standard Dw function */static void Dw_page_add(DwContainer * container, DwWidget * widget){	/* todo */}/* * Standard Dw function */static void Dw_page_remove(DwContainer * container, DwWidget * widget){	/* todo */}/* * Standard Dw function */static void Dw_page_forall(DwContainer * container, DwCallback callback, gpointer callback_data){	DwPage *page;	int word_index;	DwPageWord *word;	page = DW_PAGE(container);	for (word_index = 0; word_index < page->num_words; word_index++) {		word = &page->words[word_index];		if (word->content_type == DW_PAGE_CONTENT_WIDGET)			(*callback) (word->content.widget.widget, callback_data);	}}static void Dw_page_real_link_entered(DwPage * page, const char *url){	a_Dw_widget_set_cursor(DW_WIDGET(page), url ? page->hand_cursor : NULL);}/* todo:

⌨️ 快捷键说明

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