diff options
-rw-r--r-- | Makefile | 1 | ||||
-rw-r--r-- | common.h | 31 | ||||
-rw-r--r-- | libfonts.h | 51 | ||||
-rw-r--r-- | libfonts_calculate_subpixel_order.c | 24 | ||||
-rw-r--r-- | libfonts_decode_font_description.c | 9 | ||||
-rw-r--r-- | libfonts_encode_font_description.c | 5 | ||||
-rw-r--r-- | libfonts_get_output_dpi.c | 50 |
7 files changed, 98 insertions, 73 deletions
@@ -23,6 +23,7 @@ OBJ =\ libfonts_get_output_dpi.o HDR =\ + common.h\ libfonts.h LOBJ = $(OBJ:.o=.lo) diff --git a/common.h b/common.h new file mode 100644 index 0000000..f39090e --- /dev/null +++ b/common.h @@ -0,0 +1,31 @@ +/* See LICENSE file for copyright and license details. */ +#include "libfonts.h" +#include <ctype.h> +#include <errno.h> +#include <inttypes.h> +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <strings.h> + +#define DOUBLE_TOLERANCE 0.000001 + + +static inline void +transform(double *x_out, double *y_out, double x, double y, const struct libfonts_transformation *transformation) +{ + double a = transformation->m[0][0], b = transformation->m[0][1], c = transformation->m[0][2]; + double d = transformation->m[1][0], e = transformation->m[1][1], f = transformation->m[1][2]; + double g = transformation->m[2][0], h = transformation->m[2][1], i = transformation->m[2][2]; + double w = g*x + h*y + i; + *x_out = (a*x + b*y + c) / w; + *y_out = (d*x + e*y + f) / w; +} + + +static inline int +eq(double a, double b) +{ + return b - DOUBLE_TOLERANCE <= a && a <= b + DOUBLE_TOLERANCE; +} @@ -42,8 +42,8 @@ enum libfonts_subpixel_order { */ LIBFONTS_SUBPIXEL_ORDER_OTHER, - LIBFONTS_SUBPIXEL_ORDER_RGB, - LIBFONTS_SUBPIXEL_ORDER_R_G_B, /* vertically stacked horizontal stripes */ + LIBFONTS_SUBPIXEL_ORDER_RGB, /* horizontal stacked vertically stripes, red to the left, blue to the right */ + LIBFONTS_SUBPIXEL_ORDER_R_G_B, /* vertically stacked horizontal stripes, red at the top, blue at the bottom */ LIBFONTS_SUBPIXEL_ORDER_BGR, LIBFONTS_SUBPIXEL_ORDER_B_G_R, @@ -225,24 +225,34 @@ struct libfonts_output { int32_t output_y; /** - * The output's width, in pixels + * The output's width, in pixels, on the screen */ uint32_t output_width; /** - * The output's height, in pixels + * The output's height, in pixels, on the screen */ uint32_t output_height; /** + * The output's width, in pixels, before transformation is applied + */ + uint32_t unrotated_output_width; + + /** + * The output's height, in pixels, before transformation is applied + */ + uint32_t unrotated_output_height; + + /** * The index of the screen the output belongs to */ int output_screen; /** - * The rotation of the output + * Transformation that is applied to the output */ - enum libfonts_orientation physical_screen_orientation; + struct libfonts_transformation output_transformation; /** * The output's subpixel order, disregarding applied rotation @@ -251,19 +261,23 @@ struct libfonts_output { /** * The output's horizontal pixel density (pixels per inch), - * zero if not applicable or unknown + * zero if not applicable or unknown, after transformation + * is applied * - * This `.output_width` divided by the output's physical - * width in inches + * This `.unrotated_output_width` divided by the output's + * physical width in inches, with `.output_transformation` + * than applied */ double dpi_x; /** * The output's vertical pixel density (pixels per inch), - * zero if not applicable or unknown + * zero if not applicable or unknown, after transformation + * is applied * - * This `.output_height` divided by the output's physical - * height in inches + * This `.unrotated_output_height` divided by the output's + * physical height in inches, with `.output_transformation` + * than applied */ double dpi_y; @@ -489,15 +503,20 @@ int libfonts_get_output_rendering_settings(struct libfonts_rendering_settings *, * The output pixel density is only approximate because * the EDID has limited dimension resolution * - * @param output Output device information, `.output_width` and `.output_height` - * must already be set; this function will set `.dpi_x` and `.dpi_y` + * @param output Output device information, `.unrotated_output_width`, + * `.unrotated_output_height`, and `.output_transformation` must + * already be set; this function will set `.dpi_x` and `.dpi_y` * (both will be set to zero if the function returns zero) - * @param edid The output device's EDID, in hexadecimal representation + * @param edid The output device's EDID, in hexadecimal representation; + * if `NULL`, `output->unrotated_output_width` and + * `output->unrotated_output_height` need not be set, instead + * `output->dpi_x` and `output->dpi_y` must be set to the + * pixel density before the `output->output_transformation` + * is applied * @return 1 if a pixel density was calculated, * 0 otherwise (projector or unsupported EDID) */ int libfonts_get_output_dpi(struct libfonts_output *, const char *); -/* TODO should take transformation into account */ /** * Calculate the subpixel order on an output device after diff --git a/libfonts_calculate_subpixel_order.c b/libfonts_calculate_subpixel_order.c index 746cece..493b9e7 100644 --- a/libfonts_calculate_subpixel_order.c +++ b/libfonts_calculate_subpixel_order.c @@ -1,27 +1,5 @@ /* See LICENSE file for copyright and license details. */ -#include "libfonts.h" - - -#define TOLERANCE 0.000001 - - -static void -transform(double *x_out, double *y_out, double x, double y, const struct libfonts_transformation *transformation) -{ - double a = transformation->m[0][0], b = transformation->m[0][1], c = transformation->m[0][2]; - double d = transformation->m[1][0], e = transformation->m[1][1], f = transformation->m[1][2]; - double g = transformation->m[2][0], h = transformation->m[2][1], i = transformation->m[2][2]; - double w = g*x + h*y + i; - *x_out = (a*x + b*y + c) / w; - *y_out = (d*x + e*y + f) / w; -} - - -static int -eq(double a, double b) -{ - return b - TOLERANCE <= a && a <= b + TOLERANCE; -} +#include "common.h" enum libfonts_subpixel_order diff --git a/libfonts_decode_font_description.c b/libfonts_decode_font_description.c index 83cf5c2..7a8591d 100644 --- a/libfonts_decode_font_description.c +++ b/libfonts_decode_font_description.c @@ -1,12 +1,5 @@ /* See LICENSE file for copyright and license details. */ -#include "libfonts.h" -#include <ctype.h> -#include <errno.h> -#include <inttypes.h> -#include <stdint.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> +#include "common.h" #define LIST_FIELDS_EXCEPT_FINAL(X)\ X(foundry)\ diff --git a/libfonts_encode_font_description.c b/libfonts_encode_font_description.c index 8e0d87a..b594754 100644 --- a/libfonts_encode_font_description.c +++ b/libfonts_encode_font_description.c @@ -1,8 +1,5 @@ /* See LICENSE file for copyright and license details. */ -#include "libfonts.h" -#include <ctype.h> -#include <errno.h> -#include <string.h> +#include "common.h" #define LIST_FIELDS(X)\ X(foundry)\ diff --git a/libfonts_get_output_dpi.c b/libfonts_get_output_dpi.c index 259702a..8e698e2 100644 --- a/libfonts_get_output_dpi.c +++ b/libfonts_get_output_dpi.c @@ -1,8 +1,5 @@ /* See LICENSE file for copyright and license details. */ -#include "libfonts.h" -#include <ctype.h> -#include <string.h> -#include <strings.h> +#include "common.h" int @@ -10,31 +7,40 @@ libfonts_get_output_dpi(struct libfonts_output *output, const char *edid) { int width, height; char width1, width2, height1, height2; + double x[2], y[2]; - output->dpi_x = 0; - output->dpi_y = 0; + if (edid) { + output->dpi_x = 0; + output->dpi_y = 0; - if (strncasecmp(edid, "00""FF""FF""FF""FF""FF""FF""00", 2 * 8) || strlen(edid) < 256) - return 0; + if (strncasecmp(edid, "00""FF""FF""FF""FF""FF""FF""00", 2 * 8) || strlen(edid) < 256) + return 0; - width1 = edid[21 * 2 + 0]; - width2 = edid[21 * 2 + 0]; - height1 = edid[22 * 2 + 0]; - height2 = edid[22 * 2 + 0]; + width1 = edid[21 * 2 + 0]; + width2 = edid[21 * 2 + 1]; + height1 = edid[22 * 2 + 0]; + height2 = edid[22 * 2 + 1]; - if (!isxdigit(width1) || !isxdigit(width2) || !isxdigit(height1) || !isxdigit(height2)) - return 0; + if (!isxdigit(width1) || !isxdigit(width2) || !isxdigit(height1) || !isxdigit(height2)) + return 0; - width = ((width1 & 15) + (width1 > '9' ? 9 : 0)) << 4; - width |= (width2 & 15) + (width2 > '9' ? 9 : 0); - height = ((height1 & 15) + (height1 > '9' ? 9 : 0)) << 4; - height |= (height2 & 15) + (height2 > '9' ? 9 : 0); + width = ((width1 & 15) + (width1 > '9' ? 9 : 0)) << 4; + width |= (width2 & 15) + (width2 > '9' ? 9 : 0); + height = ((height1 & 15) + (height1 > '9' ? 9 : 0)) << 4; + height |= (height2 & 15) + (height2 > '9' ? 9 : 0); - if (!width || !height) - return 0; + if (!width || !height) + return 0; - output->dpi_x = (double)output->output_width / (double)width * 2.54; - output->dpi_y = (double)output->output_height / (double)height * 2.54; + output->dpi_x = (double)output->unrotated_output_width / (double)width * 2.54; + output->dpi_y = (double)output->unrotated_output_height / (double)height * 2.54; + } + + transform(&x[0], &y[0], 0, 0, &output->output_transformation); + transform(&x[1], &y[1], output->dpi_x, output->dpi_y, &output->output_transformation); + + output->dpi_x = x[1] > x[0] ? x[1] - x[0] : x[0] - x[1]; + output->dpi_y = y[1] > y[0] ? y[1] - y[0] : y[0] - y[1]; return 1; } |