Commit a4c2a31138221165db524ca02f28f0b54698b305

Werner Lemberg 2016-08-22T19:32:34

[truetype] Fix `MPS' instruction. According to Greg Hitchcock, MPS in DWrite really returns the point size. * src/truetype/ttobjs.h (TT_SizeRec): Add `point_size' member. * src/truetype/ttdriver.c (tt_size_request): Set `point_size'. * src/truetype/ttinterp.h (TT_ExecContextRec): Add `pointSize' member. * src/truetype/ttinterp.c (TT_Load_Context): Updated. (Ins_MPS): Fix instruction.

diff --git a/ChangeLog b/ChangeLog
index 8aaa78e..cfb9ae5 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,22 @@
 2016-08-16  Werner Lemberg  <wl@gnu.org>
 
+	[truetype] Fix `MPS' instruction.
+
+	According to Greg Hitchcock, MPS in DWrite really returns the point
+	size.
+
+	* src/truetype/ttobjs.h (TT_SizeRec): Add `point_size' member.
+
+	* src/truetype/ttdriver.c (tt_size_request): Set `point_size'.
+
+	* src/truetype/ttinterp.h (TT_ExecContextRec): Add `pointSize'
+	member.
+
+	* src/truetype/ttinterp.c (TT_Load_Context): Updated.
+	(Ins_MPS): Fix instruction.
+
+2016-08-16  Werner Lemberg  <wl@gnu.org>
+
 	[lzw] Optimize last commit.
 
 	* src/lzw/ftzopen.c (ft_lzwstate_get_code): Move check into
diff --git a/src/truetype/ttdriver.c b/src/truetype/ttdriver.c
index 2659b9c..6520c93 100644
--- a/src/truetype/ttdriver.c
+++ b/src/truetype/ttdriver.c
@@ -339,6 +339,25 @@
     {
       error = tt_size_reset( ttsize );
       ttsize->root.metrics = ttsize->metrics;
+
+#ifdef TT_USE_BYTECODE_INTERPRETER
+      /* for the `MPS' bytecode instruction we need the point size */
+      {
+        FT_UInt  resolution = ttsize->metrics.x_ppem > ttsize->metrics.y_ppem
+                                ? req->horiResolution
+                                : req->vertResolution;
+
+
+        /* if we don't have a resolution value, assume 72dpi */
+        if ( req->type == FT_SIZE_REQUEST_TYPE_SCALES ||
+             !resolution                              )
+          resolution = 72;
+
+        ttsize->point_size = FT_MulDiv( ttsize->ttmetrics.ppem,
+                                        64 * 72,
+                                        resolution );
+      }
+#endif
     }
 
     return error;
diff --git a/src/truetype/ttinterp.c b/src/truetype/ttinterp.c
index f23a3dd..caeb6ca 100644
--- a/src/truetype/ttinterp.c
+++ b/src/truetype/ttinterp.c
@@ -397,6 +397,7 @@
       exec->maxIDefs   = size->max_instruction_defs;
       exec->FDefs      = size->function_defs;
       exec->IDefs      = size->instruction_defs;
+      exec->pointSize  = size->point_size;
       exec->tt_metrics = size->ttmetrics;
       exec->metrics    = size->metrics;
 
@@ -2580,13 +2581,20 @@
   Ins_MPS( TT_ExecContext  exc,
            FT_Long*        args )
   {
-    /* Note: The point size should be irrelevant in a given font program; */
-    /*       we thus decide to return only the PPEM value.                */
-#if 0
-    args[0] = exc->metrics.pointSize;
-#else
-    args[0] = exc->func_cur_ppem( exc );
-#endif
+    if ( NO_SUBPIXEL_HINTING )
+    {
+      /* Microsoft's GDI bytecode interpreter always returns value 12; */
+      /* we return the current PPEM value instead.                     */
+      args[0] = exc->func_cur_ppem( exc );
+    }
+    else
+    {
+      /* A possible practical application of the MPS instruction is to   */
+      /* implement optical scaling and similar features, which should be */
+      /* based on perceptual attributes, thus independent of the         */
+      /* resolution.                                                     */
+      args[0] = exc->pointSize;
+    }
   }
 
 
diff --git a/src/truetype/ttinterp.h b/src/truetype/ttinterp.h
index df7ce51..53f0944 100644
--- a/src/truetype/ttinterp.h
+++ b/src/truetype/ttinterp.h
@@ -170,6 +170,7 @@ FT_BEGIN_HEADER
                        pts,
                        twilight;
 
+    FT_Long            pointSize;  /* in 26.6 format */
     FT_Size_Metrics    metrics;
     TT_Size_Metrics    tt_metrics; /* size metrics */
 
diff --git a/src/truetype/ttobjs.h b/src/truetype/ttobjs.h
index ed61a7d..98ad383 100644
--- a/src/truetype/ttobjs.h
+++ b/src/truetype/ttobjs.h
@@ -286,6 +286,8 @@ FT_BEGIN_HEADER
 
 #ifdef TT_USE_BYTECODE_INTERPRETER
 
+    FT_Long            point_size;    /* for the `MPS' bytecode instruction */
+
     FT_UInt            num_function_defs; /* number of function definitions */
     FT_UInt            max_function_defs;
     TT_DefArray        function_defs;     /* table of function definitions  */