📄 dw_style.c
字号:
} 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; }}/* * d is a factor the color is multiplied with before, this is needed * for shaded colors. */static void Dw_style_color_create (gint color_val, RGB *color, 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) -> ", d, 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->r = red; color->g = green; color->b = blue;}/* Return a new or already existing color. color_val has the form 0xrrggbb. */DwStyleColor* a_Dw_style_color_new (gint color_val, HWND wnd){ DwStyleColor *color; HDC hdc; hdc = GetClientDC (wnd); color = g_hash_table_lookup (colors_table, (gpointer) (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, &color->color, 0); color->pixel = RGB2Pixel (hdc, color->color.r, color->color.g, color->color.b); Dw_style_color_create (color_val ^ 0xffffff, &color->inverse_color, 0); color->inverse_pixel = RGB2Pixel (hdc, color->inverse_color.r, color->inverse_color.g, color->inverse_color.b); g_hash_table_insert (colors_table, (gpointer) color_val, color); g_hash_table_insert (colors_table, (gpointer) color_val, color); } ReleaseDC (hdc); 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));#if 0 gdk_gc_destroy (color->gc); gdk_gc_destroy (color->inverse_gc);#endif 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, HWND wnd){ DwStyleShadedColor *color; HDC hdc; hdc = GetClientDC (wnd); color = g_hash_table_lookup (shaded_colors_table, (gpointer) (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, &color->color, 0); color->pixel = RGB2Pixel (hdc, color->color.r, color->color.g, color->color.b); Dw_style_color_create (color_val ^ 0xffffff, &color->inverse_color, 0); color->inverse_pixel = RGB2Pixel (hdc, color->inverse_color.r, color->inverse_color.g, color->inverse_color.b); Dw_style_color_create (color_val, &color->color_dark, -1); color->pixel_dark = RGB2Pixel (hdc, color->color_dark.r, color->color_dark.g, color->color_dark.b); Dw_style_color_create (color_val, &color->color_light, +1); color->pixel_light = RGB2Pixel (hdc, color->color_light.r, color->color_light.g, color->color_light.b); g_hash_table_insert (shaded_colors_table, (gpointer) (color_val), color); } ReleaseDC (hdc); 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, (gpointer) (color->color_val));#if 0 gdk_gc_destroy (color->gc); gdk_gc_destroy (color->gc_dark); gdk_gc_destroy (color->gc_light);#endif 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 (HDC hdc, const RGB* color, gint32 x1, gint32 y1, gint32 x2, gint32 y2, gint32 width, gint32 w1, gint32 w2){ POINT points[4]; SetPenColor (hdc, RGB2Pixel (hdc, color->r, color->g, color->b)); SetBrushColor (hdc, RGB2Pixel (hdc, color->r, color->g, color->b)); if (width != 0) { if (width == 1) { if (x1 == x2) { MoveTo (hdc, x1, y1); LineTo (hdc, x2, y2 - 1); } else { MoveTo (hdc, x1, y1); LineTo (hdc, x2 - 1, y2); } } else if (width == -1) { if (x1 == x2) { MoveTo (hdc, x1 - 1, y1); LineTo (hdc, x2 - 1, y2 - 1); } else { MoveTo (hdc, x1, y1 - 1); LineTo (hdc, 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; } FillPolygon (hdc, 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 (HDC hdc, DwRectangle *area, gint32 vx, gint32 vy, gint32 x, gint32 y, gint32 width, gint32 height, DwStyle *style, gboolean inverse){ /* todo: a lot! */ RGB *dark_color, *light_color, *normal_color; RGB *top_color, *right_color, *bottom_color, *left_color; 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_color = inverse ? &style->border_color.top->color_dark : &style->border_color.top->color_light; dark_color = inverse ? &style->border_color.top->color_light : &style->border_color.top->color_dark; normal_color = inverse ? &style->border_color.top->inverse_color : &style->border_color.top->color; switch (style->border_style.top) { case DW_STYLE_BORDER_INSET: top_color = left_color = dark_color; right_color = bottom_color = light_color; break; case DW_STYLE_BORDER_OUTSET: top_color = left_color = light_color; right_color = bottom_color = dark_color; break; default: top_color = right_color = bottom_color = left_color = normal_color; break; } Dw_style_draw_polygon (hdc, top_color, xb1, yb1, xb2, yb1, style->border_width.top, style->border_width.left, - style->border_width.right); Dw_style_draw_polygon (hdc, right_color, xb2, yb1, xb2, yb2, - style->border_width.right, style->border_width.top, - style->border_width.bottom); Dw_style_draw_polygon (hdc, bottom_color, xb1, yb2, xb2, yb2, - style->border_width.bottom, style->border_width.left, - style->border_width.right); Dw_style_draw_polygon (hdc, left_color, 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 (HDC hdc, DwRectangle *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)) { gal_pixel pixel = inverse ? style->background_color->inverse_pixel : style->background_color->pixel; SetBrushColor (hdc, pixel); FillBox (hdc, 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 + -