Commit 7f93c977e7ce2c1c8f3ac39fc5e622440a7b3a35

Alexei Podtelezhnikov 2018-09-19T22:45:45

[pcf] Prepare to replace charmap implementation. * src/pcf/pcf.h (PCF_Face): Updated to include... (PCF_EncRec): ... this new structure to store charmap geometry. * src/pcf/pcfread.c (pcf_get_encodings): Store charmap geometry.

diff --git a/ChangeLog b/ChangeLog
index 00c9ba8..89ae802 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2018-09-19  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	[pcf] Prepare to replace charmap implementation.
+
+	* src/pcf/pcf.h (PCF_Face): Updated to include...
+	(PCF_EncRec): ... this new structure to store charmap geometry.
+
+	* src/pcf/pcfread.c (pcf_get_encodings): Store charmap geometry.
+
 2018-09-18  Alexei Podtelezhnikov  <apodtele@gmail.com>
 
 	Remove unused fields.
diff --git a/src/pcf/pcf.h b/src/pcf/pcf.h
index ee83023..8b94782 100644
--- a/src/pcf/pcf.h
+++ b/src/pcf/pcf.h
@@ -104,6 +104,19 @@ FT_BEGIN_HEADER
   } PCF_MetricRec, *PCF_Metric;
 
 
+  typedef struct  PCF_EncRec_
+  {
+    FT_UShort   firstCol;
+    FT_UShort   lastCol;
+    FT_UShort   firstRow;
+    FT_UShort   lastRow;
+    FT_UShort   defaultChar;
+
+    FT_UShort*  offset;  /* unused yet */
+
+  } PCF_EncRec, *PCF_Enc;
+
+
   typedef struct  PCF_AccelRec_
   {
     FT_Byte        noOverlap;
@@ -157,7 +170,7 @@ FT_BEGIN_HEADER
     FT_ULong       nencodings;
     PCF_Encoding   encodings;
 
-    FT_UShort      defaultChar;
+    PCF_EncRec     enc;
 
     FT_ULong       bitmapsFormat;
 
diff --git a/src/pcf/pcfread.c b/src/pcf/pcfread.c
index 3aa6c0b..d2f59f2 100644
--- a/src/pcf/pcfread.c
+++ b/src/pcf/pcfread.c
@@ -936,6 +936,40 @@ THE SOFTWARE.
    * This file uses X11 terminology for PCF data; an `encoding' in X11 speak
    * is the same as a character code in FreeType speak.
    */
+#define PCF_ENC_SIZE  10
+
+  static
+  const FT_Frame_Field  pcf_enc_header[] =
+  {
+#undef  FT_STRUCTURE
+#define FT_STRUCTURE  PCF_EncRec
+
+    FT_FRAME_START( PCF_ENC_SIZE ),
+      FT_FRAME_USHORT_LE( firstCol ),
+      FT_FRAME_USHORT_LE( lastCol ),
+      FT_FRAME_USHORT_LE( firstRow ),
+      FT_FRAME_USHORT_LE( lastRow ),
+      FT_FRAME_USHORT_LE( defaultChar ),
+    FT_FRAME_END
+  };
+
+
+  static
+  const FT_Frame_Field  pcf_enc_msb_header[] =
+  {
+#undef  FT_STRUCTURE
+#define FT_STRUCTURE  PCF_EncRec
+
+    FT_FRAME_START( PCF_ENC_SIZE ),
+      FT_FRAME_USHORT( firstCol ),
+      FT_FRAME_USHORT( lastCol ),
+      FT_FRAME_USHORT( firstRow ),
+      FT_FRAME_USHORT( lastRow ),
+      FT_FRAME_USHORT( defaultChar ),
+    FT_FRAME_END
+  };
+
+
   static FT_Error
   pcf_get_encodings( FT_Stream  stream,
                      PCF_Face   face )
@@ -943,8 +977,7 @@ THE SOFTWARE.
     FT_Error      error;
     FT_Memory     memory = FT_FACE( face )->memory;
     FT_ULong      format, size;
-    FT_UShort     firstCol, lastCol;
-    FT_UShort     firstRow, lastRow;
+    PCF_Enc       enc = &face->enc;
     FT_ULong      nencoding;
     FT_UShort     defaultCharRow, defaultCharCol;
     FT_UShort     encodingOffset, defaultCharEncodingOffset;
@@ -961,86 +994,73 @@ THE SOFTWARE.
                                     &format,
                                     &size );
     if ( error )
-      return error;
+      goto Bail;
 
-    error = FT_Stream_EnterFrame( stream, 14 );
-    if ( error )
-      return error;
+    if ( FT_READ_ULONG_LE( format ) )
+      goto Bail;
 
-    format = FT_GET_ULONG_LE();
+    FT_TRACE4(( "pcf_get_encodings:\n"
+                "  format: 0x%lX (%s)\n",
+                format,
+                PCF_BYTE_ORDER( format ) == MSBFirst ? "MSB" : "LSB" ));
+
+    if ( !PCF_FORMAT_MATCH( format, PCF_DEFAULT_FORMAT ) &&
+         !PCF_FORMAT_MATCH( format, PCF_BDF_ENCODINGS )  )
+      return FT_THROW( Invalid_File_Format );
 
-    /* X11's reference implementation uses the equivalent to  */
-    /* `FT_GET_SHORT' for `defaultChar', however this doesn't */
-    /* make sense for most encodings.                         */
     if ( PCF_BYTE_ORDER( format ) == MSBFirst )
     {
-      firstCol          = FT_GET_USHORT();
-      lastCol           = FT_GET_USHORT();
-      firstRow          = FT_GET_USHORT();
-      lastRow           = FT_GET_USHORT();
-      face->defaultChar = FT_GET_USHORT();
+      if ( FT_STREAM_READ_FIELDS( pcf_enc_msb_header, enc ) )
+        goto Bail;
     }
     else
     {
-      firstCol          = FT_GET_USHORT_LE();
-      lastCol           = FT_GET_USHORT_LE();
-      firstRow          = FT_GET_USHORT_LE();
-      lastRow           = FT_GET_USHORT_LE();
-      face->defaultChar = FT_GET_USHORT_LE();
+      if ( FT_STREAM_READ_FIELDS( pcf_enc_header, enc ) )
+        goto Bail;
     }
 
-    FT_Stream_ExitFrame( stream );
-
-    FT_TRACE4(( "pcf_get_encodings:\n"
-                "  format: 0x%lX (%s)\n",
-                format,
-                PCF_BYTE_ORDER( format ) == MSBFirst ? "MSB" : "LSB" ));
-
-    if ( !PCF_FORMAT_MATCH( format, PCF_DEFAULT_FORMAT ) )
-      return FT_THROW( Invalid_File_Format );
-
     FT_TRACE4(( "  firstCol 0x%X, lastCol 0x%X\n"
                 "  firstRow 0x%X, lastRow 0x%X\n"
                 "  defaultChar 0x%X\n",
-                firstCol, lastCol,
-                firstRow, lastRow,
-                face->defaultChar ));
+                enc->firstCol, enc->lastCol,
+                enc->firstRow, enc->lastRow,
+                enc->defaultChar ));
 
     /* sanity checks; we limit numbers of rows and columns to 256 */
-    if ( firstCol > lastCol ||
-         lastCol  > 0xFF    ||
-         firstRow > lastRow ||
-         lastRow  > 0xFF    )
+    if ( enc->firstCol > enc->lastCol ||
+         enc->lastCol  > 0xFF         ||
+         enc->firstRow > enc->lastRow ||
+         enc->lastRow  > 0xFF         )
       return FT_THROW( Invalid_Table );
 
-    nencoding = (FT_ULong)( lastCol - firstCol + 1 ) *
-                (FT_ULong)( lastRow - firstRow + 1 );
+    nencoding = (FT_ULong)( enc->lastCol - enc->firstCol + 1 ) *
+                (FT_ULong)( enc->lastRow - enc->firstRow + 1 );
 
     if ( FT_NEW_ARRAY( encoding, nencoding ) )
-      return error;
+      goto Bail;
 
     error = FT_Stream_EnterFrame( stream, 2 * nencoding );
     if ( error )
-      goto Bail;
+      goto Exit;
 
     FT_TRACE5(( "\n" ));
 
-    defaultCharRow = face->defaultChar >> 8;
-    defaultCharCol = face->defaultChar & 0xFF;
+    defaultCharRow = enc->defaultChar >> 8;
+    defaultCharCol = enc->defaultChar & 0xFF;
 
     /* validate default character */
-    if ( defaultCharRow < firstRow ||
-         defaultCharRow > lastRow  ||
-         defaultCharCol < firstCol ||
-         defaultCharCol > lastCol  )
+    if ( defaultCharRow < enc->firstRow ||
+         defaultCharRow > enc->lastRow  ||
+         defaultCharCol < enc->firstCol ||
+         defaultCharCol > enc->lastCol  )
     {
-      face->defaultChar = firstRow * 256U + firstCol;
+      enc->defaultChar = enc->firstRow * 256U + enc->firstCol;
       FT_TRACE0(( "pcf_get_encodings:"
                   " Invalid default character set to %u\n",
-                  face->defaultChar ));
+                  enc->defaultChar ));
 
-      defaultCharRow = face->defaultChar >> 8;
-      defaultCharCol = face->defaultChar & 0xFF;
+      defaultCharRow = enc->firstRow;
+      defaultCharCol = enc->firstCol;
     }
 
     /* FreeType mandates that glyph index 0 is the `undefined glyph',  */
@@ -1051,8 +1071,9 @@ THE SOFTWARE.
     /* `stream->cursor' still points at the beginning of the frame; */
     /* we can thus easily get the offset to the default character   */
     pos = stream->cursor +
-            2 * ( ( defaultCharRow - firstRow ) * ( lastCol - firstCol + 1 ) +
-                  defaultCharCol - firstCol );
+            2 * ( ( defaultCharRow - enc->firstRow ) *
+                  ( enc->lastCol - enc->firstCol + 1 ) +
+                    defaultCharCol - enc->firstCol       );
 
     if ( PCF_BYTE_ORDER( format ) == MSBFirst )
       defaultCharEncodingOffset = FT_PEEK_USHORT( pos );
@@ -1078,9 +1099,9 @@ THE SOFTWARE.
     }
 
     k = 0;
-    for ( i = firstRow; i <= lastRow; i++ )
+    for ( i = enc->firstRow; i <= enc->lastRow; i++ )
     {
-      for ( j = firstCol; j <= lastCol; j++ )
+      for ( j = enc->firstCol; j <= enc->lastCol; j++ )
       {
         /* X11's reference implementation uses the equivalent to  */
         /* `FT_GET_SHORT', however PCF fonts with more than 32768 */
@@ -1111,15 +1132,17 @@ THE SOFTWARE.
     FT_Stream_ExitFrame( stream );
 
     if ( FT_RENEW_ARRAY( encoding, nencoding, k ) )
-      goto Bail;
+      goto Exit;
 
     face->nencodings = k;
     face->encodings  = encoding;
 
     return error;
 
-  Bail:
+  Exit:
     FT_FREE( encoding );
+
+  Bail:
     return error;
   }