aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMattias Andrée <maandree@kth.se>2022-07-22 17:12:09 +0200
committerMattias Andrée <maandree@kth.se>2022-07-22 17:13:29 +0200
commit84c0c1ff3f9666adb632b8c87b4c2f7c54f5d823 (patch)
tree5a275405ffffa4256894e0695f99cd0c71d5d312
parentCalculate logical subpixel order from transformation (diff)
downloadlibfonts-84c0c1ff3f9666adb632b8c87b4c2f7c54f5d823.tar.gz
libfonts-84c0c1ff3f9666adb632b8c87b4c2f7c54f5d823.tar.bz2
libfonts-84c0c1ff3f9666adb632b8c87b4c2f7c54f5d823.tar.xz
Fix EDID reading in libfonts_get_output_dpi and make it use the output transformation
Signed-off-by: Mattias Andrée <maandree@kth.se>
-rw-r--r--Makefile1
-rw-r--r--common.h31
-rw-r--r--libfonts.h51
-rw-r--r--libfonts_calculate_subpixel_order.c24
-rw-r--r--libfonts_decode_font_description.c9
-rw-r--r--libfonts_encode_font_description.c5
-rw-r--r--libfonts_get_output_dpi.c50
7 files changed, 98 insertions, 73 deletions
diff --git a/Makefile b/Makefile
index 57da740..97a3499 100644
--- a/Makefile
+++ b/Makefile
@@ -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;
+}
diff --git a/libfonts.h b/libfonts.h
index 82a5756..2c9b94d 100644
--- a/libfonts.h
+++ b/libfonts.h
@@ -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;
}