1 /***************************************************************************
2 * Copyright (c) 2024 Microsoft Corporation
3 *
4 * This program and the accompanying materials are made available under the
5 * terms of the MIT License which is available at
6 * https://opensource.org/licenses/MIT.
7 *
8 * SPDX-License-Identifier: MIT
9 **************************************************************************/
10
11
12 /**************************************************************************/
13 /**************************************************************************/
14 /** */
15 /** GUIX Component */
16 /** */
17 /** Canvas Management (Canvas) */
18 /** */
19 /**************************************************************************/
20
21 #define GX_SOURCE_CODE
22
23
24 /* Include necessary system files. */
25
26 #include "gx_api.h"
27 #include "gx_system.h"
28 #include "gx_utility.h"
29 #include "gx_display.h"
30 #include "gx_canvas.h"
31
32 /**************************************************************************/
33 /* */
34 /* FUNCTION RELEASE */
35 /* */
36 /* _gx_canvas_pixel_draw PORTABLE C */
37 /* 6.1 */
38 /* AUTHOR */
39 /* */
40 /* Kenneth Maxwell, Microsoft Corporation */
41 /* */
42 /* DESCRIPTION */
43 /* */
44 /* This function prepares to draw one pixel using current context */
45 /* */
46 /* INPUT */
47 /* */
48 /* position x,y coordinate to draw */
49 /* */
50 /* OUTPUT */
51 /* */
52 /* status Completion status */
53 /* */
54 /* CALLS */
55 /* */
56 /* _gx_utility_rectangle_point_detect Detect whether a pixel is */
57 /* inside rectangle */
58 /* [gx_display_driver_pixel_write] Actually write to canvas */
59 /* */
60 /* CALLED BY */
61 /* */
62 /* Application Code */
63 /* _gx_widget_border_draw */
64 /* */
65 /* RELEASE HISTORY */
66 /* */
67 /* DATE NAME DESCRIPTION */
68 /* */
69 /* 05-19-2020 Kenneth Maxwell Initial Version 6.0 */
70 /* 09-30-2020 Kenneth Maxwell Modified comment(s), */
71 /* resulting in version 6.1 */
72 /* */
73 /**************************************************************************/
_gx_canvas_pixel_draw(GX_POINT position)74 UINT _gx_canvas_pixel_draw(GX_POINT position)
75 {
76 GX_DRAW_CONTEXT *context;
77 GX_DISPLAY *display;
78 GX_VIEW *view;
79 GX_COLOR pixcolor;
80 GX_UBYTE brush_alpha;
81
82 /* pick up the current drawing context */
83 context = _gx_system_current_draw_context;
84
85 /* test to see if we can draw at this position */
86 if (!_gx_utility_rectangle_point_detect(&context -> gx_draw_context_dirty, position))
87 {
88 /* nothing to draw, return */
89 return GX_SUCCESS;
90 }
91
92 /* pick up current display driver */
93 display = context -> gx_draw_context_display;
94
95 brush_alpha = context -> gx_draw_context_brush.gx_brush_alpha;
96
97 /* pick up the pixel color */
98 pixcolor = context -> gx_draw_context_brush.gx_brush_line_color;
99
100 /* test to determine if any viewport of the caller overlaps this pixel.
101 For each view that overlaps the bounding rectangle, do some drawing.
102 */
103 view = context -> gx_draw_context_view_head;
104 #if defined(GX_BRUSH_ALPHA_SUPPORT)
105 if (brush_alpha == 0)
106 {
107 return GX_SUCCESS;
108 }
109 while (view)
110 {
111 if (_gx_utility_rectangle_point_detect(&view -> gx_view_rectangle, position))
112 {
113 if (brush_alpha == 0xff)
114 {
115 if (display -> gx_display_driver_pixel_write)
116 {
117 display -> gx_display_driver_pixel_write(context, position.gx_point_x, position.gx_point_y, pixcolor);
118 }
119 }
120 else
121 {
122 if (display -> gx_display_driver_pixel_blend)
123 {
124 display -> gx_display_driver_pixel_blend(context, position.gx_point_x, position.gx_point_y, pixcolor, brush_alpha);
125 }
126 }
127 break;
128 }
129 view = view->gx_view_next;
130 }
131 #else
132 while (view)
133 {
134 if (_gx_utility_rectangle_point_detect(&view -> gx_view_rectangle, position))
135 {
136 if (display -> gx_display_driver_pixel_write)
137 {
138 display -> gx_display_driver_pixel_write(context, position.gx_point_x, position.gx_point_y, pixcolor);
139 }
140 break;
141 }
142 view = view->gx_view_next;
143 }
144 #endif
145
146 /* Return successful completion. */
147 return(GX_SUCCESS);
148 }
149
150