Author Topic: PJSR wish list: distribution fonts  (Read 4461 times)

Offline mschuster

  • PTeam Member
  • PixInsight Jedi
  • *****
  • Posts: 1087
PJSR wish list: distribution fonts
« on: 2015 October 10 16:58:09 »
A new Font core object API that gives a list (array) of available distribution font names.

Names should include complete variant specification, possibly in the form of the .ttf file name, such as "mplus-1p-light".

A new Font constructor that accepts the name of a distribution font.

I would like to use cross-platform, distribution fonts in script generated graphics.

Thanks,
Mike

Offline Juan Conejero

  • PTeam Member
  • PixInsight Jedi Grand Master
  • ********
  • Posts: 7111
    • http://pixinsight.com/
Re: PJSR wish list: distribution fonts
« Reply #1 on: 2015 October 30 11:41:03 »
Hi Mike,

All what you ask for is not feasible in a portable way. However, the new version 1.8.4.1187 of PixInsight comes with the following new static methods of the Font core object:

   Array Font.families( [int writingSystem] )

Returns an array of String objects with the names of all installed fonts on the host system. You can specify a writing system to filter out unwanted languages, such as WritingSystem_Latin or WritingSystem_Symbol, etc. There is a new pjsr/WritingSystem.jsh standard header.

   Boolean Font.isFixedPitchFont( String family )

Returns true if the specified font is installed and is a fixed pitch font; false otherwise.

   Boolean Font.isScalableFont( String family )

Returns true if the specified font is installed and is a scalable font; false otherwise.

The directory where all core distribution fonts are stored on the host filesystem can be retrieved as follows:

   let coreFontsDir = getEnvironmentVariable( "PXI_RSCDIR" ) + "/fonts";

All core fonts are available on subdirectories of the coreFontsDir directory obtained as above. You can use the following utility object (extracted from my code maintenance scripts) to find all fonts recursively:

Code: [Select]
/*
 * FileList
 *
 * Recursively search a directory tree for all existing files with the
 * specified file extensions.
 */
function FileList( dirPath, extensions, verbose )
{
   /*
    * Regenerate this file list for the specified base directory and file
    * extensions.
    */
   this.regenerate = function( dirPath, extensions, verbose )
   {
      // The base directory is the root of our source tree.
      this.baseDirectory = File.fullPath( dirPath );
      if ( this.baseDirectory.length == 0 )
         throw new Error( "No base directory has been specified." );
      if ( this.baseDirectory[this.baseDirectory.length-1] == '/' )
         this.baseDirectory.slice( this.baseDirectory.length-1, -1 );

      if ( verbose )
      {
         console.writeln( "<end><cbr><br>==> Finding files from base directory:" );
         console.writeln( this.baseDirectory );
      }

      // Find all files with the required extensions in our base tree recursively.
      this.files = new Array;
      for ( var i in extensions )
         this.files = this.files.concat( searchDirectory( this.baseDirectory + "/*" + extensions[i], true/*recursive*/ ) );

      // Delete baseDirectory + separator from the beginning of all file paths.
      var d = this.baseDirectory + '/';
      for ( var i in this.files )
      {
         if ( this.files[i].indexOf( d ) != 0 )
            throw new Error( "<* Panic *> Inconsistent directory search!" );
         this.files[i] = this.files[i].slice( d.length, this.files[i].length );
      }

      // Sort all file paths to ensure that all files in a given directory are
      // contiguous in the files array.
      this.files.sort(); // ensure next sort is stable
      this.files.sort( new Function( "a", "b", "{ var d1 = File.extractDirectory( a ); " +
                                                 "var d2 = File.extractDirectory( b ); " +
                                                 "return (d1 < d2) ? -1 : ((d1 > d2) ? +1 : 0); }" ) );

      // Generate an index for fast file retrieval.
      // N.B. For file indexing, we assume that all file names are unique
      //      throughout the entire directory tree.
      function IndexItem( filePath, index )
      {
         this.fileName = File.extractName( filePath ) + File.extractExtension( filePath );
         this.index = index;
      }
      this.index = new Array;
      for ( var i in this.files )
         this.index.push( new IndexItem( this.files[i], i ) );
      this.index.sort( new Function( "a", "b", "{ return (a.fileName < b.fileName) ? -1 : ((a.fileName > b.fileName) ? +1 : 0); }" ) );
   };

   /*
    * Fast file search routine. Returns the index in the this.files array for
    * the specified file name, or -1 if not found.
    */
   this.searchFileName = function( fileName )
   {
      for ( var n = this.index.length, i = 0, j = n; ; )
      {
         if ( j <= i )
            return (i < n && fileName == this.index[i].fileName) ? this.index[i].index : -1;
         var m = (i + j) >> 1;
         if ( this.index[m].fileName < fileName )
            i = m+1;
         else
            j = m;
      }
   };

   this.baseDirectory = "";
   this.files = new Array;
   this.index = new Array;

   if ( dirPath != undefined )
      this.regenerate( dirPath, extensions, verbose );

   if ( verbose )
      for ( var i in this.files )
         console.writeln( this.files[i] );
}

Then you can use it as follows:

   let coreFontsDir = getEnvironmentVariable( "PXI_RSCDIR" ) + "/fonts";
   let coreFontFiles = new FileList( coreFontsDir, [".ttf", ".otf"], true/*verbose*/ );
   ...


Hope this helps.
Juan Conejero
PixInsight Development Team
http://pixinsight.com/

Offline mschuster

  • PTeam Member
  • PixInsight Jedi
  • *****
  • Posts: 1087
Re: PJSR wish list: distribution fonts
« Reply #2 on: 2015 October 30 15:30:09 »
Thank you so much Juan for this and the displayFunction fix.

Mike