/* See LICENSE file for copyright and license details. */
#include "common.h"
#ifndef TEST
int
libfonts_get_subpixel_map(enum libfonts_subpixel_order_class layout, size_t rowsize, uint8_t *restrict map,
uint8_t *restrict n0p, uint8_t *restrict n1p, uint8_t *restrict n2p)
{
size_t n0, n1, n2;
#define SET_1_X_3(R1C1, R1C2, R1C3)\
do {\
if (map) {\
map[0] = (R1C1);\
map[1] = (R1C2);\
map[2] = (R1C3);\
}\
n0 = 1;\
n1 = 1;\
n2 = 1;\
} while (0)
#define SET_3_X_1(R1C1, R2C1, R3C1)\
do {\
if (map) {\
if (rowsize < 1)\
goto einval;\
map[0 * rowsize] = (R1C1);\
map[1 * rowsize] = (R2C1);\
map[2 * rowsize] = (R3C1);\
}\
n0 = 1;\
n1 = 1;\
n2 = 1;\
} while (0)
#define SET_2_X_2(R1C1, R1C2, R2C1, R2C2)\
do {\
if (map) {\
if (rowsize < 2)\
goto einval;\
map[0 * rowsize + 0] = (R1C1);\
map[0 * rowsize + 1] = (R1C2);\
map[1 * rowsize + 0] = (R2C1);\
map[1 * rowsize + 1] = (R2C2);\
}\
n0 = 2;\
n1 = 1;\
n2 = 1;\
} while (0)
#define SET_3_X_2(R1C1, R1C2, R2C1, R2C2, R3C1, R3C2)\
do {\
if (map) {\
if (rowsize < 2)\
goto einval;\
map[0 * rowsize + 0] = (R1C1);\
map[0 * rowsize + 1] = (R1C2);\
map[1 * rowsize + 0] = (R2C1);\
map[1 * rowsize + 1] = (R2C2);\
map[2 * rowsize + 0] = (R3C1);\
map[2 * rowsize + 1] = (R3C2);\
}\
n0 = 2;\
n1 = 2;\
n2 = 2;\
} while (0)
#define SET_2_X_3(R1C1, R1C2, R1C3, R2C1, R2C2, R2C3)\
do {\
if (map) {\
if (rowsize < 3)\
goto einval;\
map[0 * rowsize + 0] = (R1C1);\
map[0 * rowsize + 1] = (R1C2);\
map[0 * rowsize + 2] = (R1C3);\
map[1 * rowsize + 0] = (R2C1);\
map[1 * rowsize + 1] = (R2C2);\
map[1 * rowsize + 2] = (R2C3);\
}\
n0 = 2;\
n1 = 2;\
n2 = 2;\
} while (0)
switch (layout) {
case LIBFONTS_SUBPIXEL_ORDER_CLASS_123:
SET_1_X_3(0, 1, 2);
break;
case LIBFONTS_SUBPIXEL_ORDER_CLASS_1_2_3:
SET_3_X_1(0,
1,
2);
break;
case LIBFONTS_SUBPIXEL_ORDER_CLASS_11_23:
SET_2_X_2(0, 0,
1, 2);
break;
case LIBFONTS_SUBPIXEL_ORDER_CLASS_21_31:
SET_2_X_2(1, 0,
2, 0);
break;
case LIBFONTS_SUBPIXEL_ORDER_CLASS_32_11:
SET_2_X_2(2, 1,
0, 0);
break;
case LIBFONTS_SUBPIXEL_ORDER_CLASS_13_12:
SET_2_X_2(0, 2,
0, 1);
break;
case LIBFONTS_SUBPIXEL_ORDER_CLASS_BALANCED_11_23:
SET_3_X_2(0, 0,
1, 2,
1, 2);
break;
case LIBFONTS_SUBPIXEL_ORDER_CLASS_BALANCED_21_31:
SET_2_X_3(1, 1, 0,
2, 2, 0);
break;
case LIBFONTS_SUBPIXEL_ORDER_CLASS_BALANCED_32_11:
SET_3_X_2(2, 1,
2, 1,
0, 0);
break;
case LIBFONTS_SUBPIXEL_ORDER_CLASS_BALANCED_13_12:
SET_2_X_3(0, 2, 2,
0, 1, 1);
break;
case LIBFONTS_SUBPIXEL_ORDER_CLASS_OTHER:
default:
goto einval;
}
if (n0p)
*n0p = n0;
if (n1p)
*n1p = n1;
if (n2p)
*n2p = n2;
return 0;
einval:
errno = EINVAL;
return -1;
}
#else
int
main(void)
{
uint8_t map[128], ns[3];
size_t i, j, rowsize;
#define T(L)\
do {\
errno = 0;\
ASSERT(libfonts_get_subpixel_map(L, 16, NULL, NULL, NULL, NULL) == -1);\
ASSERT(errno == EINVAL);\
\
errno = 0;\
ASSERT(libfonts_get_subpixel_map(L, 16, map, NULL, NULL, NULL) == -1);\
ASSERT(errno == EINVAL);\
\
errno = 0;\
ASSERT(libfonts_get_subpixel_map(L, 16, map, &ns[0], &ns[1], &ns[2]) == -1);\
ASSERT(errno == EINVAL);\
} while (0)
T(LIBFONTS_SUBPIXEL_ORDER_CLASS_OTHER);
T((enum libfonts_subpixel_order_class)999);
#undef T
#define TEST_1_X_3(R1C1, R1C2, R1C3)\
do {\
ASSERT(map[0] == (R1C1) - 1);\
ASSERT(map[1] == (R1C2) - 1);\
ASSERT(map[2] == (R1C3) - 1);\
ASSERT(ns[0] == 1);\
ASSERT(ns[1] == 1);\
ASSERT(ns[2] == 1);\
} while (0)
#define TEST_3_X_1(R1C1, R2C1, R3C1)\
do {\
ASSERT(map[0 * rowsize] == (R1C1) - 1);\
ASSERT(map[1 * rowsize] == (R2C1) - 1);\
ASSERT(map[2 * rowsize] == (R3C1) - 1);\
ASSERT(ns[0] == 1);\
ASSERT(ns[1] == 1);\
ASSERT(ns[2] == 1);\
} while (0)
#define TEST_2_X_2(R1C1, R1C2, R2C1, R2C2)\
do {\
ASSERT(map[0 * rowsize + 0] == (R1C1) - 1);\
ASSERT(map[0 * rowsize + 1] == (R1C2) - 1);\
ASSERT(map[1 * rowsize + 0] == (R2C1) - 1);\
ASSERT(map[1 * rowsize + 1] == (R2C2) - 1);\
ASSERT(ns[0] == 2);\
ASSERT(ns[1] == 1);\
ASSERT(ns[2] == 1);\
} while (0)
#define TEST_3_X_2(R1C1, R1C2, R2C1, R2C2, R3C1, R3C2)\
do {\
ASSERT(map[0 * rowsize + 0] == (R1C1) - 1);\
ASSERT(map[0 * rowsize + 1] == (R1C2) - 1);\
ASSERT(map[1 * rowsize + 0] == (R2C1) - 1);\
ASSERT(map[1 * rowsize + 1] == (R2C2) - 1);\
ASSERT(map[2 * rowsize + 0] == (R3C1) - 1);\
ASSERT(map[2 * rowsize + 1] == (R3C2) - 1);\
ASSERT(ns[0] == 2);\
ASSERT(ns[1] == 2);\
ASSERT(ns[2] == 2);\
} while (0)
#define TEST_2_X_3(R1C1, R1C2, R1C3, R2C1, R2C2, R2C3)\
do {\
ASSERT(map[0 * rowsize + 0] == (R1C1) - 1);\
ASSERT(map[0 * rowsize + 1] == (R1C2) - 1);\
ASSERT(map[0 * rowsize + 2] == (R1C3) - 1);\
ASSERT(map[1 * rowsize + 0] == (R2C1) - 1);\
ASSERT(map[1 * rowsize + 1] == (R2C2) - 1);\
ASSERT(map[1 * rowsize + 2] == (R2C3) - 1);\
ASSERT(ns[0] == 2);\
ASSERT(ns[1] == 2);\
ASSERT(ns[2] == 2);\
} while (0)
#define TEST_3_X_2_BALANCED_2_X_2(R1C1, R1C2, R2C1, R2C2)\
TEST_3_X_2((R1C1), (R1C2),\
(R1C1) == (R1C2) ? (R2C1) : (R1C1),\
(R1C1) == (R1C2) ? (R2C2) : (R1C2),\
(R2C1), (R2C2))
#define TEST_2_X_3_BALANCED_2_X_2(R1C1, R1C2, R2C1, R2C2)\
TEST_2_X_3((R1C1), (R1C1) == (R2C1) ? (R1C2) : (R1C1), (R1C2),\
(R2C1), (R1C1) == (R2C1) ? (R2C2) : (R2C1), (R2C2))
#define CHECK_NS(H, W, N0, N1, N2)\
do {\
ns[0] = 0, ns[1] = 0, ns[2] = 0;\
for (i = 0; i < (H); i++) {\
for (j = 0; j < (W); j++) {\
ASSERT(map[i * rowsize + j] <= 2);\
ns[map[i * rowsize + j]] += 1;\
}\
}\
ASSERT(ns[0] == N0);\
ASSERT(ns[1] == N1);\
ASSERT(ns[2] == N2);\
} while (0)
#define T_(L, ROWSIZE, H, W, MAP, N0, N1, N2, NSCHECK, MAPTEST)\
do {\
rowsize = (ROWSIZE);\
\
errno = EDOM;\
ns[0] = 0, ns[1] = 0, ns[2] = 0;\
ASSERT(!libfonts_get_subpixel_map(L, rowsize, MAP, NULL, NULL, NULL));\
ASSERT(errno == EDOM);\
NSCHECK;\
MAPTEST;\
\
errno = EDOM;\
ns[0] = 0, ns[1] = 0, ns[2] = 0;\
ASSERT(!libfonts_get_subpixel_map(L, rowsize, MAP, &ns[0], NULL, NULL));\
ASSERT(errno == EDOM);\
ASSERT(ns[0] == (N0));\
NSCHECK;\
MAPTEST;\
\
errno = EDOM;\
ns[0] = 0, ns[1] = 0, ns[2] = 0;\
ASSERT(!libfonts_get_subpixel_map(L, rowsize, MAP, NULL, &ns[1], NULL));\
ASSERT(errno == EDOM);\
ASSERT(ns[1] == (N1));\
NSCHECK;\
MAPTEST;\
\
errno = EDOM;\
ns[0] = 0, ns[1] = 0, ns[2] = 0;\
ASSERT(!libfonts_get_subpixel_map(L, rowsize, MAP, &ns[0], &ns[1], NULL));\
ASSERT(errno == EDOM);\
ASSERT(ns[0] == (N0));\
ASSERT(ns[1] == (N1));\
NSCHECK;\
MAPTEST;\
\
errno = EDOM;\
ns[0] = 0, ns[1] = 0, ns[2] = 0;\
ASSERT(!libfonts_get_subpixel_map(L, rowsize, MAP, NULL, NULL, &ns[2]));\
ASSERT(errno == EDOM);\
ASSERT(ns[2] == (N2));\
NSCHECK;\
MAPTEST;\
\
errno = EDOM;\
ns[0] = 0, ns[1] = 0, ns[2] = 0;\
ASSERT(!libfonts_get_subpixel_map(L, rowsize, MAP, &ns[0], NULL, &ns[2]));\
ASSERT(errno == EDOM);\
ASSERT(ns[0] == (N0));\
ASSERT(ns[2] == (N2));\
NSCHECK;\
MAPTEST;\
\
errno = EDOM;\
ns[0] = 0, ns[1] = 0, ns[2] = 0;\
ASSERT(!libfonts_get_subpixel_map(L, rowsize, MAP, NULL, &ns[1], &ns[2]));\
ASSERT(errno == EDOM);\
ASSERT(ns[1] == (N1));\
ASSERT(ns[2] == (N2));\
NSCHECK;\
MAPTEST;\
\
errno = EDOM;\
ns[0] = 0, ns[1] = 0, ns[2] = 0;\
ASSERT(!libfonts_get_subpixel_map(L, rowsize, MAP, &ns[0], &ns[1], &ns[2]));\
ASSERT(errno == EDOM);\
ASSERT(ns[0] == (N0));\
ASSERT(ns[1] == (N1));\
ASSERT(ns[2] == (N2));\
NSCHECK;\
MAPTEST;\
} while (0)
#define T2_(L, ROWSIZE, H, N0, N1, N2, N0P, N1P, N2P)\
do {\
errno = EDOM;\
ns[0] = 0, ns[1] = 0, ns[2] = 0;\
ASSERT(!libfonts_get_subpixel_map(L, ROWSIZE, NULL, N0P, N1P, N2P));\
ASSERT(errno == EDOM);\
ASSERT(ns[0] == (N0));\
ASSERT(ns[1] == (N1));\
ASSERT(ns[2] == (N2));\
\
if (H > 1) {\
errno = 0;\
ASSERT(libfonts_get_subpixel_map(L, ROWSIZE, map, N0P, N1P, N2P) == -1);\
ASSERT(errno == EINVAL);\
} else {\
errno = EDOM;\
ns[0] = 0, ns[1] = 0, ns[2] = 0;\
ASSERT(!libfonts_get_subpixel_map(L, ROWSIZE, map, N0P, N1P, N2P));\
ASSERT(errno == EDOM);\
ASSERT(ns[0] == (N0));\
ASSERT(ns[1] == (N1));\
ASSERT(ns[2] == (N2));\
}\
} while (0)
#define T(L, H, W, N0, N1, N2, MAPTEST)\
do {\
T_(L, W, H, W, map, N0, N1, N2, CHECK_NS(H, W, N0, N1, N2), MAPTEST);\
T_(L, W, H, W, NULL, N0, N1, N2,,);\
T_(L, W + 1, H, W, map, N0, N1, N2, CHECK_NS(H, W, N0, N1, N2), MAPTEST);\
T_(L, W + 1, H, W, NULL, N0, N1, N2,,);\
T2_(L, W - 1, H, 0, 0, 0, NULL, NULL, NULL);\
T2_(L, W - 1, H, N0, 0, 0, &ns[0], NULL, NULL);\
T2_(L, W - 1, H, 0, N1, 0, NULL, &ns[1], NULL);\
T2_(L, W - 1, H, N0, N1, 0, &ns[0], &ns[1], NULL);\
T2_(L, W - 1, H, 0, 0, N2, NULL, NULL, &ns[2]);\
T2_(L, W - 1, H, N0, 0, N2, &ns[0], NULL, &ns[2]);\
T2_(L, W - 1, H, 0, N1, N2, NULL, &ns[1], &ns[2]);\
T2_(L, W - 1, H, N0, N1, N2, &ns[0], &ns[1], &ns[2]);\
} while (0)
T(LIBFONTS_SUBPIXEL_ORDER_CLASS_123,
1, 3, 1, 1, 1,
TEST_1_X_3(1, 2, 3));
T(LIBFONTS_SUBPIXEL_ORDER_CLASS_1_2_3,
3, 1, 1, 1, 1,
TEST_3_X_1(1,
2,
3));
T(LIBFONTS_SUBPIXEL_ORDER_CLASS_11_23,
2, 2, 2, 1, 1,
TEST_2_X_2(1, 1,
2, 3));
T(LIBFONTS_SUBPIXEL_ORDER_CLASS_21_31,
2, 2, 2, 1, 1,
TEST_2_X_2(2, 1,
3, 1));
T(LIBFONTS_SUBPIXEL_ORDER_CLASS_32_11,
2, 2, 2, 1, 1,
TEST_2_X_2(3, 2,
1, 1));
T(LIBFONTS_SUBPIXEL_ORDER_CLASS_13_12,
2, 2, 2, 1, 1,
TEST_2_X_2(1, 3,
1, 2));
T(LIBFONTS_SUBPIXEL_ORDER_CLASS_BALANCED_11_23,
3, 2, 2, 2, 2,
TEST_3_X_2(1, 1,
2, 3,
2, 3));
T(LIBFONTS_SUBPIXEL_ORDER_CLASS_BALANCED_21_31,
2, 3, 2, 2, 2,
TEST_2_X_3(2, 2, 1,
3, 3, 1));
T(LIBFONTS_SUBPIXEL_ORDER_CLASS_BALANCED_32_11,
3, 2, 2, 2, 2,
TEST_3_X_2_BALANCED_2_X_2(3, 2,
1, 1));
T(LIBFONTS_SUBPIXEL_ORDER_CLASS_BALANCED_13_12,
2, 3, 2, 2, 2,
TEST_2_X_3_BALANCED_2_X_2(1, 3,
1, 2));
return 0;
}
#endif