µGFX  2.9
version 2.9
gmisc.h
Go to the documentation of this file.
1 /*
2  * This file is subject to the terms of the GFX License. If a copy of
3  * the license was not distributed with this file, you can obtain one at:
4  *
5  * http://ugfx.io/license.html
6  */
7 
8 /**
9  * @file src/gmisc/gmisc.h
10  * @brief GMISC - Miscellaneous Routines header file.
11  *
12  * @addtogroup GMISC
13  *
14  * @brief Module which contains different features such as array conversions
15  *
16  * @{
17  */
18 
19 #ifndef _GMISC_H
20 #define _GMISC_H
21 
22 #include "../../gfx.h"
23 
24 /*===========================================================================*/
25 /* Type definitions */
26 /*===========================================================================*/
27 
28 // Forward definition
29 typedef struct gPoint gPoint;
30 
31 /**
32  * @brief Sample data formats
33  * @note These are defined regardless of whether you use the GMISC module
34  * or not as they are used in lots of places.
35  */
36 typedef enum ArrayDataFormat_e {
37  ARRAY_DATA_UNKNOWN = 0,
38  ARRAY_DATA_4BITUNSIGNED = 4, ARRAY_DATA_4BITSIGNED = 5,
39  ARRAY_DATA_8BITUNSIGNED = 8, ARRAY_DATA_8BITSIGNED = 9,
40  ARRAY_DATA_10BITUNSIGNED = 10, ARRAY_DATA_10BITSIGNED = 11,
41  ARRAY_DATA_12BITUNSIGNED = 12, ARRAY_DATA_12BITSIGNED = 13,
42  ARRAY_DATA_14BITUNSIGNED = 14, ARRAY_DATA_14BITSIGNED = 15,
43  ARRAY_DATA_16BITUNSIGNED = 16, ARRAY_DATA_16BITSIGNED = 17,
45 
46 /**
47  * @brief Is the sample data format a "signed" data format?
48  */
49 #define gfxSampleFormatIsSigned(fmt) ((fmt) & 1)
50 
51 /**
52  * @brief How many bits are in the sample data format
53  */
54 #define gfxSampleFormatBits(fmt) ((fmt) & ~1)
55 
56 /**
57  * @brief The type for a fixed point type.
58  * @details The top 16 bits are the integer component, the bottom 16 bits are the real component.
59  */
60 typedef gI32 fixed;
61 
62 /**
63  * @brief Macros to convert to and from a fixed point.
64  * @{
65  */
66 #define FIXED(x) ((fixed)(x)<<16) /* @< integer to fixed */
67 #define NONFIXED(x) ((x)>>16) /* @< fixed to integer */
68 #define FIXED0_5 32768 /* @< 0.5 as a fixed (used for rounding) */
69 #define FP2FIXED(x) ((fixed)((x)*65536.0)) /* @< floating point to fixed */
70 #define FIXED2FP(x) ((double)(x)/65536.0) /* @< fixed to floating point */
71 #define FIXEDMUL(a,b) ((fixed)((((long long)(a))*(b))>>16)) /* @< fixed,fixed multiplication */
72 #define FIXEDMULINT(a,b) ((a)*(b)) /* @< integer,fixed multiplication */
73 /** @} */
74 
75 /**
76  * @brief The famous number pi
77  */
78 #ifndef GFX_PI
79  #define GFX_PI 3.1415926535897932384626433832795028841971693993751
80 #endif
81 
82 /**
83  * @brief pi as a fixed point
84  */
85 #define FIXED_PI FP2FIXED(GFX_PI)
86 
87 /*===========================================================================*/
88 /* External declarations. */
89 /*===========================================================================*/
90 
91 #if GFX_USE_GMISC || defined(__DOXYGEN__)
92 
93 #if GMISC_NEED_ARRAYOPS || defined(__DOXYGEN__)
94  /**
95  * @brief Convert from one array format to another array format.
96  * @pre Requires GFX_USE_GMISC and GMISC_NEED_ARRAYOPS
97  *
98  * @param[in] srcfmt The format of the source array
99  * @param[in] src The source array
100  * @param[in] dstfmt The format of the destination array
101  * @param[in] dst The dstination array
102  * @param[in] cnt The number of array elements to convert
103  *
104  * @note Assumes the destination buffer is large enough for the resultant data.
105  * @note This routine is optimised to perform as fast as possible.
106  * @note No type checking is performed on the source format. It is assumed to
107  * have only valid values eg. ARRAY_DATA_4BITSIGNED will have values
108  * 0000 -> 0111 for positive numbers and 1111 -> 1000 for negative numbers
109  * Bits 5 -> 8 in the storage byte are treated in an undefined manner.
110  * @note If srcfmt or dstfmt is an unknown format, this routine does nothing
111  * with no warning that something is wrong
112  *
113  * @api
114  */
115  void gmiscArrayConvert(ArrayDataFormat srcfmt, void *src, ArrayDataFormat dstfmt, void *dst, gMemSize cnt);
116 
117  #if 0
118  void gmiscArrayTranslate(ArrayDataFormat fmt, void *src, void *dst, gMemSize cnt, int trans);
119 
120  void gmiscArrayMultiply(ArrayDataFormat fmt, void *src, void *dst, gMemSize cnt, int mult);
121 
122  void gmiscArrayDivide(ArrayDataFormat fmt, void *src, void *dst, gMemSize cnt, int mdiv);
123 
124  void gmiscArrayMultDiv(ArrayDataFormat fmt, void *src, void *dst, gMemSize cnt, int mult, int div);
125 
126  void gmiscArrayAdd(ArrayDataFormat fmt, void *src1, void *src2, void *dst, gMemSize cnt);
127 
128  void gmiscArrayAddNoOverflow(ArrayDataFormat fmt, void *src1, void *src2, void *dst, gMemSize cnt);
129  #endif
130 #endif
131 
132 #if GMISC_NEED_FASTTRIG || defined(__DOXYGEN__)
133  #include <math.h>
134 
135  extern const double sintabledouble[];
136 
137  /**
138  * @brief Fast Table Based Trig functions
139  * @return A double in the range -1.0 .. 0.0 .. 1.0
140  * @pre Requires GFX_USE_GMISC and GMISC_NEED_FASTTRIG
141  *
142  * @param[in] degrees The angle in degrees (not radians)
143  *
144  * @note These functions use degrees rather than radians to describe the angle.
145  *
146  * @api
147  * @{
148  */
149  double fsin(int degrees);
150  double fcos(int degrees);
151  /** @}
152  *
153  * @brief Fast Table Based Trig functions
154  * @return A double in the range -1.0 .. 0.0 .. 1.0
155  * @pre Requires GFX_USE_GMISC and GMISC_NEED_FASTTRIG
156  *
157  * @param[in] degrees The angle in degrees 0 .. 359
158  *
159  * @note These functions use degrees rather than radians to describe the angle.
160  * @note These functions are super fast but require the parameter to be in range.
161  * Use the lowercase functions if the parameter may not be in range or if a
162  * required trig function is not supported in this form.
163  *
164  * @api
165  * @{
166  */
167  #define FSIN(degrees) sintabledouble[degrees];
168  /** @} */
169 #endif
170 
171 #if GMISC_NEED_FIXEDTRIG || defined(__DOXYGEN__)
172  extern const fixed sintablefixed[];
173 
174  /**
175  * @brief Fast Table Based Trig functions
176  * @return A fixed point in the range -1.0 .. 0.0 .. 1.0
177  * @pre Requires GFX_USE_GMISC and GMISC_NEED_FIXEDTRIG
178  *
179  * @param[in] degrees The angle in degrees (not radians)
180  *
181  * @note These functions use degrees rather than radians to describe the angle.
182  *
183  * @api
184  * @{
185  */
186  fixed ffsin(int degrees);
187  fixed ffcos(int degrees);
188  /** @}
189  *
190  * @brief Fast Table Based Trig functions
191  * @return A fixed point in the range -1.0 .. 0.0 .. 1.0
192  * @pre Requires GFX_USE_GMISC and GMISC_NEED_FIXEDTRIG
193  *
194  * @param[in] degrees The angle in degrees 0 .. 359
195  *
196  * @note These functions use degrees rather than radians to describe the angle.
197  * @note These functions are super fast but require the parameter to be in range.
198  * Use the lowercase functions if the parameter may not be in range or if a
199  * required trig function is not supported in this form.
200  *
201  * @api
202  * @{
203  */
204  #define FFSIN(degrees) sintablefixed[degrees];
205  /** @} */
206 #endif
207 
208 #if GMISC_NEED_INVSQRT || defined(__DOXYGEN__)
209  /**
210  * @brief Fast inverse square root function (x^-1/2)
211  * @return The approximate inverse square root
212  * @pre Requires GFX_USE_GMISC and GMISC_NEED_INVSQRT
213  *
214  * @param[in] n The number to find the inverse square root of
215  *
216  * @note This function generates an approximate result. Higher accuracy (at the expense
217  * of speed) can be obtained by modifying the source code (the necessary line
218  * is already there - just commented out).
219  * @note This function relies on the internal machine format of a float and a long.
220  * If your machine architecture is very unusual this function may not work.
221  *
222  * @api
223  */
224  float invsqrt(float n);
225 #endif
226 
227 #if GMISC_NEED_MATRIXFLOAT2D || defined(__DOXYGEN__)
228 
229  /**
230  * @brief A matrix for doing 2D graphics using floats
231  * @pre Requires GFX_USE_GMISC and GMISC_NEED_MATRIXFLOAT2D
232  */
233  typedef struct MatrixFloat2D {
234  float a00, a01, a02;
235  float a10, a11, a12;
236  float a20, a21, a22;
238 
239  /**
240  * @brief Apply the matrix to a set of points
241  * @pre Requires GFX_USE_GMISC and GMISC_NEED_MATRIXFLOAT2D
242  *
243  * @param[in] dst The destination array of points
244  * @param[in] src The source array of points
245  * @param[in] m The matrix to apply
246  * @param[in] cnt How many points are in the array
247  *
248  * @note In-place matrix application is allowed ie. dst = src
249  *
250  * @api
251  */
252  void gmiscMatrixFloat2DApplyToPoints(gPoint *dst, const gPoint *src, const MatrixFloat2D *m, int cnt);
253 
254  /**
255  * @brief Set the 2D matrix to the identity matrix
256  * @pre Requires GFX_USE_GMISC and GMISC_NEED_MATRIXFLOAT2D
257  *
258  * @param[in] m The matrix to set to identity
259  *
260  * @api
261  */
263 
264  /**
265  * @brief Multiple two 2D matrixes together
266  * @pre Requires GFX_USE_GMISC and GMISC_NEED_MATRIXFLOAT2D
267  *
268  * @param[in] dst The destination matrix
269  * @param[in] src1 The first source matrix
270  * @param[in] src2 The second source matrix
271  *
272  * @note In-place matrix application is NOT allowed ie. dst != src1, dst != src2
273  *
274  * @api
275  */
277 
278  /**
279  * @brief Add an x,y translation to a matrix
280  * @pre Requires GFX_USE_GMISC and GMISC_NEED_MATRIXFLOAT2D
281  *
282  * @param[in] dst The destination matrix
283  * @param[in] src The source matrix. Can be NULL
284  * @param[in] tx, ty The x and y translation to apply
285  *
286  * @note In-place matrix operation is NOT allowed ie. dst != src
287  * @note If no source matrix is provided, it is equivalent to applying the operation
288  * to an identity matrix. It also is a much simpler operation requiring no multiplication.
289  *
290  * @api
291  */
292  void gmiscMatrixFloat2DApplyTranslation(MatrixFloat2D *dst, const MatrixFloat2D *src, float tx, float ty);
293 
294  /**
295  * @brief Add x,y scaling to a matrix
296  * @pre Requires GFX_USE_GMISC and GMISC_NEED_MATRIXFLOAT2D
297  *
298  * @param[in] dst The destination matrix
299  * @param[in] src The source matrix. Can be NULL
300  * @param[in] sx, sy The scaling to apply in the x and y direction. Negative numbers give reflection.
301  *
302  * @note In-place matrix operation is NOT allowed ie. dst != src
303  * @note If no source matrix is provided, it is equivalent to applying the operation
304  * to an identity matrix. It also is a much simpler operation requiring no multiplication.
305  *
306  * @api
307  */
308  void gmiscMatrixFloat2DApplyScale(MatrixFloat2D *dst, const MatrixFloat2D *src, float sx, float sy);
309 
310  /**
311  * @brief Add x,y shear to a matrix
312  * @pre Requires GFX_USE_GMISC and GMISC_NEED_MATRIXFLOAT2D
313  *
314  * @param[in] dst The destination matrix
315  * @param[in] src The source matrix. Can be NULL
316  * @param[in] sx, sy The shear to apply in the x and y direction.
317  *
318  * @note In-place matrix operation is NOT allowed ie. dst != src
319  * @note If no source matrix is provided, it is equivalent to applying the operation
320  * to an identity matrix. It also is a much simpler operation requiring no multiplication.
321  *
322  * @api
323  */
324  void gmiscMatrixFloat2DApplyShear(MatrixFloat2D *dst, const MatrixFloat2D *src, float sx, float sy);
325 
326  /**
327  * @brief Add rotation to a matrix
328  * @pre Requires GFX_USE_GMISC and GMISC_NEED_MATRIXFLOAT2D
329  *
330  * @param[in] dst The destination matrix
331  * @param[in] src The source matrix. Can be NULL
332  * @param[in] angle The angle to apply in degrees (not radians).
333  *
334  * @note In-place matrix operation is NOT allowed ie. dst != src
335  * @note If no source matrix is provided, it is equivalent to applying the operation
336  * to an identity matrix. It also is a much simpler operation.
337  * @note If GMISC_NEED_FASTTRIG is defined then the fast table sin and cos lookup's will be used
338  * rather than the C library versions.
339  *
340  * @api
341  */
343 #endif
344 
345 #if GMISC_NEED_MATRIXFIXED2D || defined(__DOXYGEN__)
346 
347  /**
348  * @brief A matrix for doing 2D graphics using fixed point maths
349  * @pre Requires GFX_USE_GMISC and GMISC_NEED_MATRIXFIXED2D
350  */
351  typedef struct MatrixFixed2D {
352  fixed a00, a01, a02;
353  fixed a10, a11, a12;
354  fixed a20, a21, a22;
356 
357  /**
358  * @brief Apply the matrix to a set of points
359  * @pre Requires GFX_USE_GMISC and GMISC_NEED_MATRIXFIXED2D
360  *
361  * @param[in] dst The destination array of points
362  * @param[in] src The source array of points
363  * @param[in] m The matrix to apply
364  * @param[in] cnt How many points are in the array
365  *
366  * @note In-place matrix application is allowed ie. dst = src
367  *
368  * @api
369  */
370  void gmiscMatrixFixed2DApplyToPoints(gPoint *dst, const gPoint *src, const MatrixFixed2D *m, int cnt);
371 
372  /**
373  * @brief Set the 2D matrix to the identity matrix
374  * @pre Requires GFX_USE_GMISC and GMISC_NEED_MATRIXFIXED2D
375  *
376  * @param[in] m The matrix to set to identity
377  *
378  * @api
379  */
381 
382  /**
383  * @brief Multiple two 2D matrixes together
384  * @pre Requires GFX_USE_GMISC and GMISC_NEED_MATRIXFIXED2D
385  *
386  * @param[in] dst The destination matrix
387  * @param[in] src1 The first source matrix
388  * @param[in] src2 The second source matrix
389  *
390  * @note In-place matrix application is NOT allowed ie. dst != src1, dst != src2
391  *
392  * @api
393  */
395 
396  /**
397  * @brief Add an x,y translation to a matrix
398  * @pre Requires GFX_USE_GMISC and GMISC_NEED_MATRIXFIXED2D
399  *
400  * @param[in] dst The destination matrix
401  * @param[in] src The source matrix. Can be NULL
402  * @param[in] tx, ty The x and y translation to apply
403  *
404  * @note In-place matrix operation is NOT allowed ie. dst != src
405  * @note If no source matrix is provided, it is equivalent to applying the operation
406  * to an identity matrix. It also is a much simpler operation requiring no multiplication.
407  *
408  * @api
409  */
411 
412  /**
413  * @brief Add x,y scaling to a matrix
414  * @pre Requires GFX_USE_GMISC and GMISC_NEED_MATRIXFIXED2D
415  *
416  * @param[in] dst The destination matrix
417  * @param[in] src The source matrix. Can be NULL
418  * @param[in] sx, sy The scaling to apply in the x and y direction. Negative numbers give reflection.
419  *
420  * @note In-place matrix operation is NOT allowed ie. dst != src
421  * @note If no source matrix is provided, it is equivalent to applying the operation
422  * to an identity matrix. It also is a much simpler operation requiring no multiplication.
423  *
424  * @api
425  */
427 
428  /**
429  * @brief Add x,y shear to a matrix
430  * @pre Requires GFX_USE_GMISC and GMISC_NEED_MATRIXFIXED2D
431  *
432  * @param[in] dst The destination matrix
433  * @param[in] src The source matrix. Can be NULL
434  * @param[in] sx, sy The shear to apply in the x and y direction.
435  *
436  * @note In-place matrix operation is NOT allowed ie. dst != src
437  * @note If no source matrix is provided, it is equivalent to applying the operation
438  * to an identity matrix. It also is a much simpler operation requiring no multiplication.
439  *
440  * @api
441  */
443 
444  #if GMISC_NEED_FIXEDTRIG || defined(__DOXYGEN__)
445  /**
446  * @brief Add rotation to a matrix
447  * @pre Requires GFX_USE_GMISC and GMISC_NEED_MATRIXFIXED2D and GMISC_NEED_FIXEDTRIG
448  *
449  * @param[in] dst The destination matrix
450  * @param[in] src The source matrix. Can be NULL
451  * @param[in] angle The angle to apply in degrees (not radians).
452  *
453  * @note In-place matrix operation is NOT allowed ie. dst != src
454  * @note If no source matrix is provided, it is equivalent to applying the operation
455  * to an identity matrix. It also is a much simpler operation requiring no multiplication.
456  *
457  * @api
458  */
460  #endif
461 #endif
462 
463 
464 #if GMISC_NEED_HITTEST_POLY || defined(__DOXYGEN__)
465  /**
466  * @brief Check whether a point is inside or on the edge of a polygon
467  * @pre Requires GFX_USE_GMISC and GMISC_NEED_HITTEST_POLY
468  *
469  * @note This function works both with convex and concave polygons
470  *
471  * @param[in] pntarray The array of points that form the polygon
472  * @param[in] cnt The number of points in the point array @p pntarray
473  * @param[in] p The point to test
474  *
475  * @return @p gTrue if the point @p p is inside or on the edge of the polygon @p pntarray, @p gFalse otherwise.
476  *
477  * @api
478  */
479  gBool gmiscHittestPoly(const gPoint *pntarray, unsigned cnt, const gPoint *p);
480 #endif // GMISC_NEED_HITTEST_POLY
481 
482 #endif /* GFX_USE_MISC */
483 
484 #endif /* _GMISC_H */
485 /** @} */
486 
gBool gmiscHittestPoly(const gPoint *pntarray, unsigned cnt, const gPoint *p)
Check whether a point is inside or on the edge of a polygon.
void gmiscMatrixFixed2DApplyShear(MatrixFixed2D *dst, const MatrixFixed2D *src, fixed sx, fixed sy)
Add x,y shear to a matrix.
ArrayDataFormat_e
Sample data formats.
Definition: gmisc.h:36
gI32 fixed
The type for a fixed point type.
Definition: gmisc.h:60
void gmiscMatrixFloat2DApplyTranslation(MatrixFloat2D *dst, const MatrixFloat2D *src, float tx, float ty)
Add an x,y translation to a matrix.
void gmiscMatrixFloat2DApplyShear(MatrixFloat2D *dst, const MatrixFloat2D *src, float sx, float sy)
Add x,y shear to a matrix.
fixed ffsin(int degrees)
Fast Table Based Trig functions.
double fsin(int degrees)
Fast Table Based Trig functions.
float invsqrt(float n)
Fast inverse square root function (x^-1/2)
void gmiscMatrixFixed2DMultiply(MatrixFixed2D *dst, const MatrixFixed2D *src1, const MatrixFixed2D *src2)
Multiple two 2D matrixes together.
void gmiscMatrixFloat2DApplyRotation(MatrixFloat2D *dst, const MatrixFloat2D *src, int angle)
Add rotation to a matrix.
struct MatrixFloat2D MatrixFloat2D
A matrix for doing 2D graphics using floats.
void gmiscMatrixFloat2DSetIdentity(MatrixFloat2D *m)
Set the 2D matrix to the identity matrix.
void gmiscMatrixFixed2DApplyScale(MatrixFixed2D *dst, const MatrixFixed2D *src, fixed sx, fixed sy)
Add x,y scaling to a matrix.
void gmiscMatrixFixed2DApplyTranslation(MatrixFixed2D *dst, const MatrixFixed2D *src, fixed tx, fixed ty)
Add an x,y translation to a matrix.
void gmiscMatrixFixed2DApplyRotation(MatrixFixed2D *dst, const MatrixFixed2D *src, int angle)
Add rotation to a matrix.
void gmiscMatrixFloat2DApplyScale(MatrixFloat2D *dst, const MatrixFloat2D *src, float sx, float sy)
Add x,y scaling to a matrix.
void gmiscMatrixFloat2DApplyToPoints(gPoint *dst, const gPoint *src, const MatrixFloat2D *m, int cnt)
Apply the matrix to a set of points.
struct MatrixFixed2D MatrixFixed2D
A matrix for doing 2D graphics using fixed point maths.
void gmiscMatrixFloat2DMultiply(MatrixFloat2D *dst, const MatrixFloat2D *src1, const MatrixFloat2D *src2)
Multiple two 2D matrixes together.
void gmiscMatrixFixed2DSetIdentity(MatrixFixed2D *m)
Set the 2D matrix to the identity matrix.
void gmiscMatrixFixed2DApplyToPoints(gPoint *dst, const gPoint *src, const MatrixFixed2D *m, int cnt)
Apply the matrix to a set of points.
void gmiscArrayConvert(ArrayDataFormat srcfmt, void *src, ArrayDataFormat dstfmt, void *dst, gMemSize cnt)
Convert from one array format to another array format.
enum ArrayDataFormat_e ArrayDataFormat
Sample data formats.
A matrix for doing 2D graphics using fixed point maths.
Definition: gmisc.h:351
A matrix for doing 2D graphics using floats.
Definition: gmisc.h:233
Type for a 2D point on the screen.
Definition: gdisp.h:51