diff options
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | Makefile | 17 | ||||
-rw-r--r-- | common.h | 13 | ||||
-rw-r--r-- | libfonts.h | 19 | ||||
-rw-r--r-- | libfonts_get_subpixel_order_class.c | 129 | ||||
-rw-r--r-- | libfonts_unget_subpixel_order_class.c | 168 |
6 files changed, 335 insertions, 12 deletions
@@ -12,3 +12,4 @@ *.gcov *.gcno *.gcda +*.test @@ -25,6 +25,10 @@ OBJ =\ libfonts_get_subpixel_order_class.o\ libfonts_unget_subpixel_order_class.o +TESTS =\ + libfonts_get_subpixel_order_class.test\ + libfonts_unget_subpixel_order_class.test + HDR =\ common.h\ libfonts.h @@ -32,9 +36,10 @@ HDR =\ LOBJ = $(OBJ:.o=.lo) -all: libfonts.a libfonts.$(LIBEXT) +all: libfonts.a libfonts.$(LIBEXT) $(TESTS) $(OBJ): $(HDR) $(LOBJ): $(HDR) +$(TESTS): $(HDR) libfonts.a .c.o: $(CC) -c -o $@ $< $(CFLAGS) $(CPPFLAGS) @@ -42,6 +47,9 @@ $(LOBJ): $(HDR) .c.lo: $(CC) -fPIC -c -o $@ $< $(CFLAGS) $(CPPFLAGS) +.c.test: + $(CC) -o $@ $< libfonts.a $(CFLAGS) $(CPPFLAGS) -DTEST $(LDFLAGS) + libfonts.a: $(OBJ) @rm -f -- $@ $(AR) rc $@ $(OBJ) @@ -50,6 +58,9 @@ libfonts.a: $(OBJ) libfonts.$(LIBEXT): $(LOBJ) $(CC) $(LIBFLAGS) -o $@ $(LOBJ) $(LDFLAGS) +check: $(TESTS) + @for t in $(TESTS); do printf './%s\n' $$t; ./$$t || exit 1; done + install: libfonts.a libfonts.$(LIBEXT) mkdir -p -- "$(DESTDIR)$(PREFIX)/lib" mkdir -p -- "$(DESTDIR)$(PREFIX)/include" @@ -68,10 +79,10 @@ uninstall: -rm -f -- "$(DESTDIR)$(PREFIX)/include/libfonts.h" clean: - -rm -f -- *.o *.a *.lo *.su *.so *.so.* *.dll *.dylib + -rm -f -- *.o *.a *.lo *.su *.so *.so.* *.dll *.dylib *.test -rm -f -- *.gch *.gcov *.gcno *.gcda *.$(LIBEXT) .SUFFIXES: -.SUFFIXES: .lo .o .c +.SUFFIXES: .lo .o .c .test .PHONY: all install uninstall clean @@ -29,3 +29,16 @@ eq(double a, double b) { return b - DOUBLE_TOLERANCE <= a && a <= b + DOUBLE_TOLERANCE; } + + +#ifdef TEST + +# define ASSERT(ASSERTION)\ + do {\ + if (!(ASSERTION)) {\ + fprintf(stderr, "Failed assertion at line %u: %s\n", __LINE__, #ASSERTION);\ + exit(1);\ + }\ + } while (0) + +#endif @@ -1589,6 +1589,7 @@ ssize_t libfonts_get_default_font(enum libfonts_default_font, char *, size_t); * @throws EINVAL Unrecognised value on `font` */ ssize_t libfonts_get_default_font_name(enum libfonts_default_font, char *, size_t, size_t); +/* TODO add test */ /** * Get a default font a font name represents @@ -1617,6 +1618,7 @@ int libfonts_get_default_font_by_name(enum libfonts_default_font *, const char * * @throws EINVAL Invalid font description */ int libfonts_encode_font_description(const struct libfonts_font_description *, char[static 256]); +/* TODO add test */ /** * Decode an X Logical Font Description (XLFD) string @@ -1628,6 +1630,7 @@ int libfonts_encode_font_description(const struct libfonts_font_description *, c * @throws EINVAL Invalid font description */ int libfonts_decode_font_description(struct libfonts_font_description *, const char *); +/* TODO add test */ /** * Check if an X Logical Font Description (XLFD) matches @@ -1729,6 +1732,7 @@ int libfonts_get_output_rendering_settings(struct libfonts_rendering_settings *, * non-invertable output transformation) */ int libfonts_get_output_dpi(struct libfonts_output *, const char *); +/* TODO add test */ /** * Calculate the subpixel order on an output device after @@ -1739,6 +1743,7 @@ int libfonts_get_output_dpi(struct libfonts_output *, const char *); * @return The device's logical subpixel order */ enum libfonts_subpixel_order libfonts_calculate_subpixel_order(enum libfonts_subpixel_order, const struct libfonts_transformation *); +/* TODO add test */ /** * Get the general subpixel layout, as well @@ -1763,13 +1768,13 @@ enum libfonts_subpixel_order_class libfonts_get_subpixel_order_class(enum libfon * cell in the layout, from a specific * subpixel order * - * @param orderp Output parameter for the subpixel order - * @param layout The subpixel layout - * @param cell1 The primary contained in cell 1 - * @param cell2 The primary contained in cell 2 - * @param cell3 The primary contained in cell 3 - * @return Normally 1, but 0 if `layout` is `LIBFONTS_SUBPIXEL_ORDER_CLASS_OTHER`; - * -1 on failure + * @param orderp Output parameter for the subpixel order + * @param layout The subpixel layout + * @param cell1 The primary contained in cell 1 + * @param cell2 The primary contained in cell 2 + * @param cell3 The primary contained in cell 3 + * @return Normally 1, but 0 if `layout` is `LIBFONTS_SUBPIXEL_ORDER_CLASS_OTHER`; + * -1 on failure * * @throws EINVAL Unrecognised value in `layout`, `cell1`, `cell2`, or `cell3` * @throws EINVAL The values of `cell1`, `cell2`, and `cell3` are not unique diff --git a/libfonts_get_subpixel_order_class.c b/libfonts_get_subpixel_order_class.c index 577b0f0..2c6e3bc 100644 --- a/libfonts_get_subpixel_order_class.c +++ b/libfonts_get_subpixel_order_class.c @@ -1,5 +1,6 @@ /* See LICENSE file for copyright and license details. */ #include "common.h" +#ifndef TEST enum libfonts_subpixel_order_class @@ -39,3 +40,131 @@ libfonts_get_subpixel_order_class(enum libfonts_subpixel_order order, *cell3p = c3; return layout; } + + +#else + + +int +main(void) +{ + enum libfonts_subpixel_colour c1, c2, c3; + +#define R LIBFONTS_SUBPIXEL_COLOUR_RED +#define G LIBFONTS_SUBPIXEL_COLOUR_GREEN +#define B LIBFONTS_SUBPIXEL_COLOUR_BLUE + +#define T(ORDER, LAYOUT, C1, C2, C3)\ + T_(LIBFONTS_SUBPIXEL_ORDER_##ORDER,\ + LIBFONTS_SUBPIXEL_ORDER_CLASS_##LAYOUT,\ + C1, C2, C3) +#define T_(ORDER, LAYOUT, C1, C2, C3)\ + do {\ + errno = 0;\ + c1 = c2 = c3 = -1;\ + ASSERT(libfonts_get_subpixel_order_class(ORDER, &c1, &c2, &c3) == LAYOUT);\ + ASSERT(c1 == C1);\ + ASSERT(c2 == C2);\ + ASSERT(c3 == C3);\ + ASSERT(!errno);\ + ASSERT(libfonts_get_subpixel_order_class(ORDER, NULL, &c2, &c3) == LAYOUT);\ + ASSERT(c2 == C2);\ + ASSERT(c3 == C3);\ + ASSERT(!errno);\ + ASSERT(libfonts_get_subpixel_order_class(ORDER, &c1, NULL, &c3) == LAYOUT);\ + ASSERT(c1 == C1);\ + ASSERT(c3 == C3);\ + ASSERT(!errno);\ + ASSERT(libfonts_get_subpixel_order_class(ORDER, &c1, &c2, NULL) == LAYOUT);\ + ASSERT(c1 == C1);\ + ASSERT(c2 == C2);\ + ASSERT(!errno);\ + } while (0) + + T(UNKNOWN, OTHER, R, G, B); + T(NONRGB, OTHER, R, G, B); + T(NONLINEAR, OTHER, R, G, B); + T(OTHER, OTHER, R, G, B); + T(UNKNOWN - 1000, OTHER, R, G, B); + T(UNKNOWN + 9999, OTHER, R, G, B); + + T(RGB, 123, R, G, B); + T(R_G_B, 1_2_3, R, G, B); + T(BGR, 123, B, G, R); + T(B_G_R, 1_2_3, B, G, R); + + T(GBR, 123, G, B, R); + T(G_B_R, 1_2_3, G, B, R); + T(RBG, 123, R, B, G); + T(R_B_G, 1_2_3, R, B, G); + + T(BRG, 123, B, R, G); + T(B_R_G, 1_2_3, B, R, G); + T(GRB, 123, G, R, B); + T(G_R_B, 1_2_3, G, R, B); + + T(RR_GB, 11_23, R, G, B); + T(GR_BR, 21_31, R, G, B); + T(BG_RR, 32_11, R, G, B); + T(RB_RG, 13_12, R, G, B); + + T(RR_BG, 11_23, R, B, G); + T(BR_GR, 21_31, R, B, G); + T(GB_RR, 32_11, R, B, G); + T(RG_RB, 13_12, R, B, G); + + T(GG_RB, 11_23, G, R, B); + T(RG_BG, 21_31, G, R, B); + T(BR_GG, 32_11, G, R, B); + T(GB_GR, 13_12, G, R, B); + + T(GG_BR, 11_23, G, B, R); + T(BG_RG, 21_31, G, B, R); + T(RB_GG, 32_11, G, B, R); + T(GR_GB, 13_12, G, B, R); + + T(BB_RG, 11_23, B, R, G); + T(RB_GB, 21_31, B, R, G); + T(GR_BB, 32_11, B, R, G); + T(BG_BR, 13_12, B, R, G); + + T(BB_GR, 11_23, B, G, R); + T(GB_RB, 21_31, B, G, R); + T(RG_BB, 32_11, B, G, R); + T(BR_BG, 13_12, B, G, R); + + T(BALANCED_RR_GB, BALANCED_11_23, R, G, B); + T(BALANCED_GR_BR, BALANCED_21_31, R, G, B); + T(BALANCED_BG_RR, BALANCED_32_11, R, G, B); + T(BALANCED_RB_RG, BALANCED_13_12, R, G, B); + + T(BALANCED_RR_BG, BALANCED_11_23, R, B, G); + T(BALANCED_BR_GR, BALANCED_21_31, R, B, G); + T(BALANCED_GB_RR, BALANCED_32_11, R, B, G); + T(BALANCED_RG_RB, BALANCED_13_12, R, B, G); + + T(BALANCED_GG_RB, BALANCED_11_23, G, R, B); + T(BALANCED_RG_BG, BALANCED_21_31, G, R, B); + T(BALANCED_BR_GG, BALANCED_32_11, G, R, B); + T(BALANCED_GB_GR, BALANCED_13_12, G, R, B); + + T(BALANCED_GG_BR, BALANCED_11_23, G, B, R); + T(BALANCED_BG_RG, BALANCED_21_31, G, B, R); + T(BALANCED_RB_GG, BALANCED_32_11, G, B, R); + T(BALANCED_GR_GB, BALANCED_13_12, G, B, R); + + T(BALANCED_BB_RG, BALANCED_11_23, B, R, G); + T(BALANCED_RB_GB, BALANCED_21_31, B, R, G); + T(BALANCED_GR_BB, BALANCED_32_11, B, R, G); + T(BALANCED_BG_BR, BALANCED_13_12, B, R, G); + + T(BALANCED_BB_GR, BALANCED_11_23, B, G, R); + T(BALANCED_GB_RB, BALANCED_21_31, B, G, R); + T(BALANCED_RG_BB, BALANCED_32_11, B, G, R); + T(BALANCED_BR_BG, BALANCED_13_12, B, G, R); + + return 0; +} + + +#endif diff --git a/libfonts_unget_subpixel_order_class.c b/libfonts_unget_subpixel_order_class.c index 5fa9274..47d8366 100644 --- a/libfonts_unget_subpixel_order_class.c +++ b/libfonts_unget_subpixel_order_class.c @@ -1,5 +1,6 @@ /* See LICENSE file for copyright and license details. */ #include "common.h" +#ifndef TEST int @@ -35,12 +36,12 @@ libfonts_unget_subpixel_order_class(enum libfonts_subpixel_order *orderp, } return 1; - } else if (layout >= LIBFONTS_SUBPIXEL_ORDER_CLASS_11_23 || layout <= LIBFONTS_SUBPIXEL_ORDER_CLASS_BALANCED_13_12) { + } else if (layout >= LIBFONTS_SUBPIXEL_ORDER_CLASS_11_23 && layout <= LIBFONTS_SUBPIXEL_ORDER_CLASS_BALANCED_13_12) { if (orderp) { /* RGB, RBG, GRB, GBR, BRG, BGR */ i = (cell1 * 2) + (cell2 > cell3); *orderp = i * 4 + (layout - LIBFONTS_SUBPIXEL_ORDER_CLASS_11_23) % 4 + LIBFONTS_SUBPIXEL_ORDER_RR_GB; - *orderp = (layout >= LIBFONTS_SUBPIXEL_ORDER_CLASS_BALANCED_11_23) * 24; + *orderp += (layout >= LIBFONTS_SUBPIXEL_ORDER_CLASS_BALANCED_11_23) * 24; } return 1; @@ -49,3 +50,166 @@ libfonts_unget_subpixel_order_class(enum libfonts_subpixel_order *orderp, return -1; } } + + +#else + + +int +main(void) +{ +#define R LIBFONTS_SUBPIXEL_COLOUR_RED +#define G LIBFONTS_SUBPIXEL_COLOUR_GREEN +#define B LIBFONTS_SUBPIXEL_COLOUR_BLUE + +#define T(ORDER, LAYOUT, C1, C2, C3)\ + T_(LIBFONTS_SUBPIXEL_ORDER_##ORDER,\ + LIBFONTS_SUBPIXEL_ORDER_CLASS_##LAYOUT,\ + C1, C2, C3) +#define T_(ORDER, LAYOUT, C1, C2, C3)\ + do {\ + errno = 0;\ + order = -1;\ + ASSERT(libfonts_unget_subpixel_order_class(&order, LAYOUT, C1, C2, C3) == 1);\ + ASSERT(order == ORDER);\ + ASSERT(!errno);\ + ASSERT(libfonts_unget_subpixel_order_class(NULL, LAYOUT, C1, C2, C3) == 1);\ + ASSERT(!errno);\ + } while (0) + +#define TU(LAYOUT, C1, C2, C3)\ + TU_(LIBFONTS_SUBPIXEL_ORDER_CLASS_##LAYOUT, C1, C2, C3) +#define TU_(LAYOUT, C1, C2, C3)\ + do {\ + errno = 0;\ + order = -1;\ + ASSERT(libfonts_unget_subpixel_order_class(&order, LAYOUT, C1, C2, C3) == 0);\ + ASSERT(order == LIBFONTS_SUBPIXEL_ORDER_UNKNOWN);\ + ASSERT(!errno);\ + ASSERT(libfonts_unget_subpixel_order_class(NULL, LAYOUT, C1, C2, C3) == 0);\ + ASSERT(!errno);\ + } while (0) + +#define TE(LAYOUT, C1, C2, C3)\ + TE_(LIBFONTS_SUBPIXEL_ORDER_CLASS_##LAYOUT, C1, C2, C3) +#define TE_(LAYOUT, C1, C2, C3)\ + do {\ + errno = 0;\ + ASSERT(libfonts_unget_subpixel_order_class(&order, LAYOUT, C1, C2, C3) == -1);\ + ASSERT(errno == EINVAL);\ + errno = 0;\ + ASSERT(libfonts_unget_subpixel_order_class(NULL, LAYOUT, C1, C2, C3) == -1);\ + ASSERT(errno == EINVAL);\ + } while (0) + + enum libfonts_subpixel_order order; + + TU(OTHER, R, G, B); + TU(OTHER, G, B, R); + TU(OTHER, B, R, G); + TU(OTHER, R, B, G); + TU(OTHER, G, R, B); + TU(OTHER, B, G, R); + + TE(OTHER, -1, G, B); + TE(OTHER, R, -1, B); + TE(OTHER, R, G, -1); + TE(OTHER, -1, -2, B); + TE(OTHER, 3, G, B); + TE(OTHER, R, 3, B); + TE(OTHER, R, G, 3); + TE(OTHER, R, 3, 4); + TE(123, -1, G, B); + TE(123, R, -1, B); + TE(123, R, G, -1); + TE(123, -1, -2, B); + TE(123, 3, G, B); + TE(123, R, 3, B); + TE(123, R, G, 3); + TE(123, R, 3, 4); + TE(123, R, R, G); + TE(123, R, G, R); + TE(123, R, G, G); + TE_(-1, R, G, B); + TE_(9999, R, G, B); + + T(RGB, 123, R, G, B); + T(R_G_B, 1_2_3, R, G, B); + T(BGR, 123, B, G, R); + T(B_G_R, 1_2_3, B, G, R); + + T(GBR, 123, G, B, R); + T(G_B_R, 1_2_3, G, B, R); + T(RBG, 123, R, B, G); + T(R_B_G, 1_2_3, R, B, G); + + T(BRG, 123, B, R, G); + T(B_R_G, 1_2_3, B, R, G); + T(GRB, 123, G, R, B); + T(G_R_B, 1_2_3, G, R, B); + + T(RR_GB, 11_23, R, G, B); + T(GR_BR, 21_31, R, G, B); + T(BG_RR, 32_11, R, G, B); + T(RB_RG, 13_12, R, G, B); + + T(RR_BG, 11_23, R, B, G); + T(BR_GR, 21_31, R, B, G); + T(GB_RR, 32_11, R, B, G); + T(RG_RB, 13_12, R, B, G); + + T(GG_RB, 11_23, G, R, B); + T(RG_BG, 21_31, G, R, B); + T(BR_GG, 32_11, G, R, B); + T(GB_GR, 13_12, G, R, B); + + T(GG_BR, 11_23, G, B, R); + T(BG_RG, 21_31, G, B, R); + T(RB_GG, 32_11, G, B, R); + T(GR_GB, 13_12, G, B, R); + + T(BB_RG, 11_23, B, R, G); + T(RB_GB, 21_31, B, R, G); + T(GR_BB, 32_11, B, R, G); + T(BG_BR, 13_12, B, R, G); + + T(BB_GR, 11_23, B, G, R); + T(GB_RB, 21_31, B, G, R); + T(RG_BB, 32_11, B, G, R); + T(BR_BG, 13_12, B, G, R); + + T(BALANCED_RR_GB, BALANCED_11_23, R, G, B); + T(BALANCED_GR_BR, BALANCED_21_31, R, G, B); + T(BALANCED_BG_RR, BALANCED_32_11, R, G, B); + T(BALANCED_RB_RG, BALANCED_13_12, R, G, B); + + T(BALANCED_RR_BG, BALANCED_11_23, R, B, G); + T(BALANCED_BR_GR, BALANCED_21_31, R, B, G); + T(BALANCED_GB_RR, BALANCED_32_11, R, B, G); + T(BALANCED_RG_RB, BALANCED_13_12, R, B, G); + + T(BALANCED_GG_RB, BALANCED_11_23, G, R, B); + T(BALANCED_RG_BG, BALANCED_21_31, G, R, B); + T(BALANCED_BR_GG, BALANCED_32_11, G, R, B); + T(BALANCED_GB_GR, BALANCED_13_12, G, R, B); + + T(BALANCED_GG_BR, BALANCED_11_23, G, B, R); + T(BALANCED_BG_RG, BALANCED_21_31, G, B, R); + T(BALANCED_RB_GG, BALANCED_32_11, G, B, R); + T(BALANCED_GR_GB, BALANCED_13_12, G, B, R); + + T(BALANCED_BB_RG, BALANCED_11_23, B, R, G); + T(BALANCED_RB_GB, BALANCED_21_31, B, R, G); + T(BALANCED_GR_BB, BALANCED_32_11, B, R, G); + T(BALANCED_BG_BR, BALANCED_13_12, B, R, G); + + T(BALANCED_BB_GR, BALANCED_11_23, B, G, R); + T(BALANCED_GB_RB, BALANCED_21_31, B, G, R); + T(BALANCED_RG_BB, BALANCED_32_11, B, G, R); + T(BALANCED_BR_BG, BALANCED_13_12, B, G, R); + + return 0; +} + + +#endif |