GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: gx_utility_gradient_create.c Lines: 99 99 100.0 %
Date: 2026-03-06 19:21:09 Branches: 56 56 100.0 %

Line Branch Exec Source
1
/***************************************************************************
2
 * Copyright (c) 2024 Microsoft Corporation
3
 * Copyright (c) 2026-present Eclipse ThreadX contributors
4
 *
5
 * This program and the accompanying materials are made available under the
6
 * terms of the MIT License which is available at
7
 * https://opensource.org/licenses/MIT.
8
 *
9
 * SPDX-License-Identifier: MIT
10
 **************************************************************************/
11
12
13
/**************************************************************************/
14
/**************************************************************************/
15
/**                                                                       */
16
/** GUIX Component                                                        */
17
/**                                                                       */
18
/**   Utility (Utility)                                                   */
19
/**                                                                       */
20
/**************************************************************************/
21
22
#define GX_SOURCE_CODE
23
24
/* Include necessary system files.  */
25
26
#include "gx_api.h"
27
#include "gx_canvas.h"
28
#include "gx_system.h"
29
#include "gx_utility.h"
30
31
/**************************************************************************/
32
/*                                                                        */
33
/*  FUNCTION                                               RELEASE        */
34
/*                                                                        */
35
/*    _gx_utility_gradient_find                           PORTABLE C      */
36
/*                                                           6.1          */
37
/*  AUTHOR                                                                */
38
/*                                                                        */
39
/*    Kenneth Maxwell, Microsoft Corporation                              */
40
/*                                                                        */
41
/*  DESCRIPTION                                                           */
42
/*                                                                        */
43
/*    Helper function for _gx_utility_gradient_create. This function      */
44
/*    searches the gradient list to find a match.                         */
45
/*                                                                        */
46
/*  INPUT                                                                 */
47
/*                                                                        */
48
/*    gradient                                   GX_GRADIENT pointer      */
49
/*                                                                        */
50
/*  OUTPUT                                                                */
51
/*                                                                        */
52
/*    Completion Status                                                   */
53
/*                                                                        */
54
/*  CALLS                                                                 */
55
/*                                                                        */
56
/*    None                                                                */
57
/*                                                                        */
58
/*  CALLED BY                                                             */
59
/*                                                                        */
60
/*    _gx_utility_gradient_create                                         */
61
/*                                                                        */
62
/**************************************************************************/
63
165
static GX_BOOL _gx_utility_gradient_find(GX_GRADIENT *gradient)
64
{
65
165
GX_GRADIENT *search = _gx_system_gradient_list;
66
67
    /* look for a matching gradient */
68
251
    while (search)
69
    {
70
137
        if (search -> gx_gradient_pixelmap.gx_pixelmap_data &&
71
136
            search -> gx_gradient_type == gradient -> gx_gradient_type &&
72
127
            search -> gx_gradient_alpha_start == gradient -> gx_gradient_alpha_start &&
73
125
            search -> gx_gradient_alpha_end == gradient -> gx_gradient_alpha_end &&
74
123
            search -> gx_gradient_pixelmap.gx_pixelmap_width == gradient -> gx_gradient_pixelmap.gx_pixelmap_width &&
75
52
            search -> gx_gradient_pixelmap.gx_pixelmap_height == gradient -> gx_gradient_pixelmap.gx_pixelmap_height)
76
        {
77
            /* found a match, just copy the pixelmap */
78
51
            gradient -> gx_gradient_pixelmap = search -> gx_gradient_pixelmap;
79
51
            return GX_TRUE;
80
        }
81
86
        search = search -> gx_gradient_next;
82
    }
83
84
    /* did not find a match, need to create a new gradient pixelmap */
85
114
    return GX_FALSE;
86
}
87
88
89
/**************************************************************************/
90
/*                                                                        */
91
/*  FUNCTION                                               RELEASE        */
92
/*                                                                        */
93
/*    _gx_utility_horizontal_alpha_gradient_create        PORTABLE C      */
94
/*                                                           6.1          */
95
/*  AUTHOR                                                                */
96
/*                                                                        */
97
/*    Kenneth Maxwell, Microsoft Corporation                              */
98
/*                                                                        */
99
/*  DESCRIPTION                                                           */
100
/*                                                                        */
101
/*    This function creates a horizontal alpha gradient pixelmap.         */
102
/*                                                                        */
103
/*  INPUT                                                                 */
104
/*                                                                        */
105
/*    gradient                                   GX_GRADIENT structure    */
106
/*                                                                        */
107
/*  OUTPUT                                                                */
108
/*                                                                        */
109
/*    Completion Status                                                   */
110
/*                                                                        */
111
/*  CALLS                                                                 */
112
/*                                                                        */
113
/*    None                                                                */
114
/*                                                                        */
115
/*  CALLED BY                                                             */
116
/*                                                                        */
117
/*    _gx_utility_gradient_create                                         */
118
/*                                                                        */
119
/**************************************************************************/
120
75
static UINT _gx_utility_horizontal_alpha_gradient_create(GX_GRADIENT *gradient)
121
{
122
INT       column;
123
INT       row;
124
INT       height;
125
INT       width;
126
GX_UBYTE  dataval;
127
GX_UBYTE *data;
128
75
GX_UBYTE *data_start = (GX_UBYTE *)gradient -> gx_gradient_pixelmap.gx_pixelmap_data;
129
130
75
    height = gradient -> gx_gradient_pixelmap.gx_pixelmap_height;
131
75
    width = gradient -> gx_gradient_pixelmap.gx_pixelmap_width;
132
133
75
    if (gradient -> gx_gradient_type & GX_GRADIENT_TYPE_MIRROR)
134
    {
135
8222
        for (column = 0; column < width / 2; column++)
136
        {
137
8148
            dataval = (GX_UBYTE)(GX_FIXED_VAL_TO_INT(gradient -> gx_gradient_alpha_current));
138
8148
            data = data_start;
139
140
32629
            for (row = 0; row < height; row++)
141
            {
142
24481
                *data = dataval;
143
24481
                data += width;
144
            }
145
8148
            data_start++;
146
8148
            gradient -> gx_gradient_alpha_current += gradient -> gx_gradient_alpha_step;
147
        }
148
8225
        for (; column < width; column++)
149
        {
150
8151
            dataval = (GX_UBYTE)(GX_FIXED_VAL_TO_INT(gradient -> gx_gradient_alpha_current));
151
8151
            data = data_start;
152
153
32664
            for (row = 0; row < height; row++)
154
            {
155
24513
                *data = dataval;
156
24513
                data += width;
157
            }
158
8151
            data_start++;
159
8151
            gradient -> gx_gradient_alpha_current -= gradient -> gx_gradient_alpha_step;
160
        }
161
    }
162
    else
163
    {
164
101
        for (column = 0; column < width; column++)
165
        {
166
100
            dataval = (GX_UBYTE)(GX_FIXED_VAL_TO_INT(gradient -> gx_gradient_alpha_current));
167
100
            data = data_start;
168
169
400
            for (row = 0; row < height; row++)
170
            {
171
300
                *data = dataval;
172
300
                data += width;
173
            }
174
100
            data_start++;
175
100
            gradient -> gx_gradient_alpha_current += gradient -> gx_gradient_alpha_step;
176
        }
177
    }
178
75
    return GX_SUCCESS;
179
}
180
181
/**************************************************************************/
182
/*                                                                        */
183
/*  FUNCTION                                               RELEASE        */
184
/*                                                                        */
185
/*    _gx_utility_vertical_alpha_gradient_create          PORTABLE C      */
186
/*                                                           6.1          */
187
/*  AUTHOR                                                                */
188
/*                                                                        */
189
/*    Kenneth Maxwell, Microsoft Corporation                              */
190
/*                                                                        */
191
/*  DESCRIPTION                                                           */
192
/*                                                                        */
193
/*    This function creates a vertical alpha gradient pixelmap.           */
194
/*                                                                        */
195
/*  INPUT                                                                 */
196
/*                                                                        */
197
/*    gradient                                   GX_GRADIENT structure    */
198
/*                                                                        */
199
/*  OUTPUT                                                                */
200
/*                                                                        */
201
/*    Completion status                                                   */
202
/*                                                                        */
203
/*  CALLS                                                                 */
204
/*                                                                        */
205
/*    None                                                                */
206
/*                                                                        */
207
/*  CALLED BY                                                             */
208
/*                                                                        */
209
/*    _gx_utility_gradient_create                                         */
210
/*                                                                        */
211
/**************************************************************************/
212
33
static UINT _gx_utility_vertical_alpha_gradient_create(GX_GRADIENT *gradient)
213
{
214
INT       row;
215
INT       height;
216
INT       width;
217
33
GX_UBYTE *data = (GX_UBYTE *)gradient -> gx_gradient_pixelmap.gx_pixelmap_data;
218
219
33
    height = gradient -> gx_gradient_pixelmap.gx_pixelmap_height;
220
33
    width = gradient -> gx_gradient_pixelmap.gx_pixelmap_width;
221
222
33
    if (gradient -> gx_gradient_type & GX_GRADIENT_TYPE_MIRROR)
223
    {
224
3772
        for (row = 0; row < height / 2; row++)
225
        {
226
3740
            memset(data, GX_FIXED_VAL_TO_INT(gradient -> gx_gradient_alpha_current), (size_t)width);
227
3740
            data += width;
228
3740
            gradient -> gx_gradient_alpha_current += gradient -> gx_gradient_alpha_step;
229
        }
230
3775
        for (; row < height; row++)
231
        {
232
3743
            memset(data, GX_FIXED_VAL_TO_INT(gradient -> gx_gradient_alpha_current), (size_t)width);
233
3743
            data += width;
234
3743
            gradient -> gx_gradient_alpha_current -= gradient -> gx_gradient_alpha_step;
235
        }
236
    }
237
    else
238
    {
239
201
        for (row = 0; row < height; row++)
240
        {
241
200
            memset(data, GX_FIXED_VAL_TO_INT(gradient -> gx_gradient_alpha_current), (size_t)width);
242
200
            data += width;
243
200
            gradient -> gx_gradient_alpha_current += gradient -> gx_gradient_alpha_step;
244
        }
245
    }
246
247
33
    return GX_SUCCESS;
248
}
249
250
251
252
253
/**************************************************************************/
254
/*                                                                        */
255
/*  FUNCTION                                               RELEASE        */
256
/*                                                                        */
257
/*    _gx_utility_gradient_create                         PORTABLE C      */
258
/*                                                           6.1.3        */
259
/*  AUTHOR                                                                */
260
/*                                                                        */
261
/*    Kenneth Maxwell, Microsoft Corporation                              */
262
/*                                                                        */
263
/*  DESCRIPTION                                                           */
264
/*                                                                        */
265
/*    This function creates a gradient pixelmap.                          */
266
/*                                                                        */
267
/*  INPUT                                                                 */
268
/*                                                                        */
269
/*    gradient                              Pointer to GX_GRADIENT        */
270
/*    width                                 Requested width               */
271
/*    height                                Requested height              */
272
/*    type                                  Gradient type                 */
273
/*    alpha_start                           Starting alpha value          */
274
/*    alpha_end                             Ending alpha value            */
275
/*                                                                        */
276
/*  OUTPUT                                                                */
277
/*                                                                        */
278
/*    None                                                                */
279
/*                                                                        */
280
/*  CALLS                                                                 */
281
/*                                                                        */
282
/*    _gx_system_gradient_find                                            */
283
/*    _gx_utility_alphamap_create                                         */
284
/*                                                                        */
285
/*  CALLED BY                                                             */
286
/*                                                                        */
287
/*    _gx_text_scroll_wheel_gradient_create                               */
288
/*                                                                        */
289
/**************************************************************************/
290
172
UINT _gx_utility_gradient_create(GX_GRADIENT *gradient, GX_VALUE width, GX_VALUE height,
291
                                 UCHAR type, GX_UBYTE alpha_start, GX_UBYTE alpha_end)
292
{
293
172
UINT status = GX_FAILURE;
294
295
    /* width and height must be >= 2 pixels */
296
297

172
    if (width < 2 || height < 2)
298
    {
299
6
        return GX_INVALID_SIZE;
300
    }
301
302
    /* only alpha gradient supported currently */
303
166
    if (!(type & GX_GRADIENT_TYPE_ALPHA))
304
    {
305
1
        return GX_NOT_SUPPORTED;
306
    }
307
308
165
    memset(&gradient -> gx_gradient_pixelmap, 0, sizeof(GX_PIXELMAP));
309
165
    gradient -> gx_gradient_pixelmap.gx_pixelmap_width = width;
310
165
    gradient -> gx_gradient_pixelmap.gx_pixelmap_height = height;
311
165
    gradient -> gx_gradient_type = type;
312
165
    gradient -> gx_gradient_alpha_start = alpha_start;
313
165
    gradient -> gx_gradient_alpha_end = alpha_end;
314
165
    gradient -> gx_gradient_previous = GX_NULL;
315
165
    gradient -> gx_gradient_next = GX_NULL;
316
317
165
    if (_gx_utility_gradient_find(gradient))
318
    {
319
51
        status = GX_SUCCESS;
320
    }
321
    else
322
    {
323
114
        gradient -> gx_gradient_alpha_current = GX_FIXED_VAL_MAKE(gradient -> gx_gradient_alpha_start);
324
114
        gradient -> gx_gradient_alpha_step = GX_FIXED_VAL_MAKE(gradient -> gx_gradient_alpha_end);
325
114
        gradient -> gx_gradient_alpha_step -= GX_FIXED_VAL_MAKE(gradient -> gx_gradient_alpha_start);
326
327
114
        status = _gx_utility_alphamap_create(width, height, &gradient -> gx_gradient_pixelmap);
328
329
114
        if (status == GX_SUCCESS)
330
        {
331
108
            if (gradient -> gx_gradient_type & GX_GRADIENT_TYPE_VERTICAL)
332
            {
333
33
                if (gradient -> gx_gradient_type & GX_GRADIENT_TYPE_MIRROR)
334
                {
335
32
                    gradient -> gx_gradient_alpha_step /= (height / 2);
336
                }
337
                else
338
                {
339
1
                    gradient -> gx_gradient_alpha_step /= height;
340
                }
341
33
                status = _gx_utility_vertical_alpha_gradient_create(gradient);
342
            }
343
            else
344
            {
345
75
                if (gradient -> gx_gradient_type & GX_GRADIENT_TYPE_MIRROR)
346
                {
347
74
                    gradient -> gx_gradient_alpha_step /= (width / 2);
348
                }
349
                else
350
                {
351
1
                    gradient -> gx_gradient_alpha_step /= width;
352
                }
353
75
                status = _gx_utility_horizontal_alpha_gradient_create(gradient);
354
            }
355
        }
356
    }
357
358
165
    if (status == GX_SUCCESS)
359
    {
360
        /* lock access to GUIX */
361
159
        GX_ENTER_CRITICAL
362
363
        /* insert gradient into global gradient list */
364
159
        gradient -> gx_gradient_next = _gx_system_gradient_list;
365
366
159
        if (_gx_system_gradient_list)
367
        {
368
103
            _gx_system_gradient_list -> gx_gradient_previous = gradient;
369
        }
370
159
        _gx_system_gradient_list = gradient;
371
372
159
        GX_EXIT_CRITICAL
373
    }
374
375
165
    return status;
376
}
377