[gtk+/wip/otte/shader: 29/52] gskslprinter: Deal with non-normal floating points



commit c3759c43f4945c7b1fa9ba25e3756321a8906470
Author: Benjamin Otte <otte redhat com>
Date:   Wed Oct 4 03:34:55 2017 +0200

    gskslprinter: Deal with non-normal floating points
    
    Instead of NaN, print "(0.0 / 0.0)" and instead of INF, print "(1.0 /
    0.0)".
    
    Both of that is not spec-conformant, but the best we can do if we
    encounter constant expressions that evaluate to these numbers.

 gsk/gskslprinter.c        |   43 +++++++++++++++++++++++++++++++++++++------
 gsk/gskslprinterprivate.h |    5 +++--
 gsk/gsksltype.c           |    5 ++---
 3 files changed, 42 insertions(+), 11 deletions(-)
---
diff --git a/gsk/gskslprinter.c b/gsk/gskslprinter.c
index 901367d..2831fc9 100644
--- a/gsk/gskslprinter.c
+++ b/gsk/gskslprinter.c
@@ -127,16 +127,47 @@ gsk_sl_printer_append_uint (GskSlPrinter *printer,
 }
 
 void
+gsk_sl_printer_append_float (GskSlPrinter *printer,
+                             float         f)
+{
+  char buf[G_ASCII_DTOSTR_BUF_SIZE];
+
+  if (isnanf (f))
+    g_string_append (printer->string, "(0.0 / 0.0)");
+  else if (isinff (f) > 0)
+    g_string_append (printer->string, "(1.0 / 0.0)");
+  else if (isinff (f) < 0)
+    g_string_append (printer->string, "(-1.0 / 0.0)");
+  else
+    {
+      g_ascii_dtostr (buf, G_ASCII_DTOSTR_BUF_SIZE, f);
+      g_string_append (printer->string, buf);
+      if (strchr (buf, '.') == NULL)
+        g_string_append (printer->string, ".0");
+    }
+}
+
+void
 gsk_sl_printer_append_double (GskSlPrinter *printer,
-                              double        d,
-                              gboolean      with_dot)
+                              double        d)
 {
   char buf[G_ASCII_DTOSTR_BUF_SIZE];
 
-  g_ascii_dtostr (buf, G_ASCII_DTOSTR_BUF_SIZE, d);
-  g_string_append (printer->string, buf);
-  if (with_dot && strchr (buf, '.') == NULL)
-    g_string_append (printer->string, ".0");
+  if (isnan (d))
+    g_string_append (printer->string, "(0.0lf / 0.0lf)");
+  else if (isinf (d) > 0)
+    g_string_append (printer->string, "(1.0lf / 0.0lf)");
+  else if (isinf (d) < 0)
+    g_string_append (printer->string, "(-1.0lf / 0.0lf)");
+  else
+    {
+      g_ascii_dtostr (buf, G_ASCII_DTOSTR_BUF_SIZE, d);
+      g_string_append (printer->string, buf);
+      if (strchr (buf, '.') == NULL)
+        g_string_append (printer->string, ".0lf");
+      else
+        g_string_append (printer->string, "lf");
+    }
 }
 
 void
diff --git a/gsk/gskslprinterprivate.h b/gsk/gskslprinterprivate.h
index 83be55d..5d1e37b 100644
--- a/gsk/gskslprinterprivate.h
+++ b/gsk/gskslprinterprivate.h
@@ -43,9 +43,10 @@ void                    gsk_sl_printer_append_int               (GskSlPrinter
                                                                  int                    i);
 void                    gsk_sl_printer_append_uint              (GskSlPrinter          *printer,
                                                                  guint                  u);
+void                    gsk_sl_printer_append_float             (GskSlPrinter          *printer,
+                                                                 float                  f);
 void                    gsk_sl_printer_append_double            (GskSlPrinter          *printer,
-                                                                 double                 d,
-                                                                 gboolean               with_dot);
+                                                                 double                 d);
 void                    gsk_sl_printer_newline                  (GskSlPrinter          *printer);
 
 G_END_DECLS
diff --git a/gsk/gsksltype.c b/gsk/gsksltype.c
index 677d4f5..a0b320e 100644
--- a/gsk/gsksltype.c
+++ b/gsk/gsksltype.c
@@ -95,7 +95,7 @@ print_float (GskSlPrinter  *printer,
 {
   const gfloat *f = value;
       
-  gsk_sl_printer_append_double (printer, *f, TRUE);
+  gsk_sl_printer_append_float (printer, *f);
 }
 
 static guint32
@@ -122,8 +122,7 @@ print_double (GskSlPrinter  *printer,
 {
   const gdouble *d = value;
       
-  gsk_sl_printer_append_double (printer, *d, TRUE);
-  gsk_sl_printer_append (printer, "lf");
+  gsk_sl_printer_append_double (printer, *d);
 }
 
 static guint32


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]