This is NXEPSImageRepSub.m in view mode; [Download] [Up]
/* * (a) (C) 1990 by Adobe Systems Incorporated. All rights reserved. * * (b) If this Sample Code is distributed as part of the Display PostScript * System Software Development Kit from Adobe Systems Incorporated, * then this copy is designated as Development Software and its use is * subject to the terms of the License Agreement attached to such Kit. * * (c) If this Sample Code is distributed independently, then the following * terms apply: * * (d) This file may be freely copied and redistributed as long as: * 1) Parts (a), (d), (e) and (f) continue to be included in the file, * 2) If the file has been modified in any way, a notice of such * modification is conspicuously indicated. * * (e) PostScript, Display PostScript, and Adobe are registered trademarks of * Adobe Systems Incorporated. * * (f) THE INFORMATION BELOW IS FURNISHED AS IS, IS SUBJECT TO * CHANGE WITHOUT NOTICE, AND SHOULD NOT BE CONSTRUED * AS A COMMITMENT BY ADOBE SYSTEMS INCORPORATED. * ADOBE SYSTEMS INCORPORATED ASSUMES NO RESPONSIBILITY * OR LIABILITY FOR ANY ERRORS OR INACCURACIES, MAKES NO * WARRANTY OF ANY KIND (EXPRESS, IMPLIED OR STATUTORY) * WITH RESPECT TO THIS INFORMATION, AND EXPRESSLY * DISCLAIMS ANY AND ALL WARRANTIES OF MERCHANTABILITY, * FITNESS FOR PARTICULAR PURPOSES AND NONINFRINGEMENT * OF THIRD PARTY RIGHTS. */ /* * NXEPSImageRepSub.m * * A subclass of NXEPSImageRep. Enhanced to handle rotation * and resources. * * Version: 2.0 * Author: Ken Fromm */ #import "NXEPSImageRepSub.h" #import <appkit/Font.h> #import <appkit/Panel.h> #import <appkit/View.h> #import <appkit/nextstd.h> #import <appkit/defaults.h> #import <objc/List.h> #import <objc/Storage.h> #import <objc/hashtable.h> #import <dpsclient/wraps.h> #import <stdio.h> /* Used only for demonstration purposes. */ #import "ImportApp.h" #import "epsfwraps.h" @implementation NXEPSImageRepSub - free { if (_tempName) NX_FREE(_tempName); return [super free]; } - writeIncludedFiles:storage; { int i, count, writelen, readlen, includelen, maxlen; char *readdata, *startdata, *includedata; NXStream *writestream, *readstream, *includestream; Inclusion *inclusion; if (storage && [storage count]) { readlen = 0; readdata = NULL; readstream = NULL; if (_fileName) { readstream = NXMapFile(_fileName, NX_READONLY); if (readstream) NXGetMemoryBuffer(readstream, &readdata, &readlen, &maxlen); } else { readdata = _memory; readlen = _epsLen; } if (readdata && readlen) { startdata = readdata; if (_fileName) writestream = NXOpenMemory(NULL, 0, NX_WRITEONLY); else writestream = NXOpenMemory(NULL, 0, NX_READWRITE); if (writestream) { count = [storage count]; for (i = 0; i < count; i++) { inclusion = [storage elementAt:i]; if (inclusion->filename && inclusion->len) { writelen = inclusion->offset - (readdata - startdata); NXWrite(writestream, readdata, writelen); includestream = NXMapFile(inclusion->filename, NX_READONLY); if (includestream) { NXGetMemoryBuffer(includestream, &includedata, &includelen, &maxlen); NXWrite(writestream, includedata, includelen); } else NXWrite(writestream, readdata+inclusion->offset, inclusion->len); readdata += writelen + inclusion->len; readlen -= (writelen + inclusion->len); } } NXWrite(writestream, readdata, readlen); if (_fileName) { _tempName = NXCopyStringBuffer("/tmp/EpsfTempXXXXXX.eps"); NXGetTempFilename(_tempName, 13); if (_tempName) NXSaveToFile(writestream, _tempName); NXCloseMemory(writestream, NX_FREEBUFFER); } else { NXGetMemoryBuffer(writestream, &_tempMemory, &_tempEpsLen, &maxlen); NXCloseMemory(writestream, NX_SAVEBUFFER); } } } if (readstream) NXCloseMemory(readstream, NX_FREEBUFFER); } return self; } /* * Check to see if the fonts are on the system and only flag * those not available. */ - checkFonts:(Resource *) resource placeIn:(ResourceList *) resourceList { id font; int i, count; if (resource && resourceList) { if (resource->states[RES_NEEDED]) resourceList->types[RES_FONTS] = [resource->states[RES_NEEDED] copy]; else if (!resource->states[RES_SUPPLIED] && resource->states[RES_PRESENT]) resourceList->types[RES_FONTS] = [resource->states[RES_PRESENT] copy]; /* * There should be an easier way to check for font availability other * than to create a font object but this will have to do for now. */ count = [resourceList->types[RES_FONTS] count]; for (i = count -1; i >= 0; i--) { font = [Font newFont:(char *) [resourceList->types[RES_FONTS] objectAt:i] size:12]; if (font) { [font free]; [resourceList->types[RES_FONTS] removeObjectAt:i]; } } if ([resourceList->types[RES_FONTS] count] == 0) { [resourceList->types[RES_FONTS] free]; resourceList->types[RES_FONTS] = NULL; } } return self; } - checkFiles:(Resource *) resource placeIn:(ResourceList *) resourceList { int i, count; FILE *file; if (resource && resourceList) { if (resource->states[RES_NEEDED]) resourceList->types[RES_FILES] = [resource->states[RES_NEEDED] copy]; /* * Try to open the files. If available then remove from the list. */ count = [resourceList->types[RES_FILES] count]; for (i = count -1; i >= 0; i--) { file = fopen((char *) [resourceList->types[RES_FILES] objectAt:i], "r"); if (file) { fclose(file); [resourceList->types[RES_FILES] removeObjectAt:i]; } } if ([resourceList->types[RES_FILES] count] == 0) { [resourceList->types[RES_FILES] free]; resourceList->types[RES_FILES] = NULL; } } return self; } - checkProcSets:(Resource *) resource placeIn:(ResourceList *) resourceList { if (resource && resourceList) { if (resource->states[RES_NEEDED]) resourceList->types[RES_PROCSETS] = [resource->states[RES_NEEDED] copy]; } return self; } - checkPatterns:(Resource *) resource placeIn:(ResourceList *) resourceList { if (resource && resourceList) { if (resource->states[RES_NEEDED]) resourceList->types[RES_PATTERNS] = [resource->states[RES_NEEDED] copy]; } return self; } - checkForms:(Resource *) resource placeIn:(ResourceList *) resourceList { if (resource && resourceList) { if (resource->states[RES_NEEDED]) resourceList->types[RES_FORMS] = [resource->states[RES_NEEDED] copy]; } return self; } /* * Fills in the empty resources and inclusions array within the epsf structure. */ - (int) getResources:(EpsfStruct *) epsf { int maxlen, error; NXStream *stream; error = EPSF_INVALIDPS; if (epsf) { stream = NULL; epsf->filedata = NULL; if (_fileName) { stream = NXMapFile(_fileName, NX_READONLY); if (stream) NXGetMemoryBuffer(stream, &epsf->filedata, &epsf->filelen, &maxlen); } else { epsf->filedata = _memory; epsf->filelen = _epsLen; } if (epsf->filedata) error = ReadEpsf(epsf); if (stream) NXCloseMemory(stream, NX_FREEBUFFER); } return error; } /* * Returns the list of unavailableResources. * * Returns any resources except for fonts that are marked as needed. * Check to see if the fonts are on the system and flags only those not * available. As the other resources move into the realm of system * resources, this method can check the availability of these resources * as well. * */ - checkResources:(ResourceList *) resourceList; { int error; EpsfStruct epsf; bzero(resourceList, sizeof(ResourceList)); error = [self getResources:&epsf]; if (!error) { [self checkFonts:&epsf.resources[RES_FONTS] placeIn:resourceList]; [self checkFiles:&epsf.resources[RES_FILES] placeIn:resourceList]; [self checkProcSets:&epsf.resources[RES_PROCSETS] placeIn:resourceList]; [self checkPatterns:&epsf.resources[RES_PATTERNS] placeIn:resourceList]; [self checkForms:&epsf.resources[RES_FORMS] placeIn:resourceList]; [self writeIncludedFiles:epsf.inclusions]; return self; } else Notify("Import Error", ErrorEpsf(error)); return nil; } /* * Used when printing. Add the resources used in this file * to the list passed in. Only adds the resources that are not * currently in the resourceDoc structure already. */ - addResources:(Resource *) resourceDoc forFile:(NXAtom) fileName { id name; int i, j, k, count; EpsfStruct epsf; if (_fileName || fileName) { i = RES_SUPPLIED; if (_fileName) { name = (id) _fileName; if (NXDrawingStatus == NX_COPYING) i = RES_NEEDED; } else name = (id) fileName; if (!resourceDoc[RES_FILES].states[RES_PRESENT]) resourceDoc[RES_FILES].states[RES_PRESENT] = [List new]; if (!resourceDoc[RES_FILES].states[RES_NEEDED]) resourceDoc[RES_FILES].states[i] = [List new]; [resourceDoc[RES_FILES].states[RES_PRESENT] addObjectIfAbsent:name]; [resourceDoc[RES_FILES].states[i] addObjectIfAbsent:name]; } [self getResources:&epsf]; for (i = 0; i < RES_NUMTYPES; i++) { for (j = 0; j < RES_NUMSTATES; j++) { if (epsf.resources[i].states[j]) { if (!resourceDoc[i].states[j]) resourceDoc[i].states[j] = [List new]; count = [epsf.resources[i].states[j] count]; for (k = 0; k < count; k++) [resourceDoc[i].states[j] addObjectIfAbsent:[epsf.resources[i].states[j] objectAt:k]]; } } } return self; } /* * Overridden to handle any %%IncludeFile. A temporary file or * memory buffer has been written out that adds the included * files. This temporary file or memory pointer are swapped for the * real ones if they exist. The image is drawn and then they are * returned back. Their is probably a better way but without * knowing the internals of how this class works its a tenuous * bet to find one. */ - (BOOL) draw { BOOL rc = YES; char *data, *tempname, *tempmemory; int templen, len, maxlen; NXStream *stream; templen = 0; tempname = tempmemory = NULL; if (_tempName || _tempMemory) { if (_fileName) { tempname = _fileName; _fileName = _tempName; } else { tempmemory = _memory; templen = _epsLen; _memory = _tempMemory; _epsLen = _tempEpsLen; } } /************************************************************* * The first case of the if-else statement is only to show * what can happen when a separate context is not used. * The imaging should be done with the draw method * because it installs a separate context. **************************************************************/ if (![NXApp contextFlag]) { PStranslate(-_bBoxOrigin.x, -_bBoxOrigin.y); if (_fileName && !_repFlags.dataLoaded) { stream = NXMapFile(_fileName, NX_READONLY); if (stream) NXGetMemoryBuffer(stream, &data, &len, &maxlen); } else { data = _memory; len = _epsLen; } PSWBeginEpsf(); DPSWritePostScript(DPSGetCurrentContext(), data, len); PSWEndEpsf(); } else rc = [super draw]; if (_tempName || _tempMemory) { if (_fileName) { _fileName = tempname; } else { _memory = tempmemory; _epsLen = templen; } } return rc; } /* * Draws the EPS file. Positions it appropriately, scaling and rotating * it according to the arguments passed in. The rotation is in degrees. */ - (BOOL) drawIn:(NXRect *) r with:(float) rotation { BOOL error; NXRect original; error = NO; if (NXDrawingStatus == NX_COPYING) { original.origin = _bBoxOrigin; original.size = size; if (_fileName) { WriteEpsfIllustratorBeg(r, &original, rotation, _fileName); WriteEpsfIllustratorInclude(_fileName); WriteEpsfIllustratorEnd(); } else { WriteEpsfIllustratorBeg(r, &original, rotation, NULL); DPSWritePostScript(DPSGetCurrentContext(), _memory, _epsLen); WriteEpsfIllustratorEnd(); } } else { PSgsave(); PStranslate(r->origin.x, r->origin.y); PSrotate(rotation); PSscale(r->size.width/size.width, r->size.height/size.height); error = [self draw]; PSgrestore(); } return error; } @end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.