note description: "[ Drawer who can draw grayscale images base on original images. ]" legal: "See notice at end of class." status: "See notice at end of class." date: "$Date$" revision: "$Revision$" class WEL_GDIP_GRAYSCALE_IMAGE_DRAWER feature -- Command draw_grayscale_bitmap (a_image: WEL_GDIP_BITMAP; a_dest_dc: WEL_DC; a_dest_x, a_dest_y: INTEGER) -- Draw grayscale version of `a_image' on `a_dest_dc' at `a_dest_x', `a_dest_y'. require a_image_not_void: a_image /= Void a_image_exists: a_image.exists a_dest_dc_not_void: a_dest_dc /= Void a_dest_dc_exists: a_dest_dc.exists local l_graphics: WEL_GDIP_GRAPHICS l_image_attributes: WEL_GDIP_IMAGE_ATTRIBUTES l_src_rect, l_dest_rect: WEL_RECT l_width, l_height: INTEGER do create l_image_attributes.make l_image_attributes.clear_color_key l_image_attributes.set_color_matrix (disabled_color_matrix) l_width := a_image.width l_height := a_image.height create l_src_rect.make (0, 0, l_width, l_height) create l_dest_rect.make (a_dest_x, a_dest_y, a_dest_x + l_width, a_dest_y + l_height) create l_graphics.make_from_dc (a_dest_dc) l_graphics.draw_image_with_src_rect_dest_rect_unit_attributes (a_image, l_dest_rect, l_src_rect, {WEL_GDIP_UNIT}.unitpixel, l_image_attributes) l_graphics.destroy_item l_dest_rect.dispose l_src_rect.dispose l_image_attributes.destroy_item end draw_grayscale_bitmap_or_icon_with_memory_buffer (a_bitmap: WEL_BITMAP; a_icon: WEL_ICON; a_control_dc: WEL_DC; a_dest_x, a_dest_y: INTEGER; a_background_color: WEL_COLOR_REF; a_pixmap_has_mask: BOOLEAN) -- This feature will use one of `draw_grayscale_icon_with_memory_buffer' or `draw_grayscale_bitmap_with_memory_buffer' automatically. require a_bitmap_not_void: a_bitmap /= Void a_bitmap_exists: a_bitmap.exists a_icon_not_void: a_icon /= Void a_icon_exists: a_icon.exists a_control_dc_not_void: a_control_dc /= Void a_control_dc_exists: a_control_dc.exists a_background_color_not_void: a_background_color /= Void local l_log_bitmap: WEL_LOG_BITMAP l_gdip_bitmap: WEL_GDIP_BITMAP do l_log_bitmap := a_bitmap.log_bitmap if not a_pixmap_has_mask and then l_log_bitmap.bits_pixel = 32 and then a_bitmap.ppv_bits /= default_pointer then create l_gdip_bitmap.make_from_bitmap_with_alpha (a_bitmap) draw_grayscale_bitmap_with_memory_buffer (l_gdip_bitmap, a_control_dc, a_dest_x, a_dest_y, a_background_color) l_gdip_bitmap.dispose else draw_grayscale_icon_with_memory_buffer (a_icon, a_control_dc, a_dest_x, a_dest_y, a_background_color) end l_log_bitmap.dispose end draw_grayscale_icon_with_memory_buffer (a_orignal_icon: WEL_ICON; a_control_dc: WEL_DC; a_dest_x, a_dest_y: INTEGER; a_background_color: WEL_COLOR_REF) -- Draw grayscale version of `a_orignal_icon' on `a_control_dc' require a_orignal_icon_not_void: a_orignal_icon /= Void a_orignal_icon_exists: a_orignal_icon.exists a_control_dc_not_void: a_control_dc /= Void a_control_dc_exists: a_control_dc.exists a_background_color_not_void: a_background_color /= Void local l_gdip_bitmap: WEL_GDIP_BITMAP do create l_gdip_bitmap.make_from_icon (a_orignal_icon) draw_grayscale_bitmap_with_memory_buffer (l_gdip_bitmap, a_control_dc, a_dest_x, a_dest_y, a_background_color) l_gdip_bitmap.dispose end draw_grayscale_bitmap_with_memory_buffer (a_gdip_bitmap: WEL_GDIP_BITMAP; a_control_dc: WEL_DC; a_dest_x, a_dest_y: INTEGER; a_background_color: WEL_COLOR_REF) -- Draw grayscale version of `a_orignal_icon' on `a_control_dc' -- We must draw on a buffer dc first, otherwise in Windows Remote Desktop (at least Windows Vista), the generated grayscale icon will distorted. require a_gdip_bitmap_not_void: a_gdip_bitmap /= Void a_gdip_bitmap_exists: a_gdip_bitmap.exists a_control_dc_not_void: a_control_dc /= Void a_control_dc_exists: a_control_dc.exists a_background_color_not_void: a_background_color /= Void local l_buffered_dc: WEL_DC l_wel_bitmap: WEL_BITMAP l_brush: WEL_BRUSH l_width, l_height: INTEGER do l_width := a_gdip_bitmap.width l_height := a_gdip_bitmap.height create {WEL_MEMORY_DC} l_buffered_dc.make_by_dc (a_control_dc) create l_wel_bitmap.make_compatible (a_control_dc, l_width, l_height) l_buffered_dc.select_bitmap (l_wel_bitmap) l_buffered_dc.set_background_color (a_background_color) -- Fill background create l_brush.make_solid (a_background_color) l_buffered_dc.fill_rect (create {WEL_RECT}.make (0, 0, l_width, l_height), l_brush) l_brush.delete -- Draw grayscale icon on memory buffer dc draw_grayscale_bitmap (a_gdip_bitmap, l_buffered_dc, 0, 0) l_wel_bitmap.dispose -- Finally, we copy buffer icon to target control dc. a_control_dc.bit_blt (a_dest_x, a_dest_y, l_width, l_height, l_buffered_dc, 0, 0, {WEL_RASTER_OPERATIONS_CONSTANTS}.srccopy) end feature {NONE} -- Implementation disabled_color_matrix: WEL_COLOR_MATRIX -- Disable color matrix. do Result := mulitply_color_matrix (disabled_color_matrix_2, disabled_color_matrix_1) ensure not_void: Result /= Void end disabled_color_matrix_1: WEL_COLOR_MATRIX -- Disabled color matrix used by GDI+ DrawImage. -- See MSDN "A Twist in Color Space" do create Result.make Result.set_m_row ({ARRAY [REAL_32]} <<0.2125, 0.2125, 0.2125, 0.0, 0.0>>, 0) -- Grey scale R channel Result.set_m_row ({ARRAY [REAL_32]} <<0.2577, 0.2577, 0.2577, 0.0, 0.0>>, 1) -- Grey scale G channel Result.set_m_row ({ARRAY [REAL_32]} <<0.0361, 0.0361, 0.0361, 0.0, 0.0>>, 2) -- Grey scale B channel Result.set_m_row ({ARRAY [REAL_32]} <<0.0, 0.0, 0.0, 1.0, 0.0>>, 3) -- Opacity Result.set_m_row ({ARRAY [REAL_32]} <<0.38, 0.38, 0.38, 0.0, 1.0>>, 4) -- Brightness ensure not_void: Result /= Void end disabled_color_matrix_2: WEL_COLOR_MATRIX -- Disabled color matrix used by GDI+ DrawImage. -- See MSDN "A Twist in Color Space" do create Result.make Result.set_m_row ({ARRAY [REAL_32]} <<1, 0, 0, 0, 0>>, 0) -- Grey scale R channel Result.set_m_row ({ARRAY [REAL_32]} <<0, 1, 0, 0, 0>>, 1) -- Grey scale G channel Result.set_m_row ({ARRAY [REAL_32]} <<0, 0, 1, 0, 0>>, 2) -- Grey scale B channel Result.set_m_row ({ARRAY [REAL_32]} <<0, 0, 0, 0.7, 0>>, 3) -- Opacity Result.set_m_row ({ARRAY [REAL_32]} <<0, 0, 0, 0, 0>>, 4) -- Brightness ensure not_void: Result /= Void end mulitply_color_matrix (a_matrix_1, a_matrix_2: WEL_COLOR_MATRIX): WEL_COLOR_MATRIX -- Mulitply `a_matrix_1' and `a_matrix_2' require not_void: a_matrix_1 /= Void not_void: a_matrix_2 /= Void local l_i, l_j, l_k: INTEGER l_temp_array: ARRAY [REAL] l_sum: REAL do create Result.make create l_temp_array.make_filled (0.0, 0, 4) from l_j := 0 until l_j > 4 loop from l_k := 0 until l_k > 4 loop l_temp_array [l_k] := a_matrix_1.m (l_k, l_j) l_k := l_k + 1 end from l_i := 0 until l_i > 4 loop l_sum := 0 from l_k := 0 until l_k > 4 loop l_sum := l_sum + a_matrix_2.m (l_i, l_k) * l_temp_array [l_k] l_k := l_k + 1 end Result.m (l_i, l_j) := l_sum l_i := l_i + 1 end l_j := l_j + 1 end end note copyright: "Copyright (c) 1984-2017, Eiffel Software and others" license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" source: "[ Eiffel Software 5949 Hollister Ave., Goleta, CA 93117 USA Telephone 805-685-1006, Fax 805-685-6869 Website http://www.eiffel.com Customer support http://support.eiffel.com ]" end