📄 dw_style.c
字号:
min = green; else min = blue; } else { if (green > blue) max = green; else max = blue; if (red < blue) min = red; else min = blue; } l = (max + min) / 2; s = 0; h = 0; if (max != min) { if (l <= 0.5) s = (max - min) / (max + min); else s = (max - min) / (2 - max - min); delta = max -min; if (red == max) h = (green - blue) / delta; else if (green == max) h = 2 + (blue - red) / delta; else if (blue == max) h = 4 + (red - green) / delta; h *= 60; if (h < 0.0) h += 360; } *r = h; *g = l; *b = s;}/* * Copied from gtkstyle.c. * Convert HLS into RGB. */static void Dw_style_hls_to_rgb (gdouble *h, gdouble *l, gdouble *s){ gdouble hue; gdouble lightness; gdouble saturation; gdouble m1, m2; gdouble r, g, b; lightness = *l; saturation = *s; if (lightness <= 0.5) m2 = lightness * (1 + saturation); else m2 = lightness + saturation - lightness * saturation; m1 = 2 * lightness - m2; if (saturation == 0) { *h = lightness; *l = lightness; *s = lightness; } else { hue = *h + 120; while (hue > 360) hue -= 360; while (hue < 0) hue += 360; if (hue < 60) r = m1 + (m2 - m1) * hue / 60; else if (hue < 180) r = m2; else if (hue < 240) r = m1 + (m2 - m1) * (240 - hue) / 60; else r = m1; hue = *h; while (hue > 360) hue -= 360; while (hue < 0) hue += 360; if (hue < 60) g = m1 + (m2 - m1) * hue / 60; else if (hue < 180) g = m2; else if (hue < 240) g = m1 + (m2 - m1) * (240 - hue) / 60; else g = m1; hue = *h - 120; while (hue > 360) hue -= 360; while (hue < 0) hue += 360; if (hue < 60) b = m1 + (m2 - m1) * hue / 60; else if (hue < 180) b = m2; else if (hue < 240) b = m1 + (m2 - m1) * (240 - hue) / 60; else b = m1; *h = r; *l = g; *s = b; }}/* * Create the necessary recources (GdkColor, GdkGC). * k is a factor the color is multiplied with before, this is needed * for shaded colors. */static void Dw_style_color_create (gint color_val, GdkWindow *window, GdkColor *color, GdkGC **gc, gint d){ gint red, green, blue; gdouble hue, lightness, saturation; red = (color_val >> 16) & 255; green = (color_val >> 8) & 255; blue = color_val & 255; if (d) { hue = (gdouble)red / 255; lightness = (gdouble)green / 255; saturation = (gdouble)blue / 255; DEBUG_MSG (1, "Shaded by %1.3g: (%1.3g, %1.3g, %1.3g) -> ", k, hue, lightness, saturation); Dw_style_rgb_to_hls (&hue, &lightness, &saturation); if (lightness > 0.8) { if (d > 0) lightness -= 0.2; else lightness -= 0.4; } else if (lightness < 0.2) { if (d > 0) lightness += 0.4; else lightness += 0.2; } else lightness += d * 0.2; Dw_style_hls_to_rgb (&hue, &lightness, &saturation); DEBUG_MSG (1, "(%1.3g, %1.3g, %1.3g)\n", hue, lightness, saturation); red = hue * 255; green = lightness * 255; blue = saturation * 255; } blue |= blue << 8; red |= red << 8; green |= green << 8; color->red = red; color->green = green; color->blue = blue; gdk_color_alloc (gdk_window_get_colormap (window), color); *gc = gdk_gc_new (window); gdk_gc_set_foreground (*gc, color);}/* 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; color = g_hash_table_lookup (colors_table, GINT_TO_POINTER (color_val)); if (color == NULL) { color = g_new (DwStyleColor, 1); color->ref_count = 0; color->color_val = color_val; Dw_style_color_create (color_val, window, &color->color, &color->gc, 0); Dw_style_color_create (color_val ^ 0xffffff, window, &color->inverse_color, &color->inverse_gc, 0); g_hash_table_insert (colors_table, GINT_TO_POINTER (color_val), color); g_hash_table_insert (colors_table, GINT_TO_POINTER (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, GINT_TO_POINTER (color->color_val)); gdk_gc_destroy (color->gc); gdk_gc_destroy (color->inverse_gc); g_free (color);}/* * Return a new or already existing shaded color. color_val has the * form 0xrrggbb. */DwStyleShadedColor* a_Dw_style_shaded_color_new (gint color_val, GdkWindow *window){ DwStyleShadedColor *color; color = g_hash_table_lookup (shaded_colors_table, GINT_TO_POINTER (color_val)); if (color == NULL) { color = g_new (DwStyleShadedColor, 1); color->ref_count = 0; color->color_val = color_val; Dw_style_color_create (color_val, window, &color->color, &color->gc, 0); Dw_style_color_create (color_val ^ 0xffffff, window, &color->inverse_color, &color->inverse_gc, 0); Dw_style_color_create (color_val, window, &color->color_dark, &color->gc_dark, -1); Dw_style_color_create (color_val, window, &color->color_light, &color->gc_light, +1); g_hash_table_insert (shaded_colors_table, GINT_TO_POINTER (color_val), color); } return color;}/* * Remove a shaded color (called when ref_count == 0). */static void Dw_style_shaded_color_remove (DwStyleShadedColor *color){ g_hash_table_remove (shaded_colors_table, GINT_TO_POINTER (color->color_val)); gdk_gc_destroy (color->gc); gdk_gc_destroy (color->gc_dark); gdk_gc_destroy (color->gc_light); g_free (color);}/* * This function returns whether something may change its size, when * its style changes from style1 to style2. It is mainly for * optimizing style changes where only colors etc change (where FALSE * would be returned), in some cases it may return TRUE, although a * size change does not actually happen (e.g. when in a certain * context a particular attribute is ignored). */gboolean a_Dw_style_size_diffs (DwStyle *style1, DwStyle *style2){ /* todo: Should for CSS implemented properly. Currently, size * changes are not needed, so always FALSE is returned. See also * a_Dw_widget_set_style(). */ return FALSE;}/* ---------------------------------------------------------------------- * * Drawing functions * * ---------------------------------------------------------------------- *//* * Draw a part of a border. */static void Dw_style_draw_polygon (GdkDrawable *drawable, GdkGC *gc, gint32 x1, gint32 y1, gint32 x2, gint32 y2, gint32 width, gint32 w1, gint32 w2){ GdkPoint points[4]; if (width != 0) { if (width == 1) { if (x1 == x2) gdk_draw_line (drawable, gc, x1, y1, x2, y2 - 1); else gdk_draw_line (drawable, gc, x1, y1, x2 - 1, y2); } else if (width == -1) { if (x1 == x2) gdk_draw_line (drawable, gc, x1 - 1, y1, x2 - 1, y2 - 1); else gdk_draw_line (drawable, gc, x1, y1 - 1, x2 - 1, y2 - 1); } else { points[0].x = x1; points[0].y = y1; points[1].x = x2; points[1].y = y2; if (x1 == x2) { points[2].x = x1 + width; points[2].y = y2 + w2; points[3].x = x1 + width; points[3].y = y1 + w1; } else { points[2].x = x2 + w2; points[2].y = y1 + width; points[3].x = x1 + w1; points[3].y = y1 + width; } gdk_draw_polygon (drawable, gc, TRUE, points, 4); } }}/* * Draw the border of a region in window, according to style. Used by * Dw_widget_draw_box and Dw_widget_draw_widget_box. */#define LIMIT(v) if ((v) < -30000) v = -30000; \ if ((v) > 30000) v = 30000void p_Dw_style_draw_border (GdkWindow *window, GdkRectangle *area, gint32 vx, gint32 vy, gint32 x, gint32 y, gint32 width, gint32 height, DwStyle *style, gboolean inverse){ /* todo: a lot! */ GdkGC *dark_gc, *light_gc, *normal_gc; GdkGC *top_gc, *right_gc, *bottom_gc, *left_gc; gint32 xb1, yb1, xb2, yb2, xp1, yp1, xp2, yp2; if (style->border_style.top == DW_STYLE_BORDER_NONE) return; xb1 = x + style->margin.left - vx; yb1 = y + style->margin.top - vy; xb2 = xb1 + width - style->margin.left - style->margin.right; yb2 = yb1 + height - style->margin.top - style->margin.bottom; xp1 = xb1 + style->border_width.top; yp1 = yb1 + style->border_width.left; xp2 = xb2 + style->border_width.bottom; yp2 = yb2 + style->border_width.right; /* Make sure that we pass 16-bit values to Gdk functions. */ LIMIT (xb1); LIMIT (xb2); LIMIT (yb1); LIMIT (yb2); light_gc = inverse ? style->border_color.top->gc_dark : style->border_color.top->gc_light; dark_gc = inverse ? style->border_color.top->gc_light : style->border_color.top->gc_dark; normal_gc = inverse ? style->border_color.top->inverse_gc : style->border_color.top->gc; switch (style->border_style.top) { case DW_STYLE_BORDER_INSET: top_gc = left_gc = dark_gc; right_gc = bottom_gc = light_gc; break; case DW_STYLE_BORDER_OUTSET: top_gc = left_gc = light_gc; right_gc = bottom_gc = dark_gc; break; default: top_gc = right_gc = bottom_gc = left_gc = normal_gc; break; } Dw_style_draw_polygon (window, top_gc, xb1, yb1, xb2, yb1, style->border_width.top, style->border_width.left, - style->border_width.right); Dw_style_draw_polygon (window, right_gc, xb2, yb1, xb2, yb2, - style->border_width.right, style->border_width.top, - style->border_width.bottom); Dw_style_draw_polygon (window, bottom_gc, xb1, yb2, xb2, yb2, - style->border_width.bottom, style->border_width.left, - style->border_width.right); Dw_style_draw_polygon (window, left_gc, xb1, yb1, xb1, yb2, style->border_width.left, style->border_width.top, - style->border_width.bottom);}/* * Draw the background (content plus padding) of a region in window, * according to style. Used by Dw_widget_draw_box and * Dw_widget_draw_widget_box. */void p_Dw_style_draw_background (GdkWindow *window, GdkRectangle *area, gint32 vx, gint32 vy, gint32 x, gint32 y, gint32 width, gint32 height, DwStyle *style, gboolean inverse){ DwRectangle dw_area, bg_area, intersection; if (style->background_color) { dw_area.x = area->x + vx; dw_area.y = area->y + vy; dw_area.width = area->width; dw_area.height = area->height; bg_area.x = x + style->margin.left + style->border_width.left; bg_area.y = y + style->margin.top + style->border_width.top; bg_area.width = width - style->margin.left - style->border_width.left - style->margin.right - style->border_width.right; bg_area.height = height - style->margin.top - style->border_width.top - style->margin.bottom - style->border_width.bottom; if (p_Dw_rectangle_intersect (&dw_area, &bg_area, &intersection)) gdk_draw_rectangle (window, inverse ? style->background_color->inverse_gc : style->background_color->gc, TRUE, intersection.x - vx, intersection.y - vy, intersection.width, intersection.height); }}/* * Convert a number into a string, in a given style. Used for ordered lists. */void a_Dw_style_numtostr (gint num, gchar *buf, gint buflen, DwStyleListStyleType list_style_tyle){ int i3, i2, i1, i0; gboolean low = FALSE; switch(list_style_tyle){ case DW_STYLE_LIST_STYLE_TYPE_LOWER_ALPHA: low = TRUE; case DW_STYLE_LIST_STYLE_TYPE_UPPER_ALPHA: i0 = num - 1; i1 = i0/26; i2 = i1/26; i0 %= 26; i1 %= 26; if (i2 > 26) /* more than 26*26*26=17576 elements ? */ sprintf(buf, "****."); else if (i2) sprintf(buf, "%c%c%c.", 'A'+i2-1,'A'+i1-1,'A'+i0); else if (i1) sprintf(buf, "%c%c.", 'A'+i1-1,'A'+i0); else sprintf(buf, "%c.", 'A'+i0); if (low) g_strdown(buf); break; case DW_STYLE_LIST_STYLE_TYPE_LOWER_ROMAN: low = TRUE; case DW_STYLE_LIST_STYLE_TYPE_UPPER_ROMAN: i0 = num - 1; i1 = i0/10; i2 = i1/10; i3 = i2/10; i0 %= 10; i1 %= 10; i2 %= 10; if (i3 > 4) /* more than 4999 elements ? */ sprintf(buf, "****."); else if (i3) sprintf(buf, "%s%s%s%s.", roman_I3[i3-1], roman_I2[i2-1], roman_I1[i1-1], roman_I0[i0]); else if (i2) sprintf(buf, "%s%s%s.", roman_I2[i2-1], roman_I1[i1-1], roman_I0[i0]); else if (i1) sprintf(buf, "%s%s.", roman_I1[i1-1], roman_I0[i0]); else sprintf(buf, "%s.", roman_I0[i0]); if (low) g_strdown(buf); break; case DW_STYLE_LIST_STYLE_TYPE_DECIMAL: default: g_snprintf(buf, buflen, "%d.", num); break; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -