This is PreFontConverter.m in view mode; [Download] [Up]
/***********************************************************************
Controller class for Convert FONT which converts Mac fonts to NeXT fonts.
Copyright (C) 1993 David John Burrowes
This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 1, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
The author, David John Burrowes, can be reached at:
davidjohn@kira.net.netcom.com
David John Burrowes
1926 Ivy #10
San Mateo, CA 94403-1367
***********************************************************************/
#import "PreFontConverter.h"
#import "FontConverter.h"
#import "PSFile.h"
#import "TextFile.h"
#import <appkit/Cell.h> // for menu enabling.
#import <appkit/Matrix.h>
#import <stdio.h>
#import <libc.h> // for mkdir and rmdir
#import <string.h> // for strrchr
#import <errno.h> // 93.01.24 for errno
@implementation PreFontConverter
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Routine: init
// Parameters: none
// Returns: self
// Stores: none
// Description:
// This overrides the defalut init method. The purpose of this overriding
// is to give ourselves a chance to set up some internal variables which are used
// later on, and allocate the converter instance.
// Bugs:
// History
// 93.03.14 Added code for encoding vector choice
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- init
{
static NXDefaultsVector theDefaults =
{
{USENSENCODING, "YES"},
};
[super init];
ConversionString = "Converting Mac FONT to Type 3 PS font";
SourcePrompt = "FONT file:";
DestPrompt = "Type 3 file:";
DestExtension = ".font";
DefaultsOwner = "ConvertFONT";
NXRegisterDefaults(DefaultsOwner, theDefaults);
UseNSEncoding = [self GetBoolPref: USENSENCODING];
converterInst = [[FontConverter alloc] init];
return self;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Routine: free
// Parameters: none
// Returns: a null instance
// Stores: none
// Description:
// This simply free's the converter instance, which we allocated in the init.
// Bugs:
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- free
{
if (converterInst != NullInstance)
[converterInst free];
[super free];
return NullInstance;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Routine: displayPreferences:
// Parameters: the object that called us
// Returns: self
// Stores: none
// This is called whenever we need to bring the preferences panel onto the screen.
// Using the value in our preferences variable, we set the button in
// the preferences panel to reflect the current value, and then shows the panel.
// Bugs:
// As pointed out elsewhere, we don't really need to do this after the first time,
// since the buttons keep their own state. So this paradigm needs revising!!
// History
// 93.03.14 Created
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-displayPreferences: target
{
//
// Get the default preference values, and compare judge what buttons to
// highlight for the user.
//
if (UseNSEncoding == YES)
[EncodingButton selectCellWithTag: 0];
else
[EncodingButton selectCellWithTag: 1];
//
// Display the panel for the user.
//
[prefPanel makeKeyAndOrderFront:self];
return self;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Routine: ChangeEncodingVector:
// Parameters: the object that called us
// Returns: self;
// Description:
// This method gets called whenever the user clicks on a button to change
// the setting of whether to use the NS or the Mac encoding. If the button they
// clicked on had a key of '1', then we will use NS, otherwise we don't.
// History
// 93.03.14 Created
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-ChangeEncodingVector: sender
{
if ( [[sender selectedCell] tag] == 0)
UseNSEncoding = YES;
else
UseNSEncoding = NO;
[self SetBoolPref: USENSENCODING To: UseNSEncoding];
return self;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Routine: openDestFile
// Parameters: the path to the file to be opened
// Returns: the opened file object (or junk if error is TERMINALERROR()
// Stores: errors
// Description:
// This is used to open the destination file object (a PS file). This is needed so
// that our superclass, when it is doing some of the work that we don' want to,
// will open an instance of the right class.
// Bugs:
// History:
// 93.01.10 djb Added last minute name processing. Specifically, give the font converter
// the full name with spaces, and other illegal characters. then, expanded
// original 'replace spaces with _'s' with 'remove all delimiters and other
// evil characters'
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- openDestFile: (CString) theFile
{
CString pathname;
CString theDir;
CString filename;
CString location;
Instance fontFile = NullInstance;
PositiveInteger index;
PositiveInteger destIndex;
Integer result;
CString buffer;
[self ResetResults];
//
// Build some names needed. If theFile is: /foo/bar/ginger.font then this builds:
// filename: ginger
// theDir: /foo/bar/
// And then we create the files
// $theDir/$filename.font
// $theDir/$filename.font/$filename
// $theDir/$filename.font/$filename.afm
//
// First, obtain the directory name. (nuke everything after the final /.
//
theDir = NewCString(strlen(theFile)); // max possible size for the directory name
strcpy (theDir, theFile);
location = strrchr(theDir, '/');
location[0] = EndOfCString;
//
// Now, build the base filename, find the last /, and copy all the rest over, and then
// find the last period, and put a terminator there
//
filename = NewCString(strlen(theFile)); // max possible size for file basename =)
location = strrchr(theFile, '/');
strcpy (filename, &(location[1]));
location = strrchr(filename, '.');
location[0] = NullCharacter;
//
// Let the actual font converter know what the actual font name should be, so it
// can store it in the afm file. We could store this name and send it to it later, but this
// seems like as good a time as any.
//
[converterInst SetFullNameTo: filename];
//
// Remove all those characters in the name that may cause the font to be misprocessed.
// The list I'm now aware of is: (, ), <, >, [, ], {, }, \, %. Also, space because it breaks
// up the name in the PS file, and period and backslash because they mess up the
// filename, and finally single quotes because they make me uncomfortable
// Replace all these characters with nothing //
destIndex = 0;
for (index = 0; index < strlen(filename); index++)
{
if ((filename[index] != ' ') &&
(filename[index] != '.') &&
(filename[index] != '`') &&
(filename[index] != '\'') &&
(filename[index] != '(') &&
(filename[index] != '<') &&
(filename[index] != '[') &&
(filename[index] != '{') &&
(filename[index] != '}') &&
(filename[index] != ']') &&
(filename[index] != '>') &&
(filename[index] != ')') &&
(filename[index] != '\\') &&
(filename[index] != '/') &&
(filename[index] != '%'))
{
filename[destIndex] = filename[index];
destIndex++;
}
}
filename[destIndex] =EndOfCString;
//
// Create a directory for the font files by
// 1) getting the file's basename (now done above)
// 2) Creating a directory with the name of the requested font
// 3) Create a font file in said directory
// 4) Create a .afm file in said directory
//
//
// 2) Creating a directory with the name of the requested font
//
pathname = NewCString(strlen(theFile)+5);// 5 extra incase no .font thefile
sprintf(pathname, "%s/%s.font", theDir, filename);
errno = 0;
result = mkdir(pathname, 0700 | 0070 | 0007); // strange perms
FreeCString(pathname);
if (result != 0)
{
buffer = NewCString(100);
sprintf(buffer, "The font folder could not be created. (mkdir error: %d)", errno);
[self StoreErrorCode: ERR_CREATEFAILED AndText:buffer];
FreeCString(filename);
FreeCString(theDir);
FreeCString(buffer);
rmdir(theFile);
}
else
{
//
// Allocate space for path to font folder, plus font or font.afm name
//
pathname = NewCString(strlen(theFile) + 5 + 1 + strlen(filename)+4);
sprintf(pathname, "%s/%s.font/%s", theDir, filename, filename);
//
// 3) Create a font file in said directory
//
fontFile = [[PSFile alloc] initAndUse: pathname];
if ([fontFile GetErrorCode] == ERR_OK)
[fontFile CreateAndOpenFor: FILE_WRITE];
if ([fontFile GetErrorCode] != ERR_OK)
{
[self StoreErrorCode: ERR_CREATEFAILED
AndText: "We failed to create the PS font file"];
fontFile = NullInstance;
rmdir(theFile);
}
else
{
//
// 4) Create a .afm file in said directory
//
strcat(pathname, ".afm");
afmFile = [[TextFile alloc] initAndUse: pathname];
if ([afmFile GetErrorCode] == ERR_OK)
[afmFile CreateAndOpenFor: FILE_WRITE];
if ([afmFile GetErrorCode] != ERR_OK)
{
[self StoreErrorCode: ERR_CREATEFAILED
AndText: "We failed to create the font's afm file."];
[fontFile CloseAndDelete];
[fontFile free];
rmdir(theFile);
afmFile = NullInstance;
}
}
FreeCString(pathname);
}
return fontFile;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Routine: closeDestFile:andDelete:
// Parameters: the path to the file to be opened
// Returns: the opened file object (or junk if error is TERMINALERROR()
// Stores: errors
// Description:
// This is used to open the destination file object (a PS file). This is needed so
// that our superclass, when it is doing some of the work that we don' want to,
// will open an instance of the right class.
// Bugs:
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- closeDestFile: fileInstance andDelete: (Boolean) deleteit
{
CString thepath;
[self ResetResults];
if (deleteit == NO)
{
[fileInstance CloseAndSave];
[afmFile CloseAndSave];
}
else
{
thepath = [fileInstance GetDirectory];
[fileInstance CloseAndDelete];
[afmFile CloseAndDelete];
rmdir(thepath);
FreeCString(thepath);
}
[self StoreErrorCode: [fileInstance GetErrorCode]
AndText: [fileInstance GetErrorText]];
[fileInstance free];
[afmFile free];
return self;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Routine: ConvertFrom:To:
// Parameters: The file to be converted from, and the file to be converted to
// Returns: self
// Stores: error code
// Description:
// This merely acts (like the rest of this object) as a kinda minimal interface
// shell. This merely creates the converting object, asks it to convert the stuff,
// stores whether there were any results, and returns.
// Bugs
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- ConvertFrom: sourceFile To: destinationFile
{
[self ResetResults];
[super ConvertFrom: sourceFile To: destinationFile];
[ConvertCommand setEnabled: NO];
//
// 93.0314 Added SetNSEncodingUse call
//
[converterInst SetNSEncodingUse: UseNSEncoding];
[converterInst ConvertMacFONT: sourceFile
ToType3Font: destinationFile AndAFM: afmFile];
if ( [converterInst GetErrorCode] < ERR_OK)
[self StoreErrorCode: [converterInst GetErrorCode]
AndText: [converterInst GetErrorText] ];
else
[self StoreErrorCode: ERR_OK
AndText: "Converted Successfully" ];
[ConvertCommand setEnabled: YES];
return self;
}
@end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.