dw_style.c

来自「微型浏览器」· C语言 代码 · 共 393 行

C
393
字号
/* * File: dw_page.c * * Copyright (C) 2001 Sebastian Geerken <S.Geerken@ping.de> * * 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 <gdk/gdk.h>#include <stdio.h>#include <string.h>#include <ctype.h>#include "dw_style.h"#define EQUIV(a, b) (((a) && (b)) || (!(a) && !(b)))#define Dw_style_font_ref(font)   ((font)->ref_count++)#define Dw_style_font_unref(font) if (--((font)->ref_count) == 0) \                                     Dw_style_font_remove (font)#define Dw_style_color_ref(color)   ((color)->ref_count++)#define Dw_style_color_unref(color) if (--((color)->ref_count) == 0) \                                       Dw_style_color_remove (color)static GHashTable *fonts_table;static GHashTable *colors_table;static gint styles_num = 0;static gint Dw_style_font_equal(gconstpointer v1, gconstpointer v2);static guint Dw_style_font_hash(gconstpointer key);static void Dw_style_font_remove(DwStyleFont * font);static void Dw_style_color_remove(DwStyleColor * color);/* ---------------------------------------------------------------------- * *    Initialization / Cleaning up * * ---------------------------------------------------------------------- *//* * Initialize the DwStyle submodule. */void a_Dw_style_init(void){	fonts_table = g_hash_table_new(Dw_style_font_hash, Dw_style_font_equal);	colors_table = g_hash_table_new(g_direct_hash, g_direct_equal);}/* * Called by a_Dw_style_freeall. */static void Dw_style_count_fonts(gpointer key, gpointer value, gpointer user_data){	DwStyleFont *font = (DwStyleFont *) key;	gint *count = (int *) user_data;	count[0]++;	count[1] += font->ref_count;}/* * Called by a_Dw_style_freeall. */static void Dw_style_count_colors(gpointer key, gpointer value, gpointer user_data){	DwStyleColor *color = (DwStyleColor *) value;	gint *count = (int *) user_data;	count[0]++;	count[1] += color->ref_count;}/* * Free variables used by DwStyle, and do a check whether memory * management works properly. */void a_Dw_style_freeall(void){	gint count[2];	if (styles_num)		g_warning("%d styles left", styles_num);	count[0] = count[1] = 0;	g_hash_table_foreach(fonts_table, Dw_style_count_fonts, count);	if (count[0] || count[1])		g_warning("%d fonts (%d references) left", count[0], count[1]);	count[0] = count[1] = 0;	g_hash_table_foreach(colors_table, Dw_style_count_colors, count);	if (count[0] || count[1])		g_warning("%d colors (%d references) left", count[0], count[1]);	g_hash_table_destroy(fonts_table);	g_hash_table_destroy(colors_table);}/* ---------------------------------------------------------------------- * *    Styles * * ---------------------------------------------------------------------- *//* * Set all style fields except font and color to reasonable defaults. */void a_Dw_style_init_values(DwStyle * style_attrs, GdkWindow * window){	style_attrs->link = -1;	style_attrs->map = 0;	style_attrs->uline = -1;	style_attrs->strike = -1;	style_attrs->SubSup = -1;	style_attrs->left_indent_first = 0;	style_attrs->left_indent_rest = 0;	style_attrs->right_indent = 0;	style_attrs->flags = DW_STYLE_ALIGN_LEFT;}/* * Return a new DwStyle, with increased reference pointer. */DwStyle *a_Dw_style_new(DwStyle * style_attrs, GdkWindow * window){	DwStyle *style;	style = g_new(DwStyle, 1);	*style = *style_attrs;	style->ref_count = 1;	Dw_style_font_ref(style->font);	Dw_style_color_ref(style->color);	styles_num++;	return style;}/* * Remove a style (called when ref_count == 0). */void Dw_style_remove(DwStyle * style){	Dw_style_font_unref(style->font);	Dw_style_color_unref(style->color);	g_free(style);	styles_num--;}/* ---------------------------------------------------------------------- * *    Fonts * * ---------------------------------------------------------------------- *//* * Create the GdkFont. font->name contains one name. If try_all is * TRUE, try also standard fonts, if anything else fails. */static void Dw_style_font_realize(DwStyleFont * font, gboolean try_all){	char fontname[256], *ItalicChar;//	ItalicChar = prefs.use_oblique ? "o" : "i";	ItalicChar = "i";	sprintf(fontname, "-*-%s-%s-%s-*-*-%d-*-75-75-*-*-*-*", font->name, font->bold ? "bold" : "medium", font->italic ? ItalicChar : "r", font->size);	font->font = gdk_font_load(fontname);	if (font->font == NULL && font->italic) {		sprintf(fontname, "-*-%s-%s-%s-*-*-%d-*-75-75-*-*-*-*", font->name, font->bold ? "bold" : "medium", (*ItalicChar == 'o') ? "i" : "o", font->size);		font->font = gdk_font_load(fontname);	}	if (try_all) {		if (font->font == NULL) {			/* Can't load the font - substitute the default instead. */			font->font = gdk_font_load("-adobe-helvetica-medium-r-normal--*-100-*-*-*-*-*-*");		}		if (font->font == NULL) {			/* Try another platform-font that should be available. (iPaq) */			font->font = gdk_font_load("-misc-fixed-medium-r-normal--13-120-75-75-c-80-iso8859-1");		}	}	if (font->font)		font->space_width = gdk_char_width(font->font, ' ');}/* * Used for the font_table hash table. */static gint Dw_style_font_equal(gconstpointer v1, gconstpointer v2){	const DwStyleFont *font1 = (DwStyleFont *) v1, *font2 = (DwStyleFont *) v2;	return (font1->size == font2->size && EQUIV(font1->bold, font2->bold) && EQUIV(font1->italic, font2->italic) && strcmp(font1->name, font2->name) == 0);}/* * Used for the font_table hash table. */static guint Dw_style_font_hash(gconstpointer key){	const DwStyleFont *font = (DwStyleFont *) key;	guint h;	h = g_str_hash(font->name);	h = (h << 5) - h + font->size;	h = (h << 5) - h + (font->bold ? 1 : 0);	h = (h << 5) - h + (font->italic ? 1 : 0);	return h;}/* * Returns a new or already existing font. This function is only used * internally, and called by a_Dw_style_font_new and * a_Dw_style_font_new_from_list. * * Note that the reference counter is not increased/set to zero, it * will be increased by a_Dw_style_new. If try_all is TRUE, try also * standard fonts, if anything else fails. */static DwStyleFont *Dw_style_font_new_internal(DwStyleFont * font_attrs, gboolean try_all){	DwStyleFont *font;	gpointer dummy;	if (g_hash_table_lookup_extended(fonts_table, font_attrs, (gpointer *) & font, &dummy))		return font;	else {		font = g_new(DwStyleFont, 1);		font->size = font_attrs->size;		font->bold = font_attrs->bold;		font->italic = font_attrs->italic;		font->name = g_strdup(font_attrs->name);		font->ref_count = 0;		Dw_style_font_realize(font, try_all);		if (font->font) {			g_hash_table_insert(fonts_table, font, (gpointer) 1);			return font;		} else {			g_free(font);			return NULL;		}	}}/* * Return a new or already existing font, with one name in * font_attrs->name. See also Dw_style_font_new_internal. */DwStyleFont *a_Dw_style_font_new(DwStyleFont * font_attrs){	DwStyleFont *font;	font = Dw_style_font_new_internal(font_attrs, TRUE);	if (font == NULL)		g_error("Could not find any font.");	return font;}/* * Return a new or already existing font, with font_attrs->name * containing a comma separated list of names. See also * Dw_style_font_new_internal. */DwStyleFont *a_Dw_style_font_new_from_list(DwStyleFont * font_attrs){	DwStyleFont *font = NULL, font_attrs2;	char *comma, *list, *current;	font_attrs2 = *font_attrs;	current = list = g_strdup(font_attrs->name);	while (current && (font == NULL)) {		comma = strchr(current, ',');		if (comma)			*comma = 0;		font_attrs2.name = current;		font = Dw_style_font_new_internal(&font_attrs2, FALSE);		if (font)			break;		if (comma) {			current = comma + 1;			while (isspace(*current))				current++;		} else			current = NULL;	}	g_free(list);	if (font == NULL) {		font_attrs2.name = "helvetica";		font = Dw_style_font_new_internal(&font_attrs2, TRUE);	}	if (font == NULL)		g_error("Could not find any font.");	return font;}/* * Remove a font (called when ref_count == 0). */static void Dw_style_font_remove(DwStyleFont * font){	g_hash_table_remove(fonts_table, font);	gdk_font_unref(font->font);	g_free(font);}/* ---------------------------------------------------------------------- * *    Colors * * ---------------------------------------------------------------------- *//* * Return a new or already existing color. color_val has the form * 0xrrggbb. */DwStyleColor *a_Dw_style_color_new(gint color_val, GdkWindow * window){	DwStyleColor *color;	gint red, green, blue;	color = g_hash_table_lookup(colors_table, (gconstpointer) color_val);	if (color == NULL) {		color = g_new(DwStyleColor, 1);		color->ref_count = 0;		color->color_val = color_val;		red = (color_val >> 16) & 255;		red |= red << 8;		green = (color_val >> 8) & 255;		green |= green << 8;		blue = color_val & 255;		blue |= blue << 8;		color->color.red = red;		color->color.green = green;		color->color.blue = blue;		gdk_color_alloc(gdk_window_get_colormap(window), &color->color);		color->gc = gdk_gc_new(window);		gdk_gc_set_foreground(color->gc, &color->color);		g_hash_table_insert(colors_table, (gpointer) color_val, color);	}	return color;}/* * Remove a color (called when ref_count == 0). */static void Dw_style_color_remove(DwStyleColor * color){	g_hash_table_remove(colors_table, (gpointer) color->color_val);	g_free(color);}

⌨️ 快捷键说明

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