GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: gx_utility_gradient_create.c Lines: 99 99 100.0 %
Date: 2024-12-05 08:52:37 Branches: 56 56 100.0 %

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

172
    if (width < 2 || height < 2)
332
    {
333
6
        return GX_INVALID_SIZE;
334
    }
335
336
    /* only alpha gradient supported currently */
337
166
    if (!(type & GX_GRADIENT_TYPE_ALPHA))
338
    {
339
1
        return GX_NOT_SUPPORTED;
340
    }
341
342
165
    memset(&gradient -> gx_gradient_pixelmap, 0, sizeof(GX_PIXELMAP));
343
165
    gradient -> gx_gradient_pixelmap.gx_pixelmap_width = width;
344
165
    gradient -> gx_gradient_pixelmap.gx_pixelmap_height = height;
345
165
    gradient -> gx_gradient_type = type;
346
165
    gradient -> gx_gradient_alpha_start = alpha_start;
347
165
    gradient -> gx_gradient_alpha_end = alpha_end;
348
165
    gradient -> gx_gradient_previous = GX_NULL;
349
165
    gradient -> gx_gradient_next = GX_NULL;
350
351
165
    if (_gx_utility_gradient_find(gradient))
352
    {
353
51
        status = GX_SUCCESS;
354
    }
355
    else
356
    {
357
114
        gradient -> gx_gradient_alpha_current = GX_FIXED_VAL_MAKE(gradient -> gx_gradient_alpha_start);
358
114
        gradient -> gx_gradient_alpha_step = GX_FIXED_VAL_MAKE(gradient -> gx_gradient_alpha_end);
359
114
        gradient -> gx_gradient_alpha_step -= GX_FIXED_VAL_MAKE(gradient -> gx_gradient_alpha_start);
360
361
114
        status = _gx_utility_alphamap_create(width, height, &gradient -> gx_gradient_pixelmap);
362
363
114
        if (status == GX_SUCCESS)
364
        {
365
108
            if (gradient -> gx_gradient_type & GX_GRADIENT_TYPE_VERTICAL)
366
            {
367
33
                if (gradient -> gx_gradient_type & GX_GRADIENT_TYPE_MIRROR)
368
                {
369
32
                    gradient -> gx_gradient_alpha_step /= (height / 2);
370
                }
371
                else
372
                {
373
1
                    gradient -> gx_gradient_alpha_step /= height;
374
                }
375
33
                status = _gx_utility_vertical_alpha_gradient_create(gradient);
376
            }
377
            else
378
            {
379
75
                if (gradient -> gx_gradient_type & GX_GRADIENT_TYPE_MIRROR)
380
                {
381
74
                    gradient -> gx_gradient_alpha_step /= (width / 2);
382
                }
383
                else
384
                {
385
1
                    gradient -> gx_gradient_alpha_step /= width;
386
                }
387
75
                status = _gx_utility_horizontal_alpha_gradient_create(gradient);
388
            }
389
        }
390
    }
391
392
165
    if (status == GX_SUCCESS)
393
    {
394
        /* lock access to GUIX */
395
159
        GX_ENTER_CRITICAL
396
397
        /* insert gradient into global gradient list */
398
159
        gradient -> gx_gradient_next = _gx_system_gradient_list;
399
400
159
        if (_gx_system_gradient_list)
401
        {
402
103
            _gx_system_gradient_list -> gx_gradient_previous = gradient;
403
        }
404
159
        _gx_system_gradient_list = gradient;
405
406
159
        GX_EXIT_CRITICAL
407
    }
408
409
165
    return status;
410
}
411