aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile1
-rw-r--r--libfonts.h7
-rw-r--r--libfonts_calculate_subpixel_order.c343
3 files changed, 346 insertions, 5 deletions
diff --git a/Makefile b/Makefile
index 016ca67..cc2a08b 100644
--- a/Makefile
+++ b/Makefile
@@ -26,6 +26,7 @@ OBJ =\
libfonts_unget_subpixel_order_class.o
TESTS =\
+ libfonts_calculate_subpixel_order.test\
libfonts_get_subpixel_order_class.test\
libfonts_unget_subpixel_order_class.test
diff --git a/libfonts.h b/libfonts.h
index 1c3437f..326f301 100644
--- a/libfonts.h
+++ b/libfonts.h
@@ -1681,7 +1681,8 @@ int libfonts_do_font_descriptions_match(const char *, const char *);
* @param spec The specification to test the description against, may include wildcards
* @return 1 if the arguments match, 0 if they don't match
*/
-int libfonts_do_decoded_font_descriptions_match(const struct libfonts_font_description *, const struct libfonts_font_description *);
+int libfonts_do_decoded_font_descriptions_match(const struct libfonts_font_description *,
+ const struct libfonts_font_description *);
/* TODO implement libfonts_do_decoded_font_descriptions_match */
@@ -1772,8 +1773,8 @@ int libfonts_get_output_dpi(struct libfonts_output *, const char *);
* @param transformation The applied transformation
* @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 */
+enum libfonts_subpixel_order libfonts_calculate_subpixel_order(enum libfonts_subpixel_order,
+ const struct libfonts_transformation *);
/**
* Get the general subpixel layout, as well
diff --git a/libfonts_calculate_subpixel_order.c b/libfonts_calculate_subpixel_order.c
index 493b9e7..bba645b 100644
--- a/libfonts_calculate_subpixel_order.c
+++ b/libfonts_calculate_subpixel_order.c
@@ -1,5 +1,6 @@
/* See LICENSE file for copyright and license details. */
#include "common.h"
+#ifndef TEST
enum libfonts_subpixel_order
@@ -99,7 +100,7 @@ known:
case ANTITRANSPOSED:
if (unrotated <= LIBFONTS_SUBPIXEL_ORDER_G_R_B)
- return unrotated ^ 1;
+ return unrotated ^ 3;
else
return unrotated ^ 5;
@@ -107,7 +108,7 @@ known:
if (unrotated <= LIBFONTS_SUBPIXEL_ORDER_G_R_B)
return unrotated ^ 1;
else
- return 8 - (unrotated & 7) + (unrotated & ~7);
+ return 7 - (unrotated & 7) + (unrotated & ~7);
case FLOPPED:
if (unrotated <= LIBFONTS_SUBPIXEL_ORDER_G_R_B)
@@ -128,3 +129,341 @@ known:
return ((unrotated + trans) & 3) + (unrotated & ~3);
}
}
+
+
+#else
+
+
+static int
+test(int xtrans, int ytrans, int zscale, int xscale, int yscale)
+{
+#define T(IN, OUT, MAT)\
+ T_(LIBFONTS_SUBPIXEL_ORDER_##IN, LIBFONTS_SUBPIXEL_ORDER_##OUT, &MAT)
+
+#define T_(IN, OUT, MAT)\
+ ASSERT(libfonts_calculate_subpixel_order(IN, MAT) == OUT)
+
+#define ASIS_(IN, OUT) T(IN, OUT, asis_matrix)
+#define ROT90CW_(IN, OUT) T(IN, OUT, rot90cw_matrix)
+#define ROT180CW_(IN, OUT) T(IN, OUT, rot180cw_matrix)
+#define ROT270CW_(IN, OUT) T(IN, OUT, rot270cw_matrix)
+#define FLIP_(IN, OUT) T(IN, OUT, flip_matrix)
+#define FLOP_(IN, OUT) T(IN, OUT, flop_matrix)
+#define TRANSPOSE_(IN, OUT) T(IN, OUT, transpose_matrix)
+#define ANTITRANSPOSE_(IN, OUT) T(IN, OUT, antitranspose_matrix)
+#define NONLINEAR_(IN, OUT) T(IN, OUT, nonlinear_matrix)
+#define UNKNOWN_(IN, OUT) T(IN, OUT, unknown_matrix)
+
+#define ROT(R0, R270, R180, R90)\
+ do {\
+ ASIS_(R0, R0);\
+ ASIS_(R90, R90);\
+ ASIS_(R180, R180);\
+ ASIS_(R270, R270);\
+ ROT90CW_(R0, R90);\
+ ROT90CW_(R90, R180);\
+ ROT90CW_(R180, R270);\
+ ROT90CW_(R270, R0);\
+ ROT180CW_(R0, R180);\
+ ROT180CW_(R90, R270);\
+ ROT180CW_(R180, R0);\
+ ROT180CW_(R270, R90);\
+ ROT270CW_(R0, R270);\
+ ROT270CW_(R90, R0);\
+ ROT270CW_(R180, R90);\
+ ROT270CW_(R270, R180);\
+ } while (0)
+#define FLIP(A, B)\
+ do {\
+ FLIP_(A, B);\
+ FLIP_(B, A);\
+ } while(0)
+#define FLOP(A, B)\
+ do {\
+ FLOP_(A, B);\
+ FLOP_(B, A);\
+ } while(0)
+#define TRANSPOSE(A, B)\
+ do {\
+ TRANSPOSE_(A, B);\
+ TRANSPOSE_(B, A);\
+ } while(0)
+#define ANTITRANSPOSE(A, B)\
+ do {\
+ ANTITRANSPOSE_(A, B);\
+ ANTITRANSPOSE_(B, A);\
+ } while(0)
+#define NONLINEAR(IN) NONLINEAR_(IN, NONLINEAR)
+#define UNKNOWN(IN) UNKNOWN_(IN, UNKNOWN)
+
+#define ROTX(R0, R270, R180, R90)\
+ do {\
+ ROT(R0, R270, R180, R90);\
+ ROT(BALANCED_##R0, BALANCED_##R270, BALANCED_##R180, BALANCED_##R90);\
+ } while (0)
+#define X(M, A, B)\
+ do {\
+ M(A, B);\
+ M(BALANCED_##A, BALANCED_##B);\
+ } while(0)
+#define NONLINEARX(A)\
+ do {\
+ NONLINEAR(A);\
+ NONLINEAR(BALANCED_##A);\
+ } while(0)
+#define UNKNOWNX(A)\
+ do {\
+ UNKNOWN(A);\
+ UNKNOWN(BALANCED_##A);\
+ } while(0)
+
+ struct libfonts_transformation asis_matrix = {.m = {
+ {+xscale, 0, xtrans},
+ { 0, +yscale, ytrans},
+ { 0, 0, zscale}}};
+ struct libfonts_transformation rot90cw_matrix = {.m = {
+ { 0, -yscale, xtrans},
+ {+xscale, 0, ytrans},
+ { 0, 0, zscale}}};
+ struct libfonts_transformation rot180cw_matrix = {.m = {
+ {-xscale, 0, xtrans},
+ { 0, -yscale, ytrans},
+ { 0, 0, zscale}}};
+ struct libfonts_transformation rot270cw_matrix = {.m = {
+ { 0, +yscale, xtrans},
+ {-xscale, 0, ytrans},
+ { 0, 0, zscale}}};
+ struct libfonts_transformation flip_matrix = {.m = {
+ {+xscale, 0, xtrans},
+ { 0, -yscale, ytrans},
+ { 0, 0, zscale}}};
+ struct libfonts_transformation flop_matrix = {.m = {
+ {-xscale, 0, xtrans},
+ { 0, +yscale, ytrans},
+ { 0, 0, zscale}}};
+ struct libfonts_transformation transpose_matrix = {.m = {
+ { 0, +yscale, xtrans},
+ {+xscale, 0, ytrans},
+ { 0, 0, zscale}}};
+ struct libfonts_transformation antitranspose_matrix = {.m = {
+ { 0, -yscale, xtrans},
+ {-xscale, 0, ytrans},
+ { 0, 0, zscale}}};
+ struct libfonts_transformation nonlinear_matrix = {.m = {
+ {+xscale, +yscale / 2., xtrans},
+ { 0, +yscale, ytrans},
+ { 0, 0, zscale}}};
+ struct libfonts_transformation unknown_matrix = {.m = {
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}}};
+
+#define UNSUPPORTED(A)\
+ do {\
+ ASIS_(A, A);\
+ ROT90CW_(A, A);\
+ ROT180CW_(A, A);\
+ ROT270CW_(A, A);\
+ FLIP_(A, A);\
+ FLOP_(A, A);\
+ TRANSPOSE_(A, A);\
+ ANTITRANSPOSE_(A, A);\
+ NONLINEAR_(A, A);\
+ UNKNOWN_(A, A);\
+ } while (0)
+
+ UNSUPPORTED(UNKNOWN);
+ UNSUPPORTED(NONRGB);
+ UNSUPPORTED(NONLINEAR);
+ UNSUPPORTED(OTHER);
+
+ ROT(RGB, R_G_B, BGR, B_G_R);
+ ROT(GBR, G_B_R, RBG, R_B_G);
+ ROT(BRG, B_R_G, GRB, G_R_B);
+ ROTX(RR_GB, GR_BR, BG_RR, RB_RG);
+ ROTX(RR_BG, BR_GR, GB_RR, RG_RB);
+ ROTX(GG_RB, RG_BG, BR_GG, GB_GR);
+ ROTX(GG_BR, BG_RG, RB_GG, GR_GB);
+ ROTX(BB_RG, RB_GB, GR_BB, BG_BR);
+ ROTX(BB_GR, GB_RB, RG_BB, BR_BG);
+
+ FLIP(RGB, RGB);
+ FLIP(R_G_B, B_G_R);
+ FLIP(BGR, BGR);
+ FLIP(GBR, GBR);
+ FLIP(G_B_R, R_B_G);
+ FLIP(RBG, RBG);
+ FLIP(BRG, BRG);
+ FLIP(B_R_G, G_R_B);
+ FLIP(GRB, GRB);
+ X(FLIP, RR_GB, GB_RR);
+ X(FLIP, GR_BR, BR_GR);
+ X(FLIP, BG_RR, RR_BG);
+ X(FLIP, RB_RG, RG_RB);
+ X(FLIP, GG_RB, RB_GG);
+ X(FLIP, RG_BG, BG_RG);
+ X(FLIP, BR_GG, GG_BR);
+ X(FLIP, GB_GR, GR_GB);
+ X(FLIP, BB_RG, RG_BB);
+ X(FLIP, RB_GB, GB_RB);
+ X(FLIP, GR_BB, BB_GR);
+ X(FLIP, BG_BR, BR_BG);
+
+ FLOP(RGB, BGR);
+ FLOP(R_G_B, R_G_B);
+ FLOP(B_G_R, B_G_R);
+ FLOP(GBR, RBG);
+ FLOP(G_B_R, G_B_R);
+ FLOP(R_B_G, R_B_G);
+ FLOP(BRG, GRB);
+ FLOP(B_R_G, B_R_G);
+ FLOP(G_R_B, G_R_B);
+ X(FLOP, RR_GB, RR_BG);
+ X(FLOP, GR_BR, RG_RB);
+ X(FLOP, BG_RR, GB_RR);
+ X(FLOP, RB_RG, BR_GR);
+ X(FLOP, GG_RB, GG_BR);
+ X(FLOP, RG_BG, GR_GB);
+ X(FLOP, BR_GG, RB_GG);
+ X(FLOP, GB_GR, BG_RG);
+ X(FLOP, BB_RG, BB_GR);
+ X(FLOP, RB_GB, BR_BG);
+ X(FLOP, GR_BB, RG_BB);
+ X(FLOP, BG_BR, GB_RB);
+
+ TRANSPOSE(RGB, R_G_B);
+ TRANSPOSE(BGR, B_G_R);
+ TRANSPOSE(GBR, G_B_R);
+ TRANSPOSE(RBG, R_B_G);
+ TRANSPOSE(BRG, B_R_G);
+ TRANSPOSE(GRB, G_R_B);
+ X(TRANSPOSE, RR_GB, RG_RB);
+ X(TRANSPOSE, GR_BR, GB_RR);
+ X(TRANSPOSE, BG_RR, BR_GR);
+ X(TRANSPOSE, RB_RG, RR_BG);
+ X(TRANSPOSE, GG_RB, GR_GB);
+ X(TRANSPOSE, RG_BG, RB_GG);
+ X(TRANSPOSE, BR_GG, BG_RG);
+ X(TRANSPOSE, GB_GR, GG_BR);
+ X(TRANSPOSE, BB_RG, BR_BG);
+ X(TRANSPOSE, RB_GB, RG_BB);
+ X(TRANSPOSE, GR_BB, GB_RB);
+ X(TRANSPOSE, BG_BR, BB_GR);
+
+ ANTITRANSPOSE(RGB, B_G_R);
+ ANTITRANSPOSE(BGR, R_G_B);
+ ANTITRANSPOSE(GBR, R_B_G);
+ ANTITRANSPOSE(RBG, G_B_R);
+ ANTITRANSPOSE(BRG, G_R_B);
+ ANTITRANSPOSE(GRB, B_R_G);
+ X(ANTITRANSPOSE, RR_GB, BR_GR);
+ X(ANTITRANSPOSE, GR_BR, RR_BG);
+ X(ANTITRANSPOSE, BG_RR, RG_RB);
+ X(ANTITRANSPOSE, RB_RG, GB_RR);
+ X(ANTITRANSPOSE, GG_RB, BG_RG);
+ X(ANTITRANSPOSE, RG_BG, GG_BR);
+ X(ANTITRANSPOSE, BR_GG, GR_GB);
+ X(ANTITRANSPOSE, GB_GR, RB_GG);
+ X(ANTITRANSPOSE, BB_RG, GB_RB);
+ X(ANTITRANSPOSE, RB_GB, BB_GR);
+ X(ANTITRANSPOSE, GR_BB, BR_BG);
+ X(ANTITRANSPOSE, BG_BR, RG_BB);
+
+ NONLINEAR(RGB);
+ NONLINEAR(R_G_B);
+ NONLINEAR(BGR);
+ NONLINEAR(B_G_R);
+ NONLINEAR(GBR);
+ NONLINEAR(G_B_R);
+ NONLINEAR(RBG);
+ NONLINEAR(R_B_G);
+ NONLINEAR(BRG);
+ NONLINEAR(B_R_G);
+ NONLINEAR(GRB);
+ NONLINEAR(G_R_B);
+ NONLINEARX(RR_GB);
+ NONLINEARX(GR_BR);
+ NONLINEARX(BG_RR);
+ NONLINEARX(RB_RG);
+ NONLINEARX(RR_BG);
+ NONLINEARX(BR_GR);
+ NONLINEARX(GB_RR);
+ NONLINEARX(RG_RB);
+ NONLINEARX(GG_RB);
+ NONLINEARX(RG_BG);
+ NONLINEARX(BR_GG);
+ NONLINEARX(GB_GR);
+ NONLINEARX(GG_BR);
+ NONLINEARX(BG_RG);
+ NONLINEARX(RB_GG);
+ NONLINEARX(GR_GB);
+ NONLINEARX(BB_RG);
+ NONLINEARX(RB_GB);
+ NONLINEARX(GR_BB);
+ NONLINEARX(BG_BR);
+ NONLINEARX(BB_GR);
+ NONLINEARX(GB_RB);
+ NONLINEARX(RG_BB);
+ NONLINEARX(BR_BG);
+
+ UNKNOWN(RGB);
+ UNKNOWN(R_G_B);
+ UNKNOWN(BGR);
+ UNKNOWN(B_G_R);
+ UNKNOWN(GBR);
+ UNKNOWN(G_B_R);
+ UNKNOWN(RBG);
+ UNKNOWN(R_B_G);
+ UNKNOWN(BRG);
+ UNKNOWN(B_R_G);
+ UNKNOWN(GRB);
+ UNKNOWN(G_R_B);
+ UNKNOWNX(RR_GB);
+ UNKNOWNX(GR_BR);
+ UNKNOWNX(BG_RR);
+ UNKNOWNX(RB_RG);
+ UNKNOWNX(RR_BG);
+ UNKNOWNX(BR_GR);
+ UNKNOWNX(GB_RR);
+ UNKNOWNX(RG_RB);
+ UNKNOWNX(GG_RB);
+ UNKNOWNX(RG_BG);
+ UNKNOWNX(BR_GG);
+ UNKNOWNX(GB_GR);
+ UNKNOWNX(GG_BR);
+ UNKNOWNX(BG_RG);
+ UNKNOWNX(RB_GG);
+ UNKNOWNX(GR_GB);
+ UNKNOWNX(BB_RG);
+ UNKNOWNX(RB_GB);
+ UNKNOWNX(GR_BB);
+ UNKNOWNX(BG_BR);
+ UNKNOWNX(BB_GR);
+ UNKNOWNX(GB_RB);
+ UNKNOWNX(RG_BB);
+ UNKNOWNX(BR_BG);
+
+ return 0;
+}
+
+int
+main(void)
+{
+ int xtrans, ytrans;
+
+ for (xtrans = -1; xtrans <= +1; xtrans++) {
+ for (ytrans = -1; ytrans <= +1; ytrans++) {
+ test(xtrans, ytrans, 1, 1, 1);
+ test(xtrans, ytrans, 1, 2, 1);
+ test(xtrans, ytrans, 1, 1, 2);
+ test(xtrans, ytrans, 1, 2, 2);
+ test(xtrans, ytrans, 2, 1, 1);
+ test(xtrans, ytrans, 2, 2, 2);
+ }
+ }
+
+ return 0;
+}
+
+
+#endif