This is EpsfParser.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. */ /* * EpsfParser.m * * This class reads in a distilled epsf file and attempts to parse through the file * and insert the paths into the programs data structures. * * Version: 2.0 * Author: Ken Fromm * History: * 03-07-91 Added this comment. */ #import "EpsfParser.h" #import "iparser.h" #import <appkit/Panel.h> #import <appkit/nextstd.h> #import <stdio.h> static char *processToLineEnd(); static char *processToField(); static BOOL checkForPS(char **dataptr, float *level_dsc, float *level_epsf) { char *dp; BOOL invalid_ps = YES; *level_dsc = *level_epsf = 0.0; dp = *dataptr; if (!strncmp(dp, "%!PS-Adobe-", 11)) { invalid_ps = NO; dp +=11; sscanf(dp, "%f", level_dsc); while(*dp == ' ') dp++; if (!strncmp(dp, "EPSF-", 5)) { dp += 5; sscanf(dp, "%f", level_dsc); } } *dataptr = processToLineEnd(dp); return invalid_ps; } static int checkType(char *s0, char *s1, char *s2, char *s3) { int type = PS_NOTYPE; if (s0 && *s0 && s1 && *s1) { if (!strncmp(s0, "Adobe", 5) && !strncmp(s1, "Illustrator", 11)) type = PS_ILLUSTRATOR; else if (!strncmp(s0, "Glenn", 5) && !strncmp(s1, "Reid", 4) && !strncmp(s3, "still.ps", 8)) type = PS_DISTILLERY; } return type; } static BOOL validateCreator(int ps_creator) { if (ps_creator == PS_DISTILLERY) return YES; else return NO; } static void convertBounds(float *aBox, NXRect *aRect) { aRect->origin.x = aBox[0]; aRect->origin.y = aBox[1]; aRect->size.width = aBox[2] - aBox[0]; aRect->size.height = aBox[3] - aBox[1]; } static char *processToLineEnd(char *dp) { dp = strchr(dp,'\n'); dp++; return dp; } static char *processToField(char *dp) { dp = strchr(dp,':'); dp++; if (*dp == ' ') { strrchr(dp, ' '); dp++; } return dp; } static void checkHeader(char **dataptr, float *bbox, BOOL *validBBox, int *creator) { BOOL done = NO; char *dp; char str0[40], str1[40], str2[40], str3[40]; int matches = 0; *creator = PS_NOTYPE; *validBBox = NO; dp = *dataptr; while (*dp && !done) { if (strncmp(dp, "%%", 2) == 0) { dp += 2; if (strncmp(dp, "EndComments", 11) == 0) done = YES; else if (strncmp(dp, "Creator:", 8) == 0) { dp = processToField(dp); sscanf(dp, "%s%s%s%s", str0, str1, str2, str3); *creator = checkType(str0, str1, str2, str3); } else if (strncmp(dp, "BoundingBox:", 12) == 0) { dp = processToField(dp); if (strncmp(dp, "(atend)", 7) != 0) { matches = sscanf(dp, "%f %f %f %f", &bbox[0], &bbox[1], &bbox[2], &bbox[3]); if ((matches && matches != 4) || (matches == 4 && (bbox[2] == bbox[0] || bbox[3] == bbox[1]))) *validBBox = YES; } } } dp = processToLineEnd(dp); } *dataptr = dp; return; } static void checkTrailer(char **dataptr, float *bbox, BOOL *validBBox) { BOOL done = NO; char *dp; int matches = 0; *validBBox = NO; dp = *dataptr; while (*dp && !done) { if (strncmp(dp, "%%", 2) == 0) { dp += 2; if (strncmp(dp, "BoundingBox:", 12) == 0) { dp = processToField(dp); matches = sscanf(dp, "%f %f %f %f", &bbox[0], &bbox[1], &bbox[2], &bbox[3]); if (matches == 4 && bbox[2] != bbox[0] && bbox[3] != bbox[1]) { done = YES; *validBBox = YES; } } } dp = processToLineEnd(dp); } *dataptr = dp; return; } @implementation EpsfParser /* * Checks for valid PS file, gets the bounding box and checks for * the creator. The creator will let us determine whether we can read * the file into our own graphics structure. */ - readPSFromStream:(NXStream *)stream { BOOL error = YES, validBBox = NO; char *data; float bbox[4]; int length, /* the number of bytes in data */ maxlen; /* size of vm_allocated region */ bbox[0] = bbox[1] = bbox[2] = bbox[3] = 0; NXGetMemoryBuffer(stream, &data, &length, &maxlen); if (length) { error = checkForPS(&data, &level_dsc, &level_epsf); if (!error) { checkHeader(&data, bbox, &validBBox, &creator); if (validateCreator(creator)) { if (!iparse(&data)) { if (!validBBox) checkTrailer(&data, bbox, &validBBox); if (validBBox) convertBounds(bbox, &bounds); else NXRunAlertPanel("Load File", "Invalid bounding box. Cannot open.", "OK", NULL, NULL); } } else NXRunAlertPanel("Load File", "Not a distilled file. Cannot open.", "OK", NULL, NULL); } else NXRunAlertPanel("Load File", "Not a valid PS file. Cannot open.", "OK", NULL, NULL); } else NXRunAlertPanel("Load File", "Invalid file. Cannot open.", "OK", NULL, NULL); if (error) return nil; else return self; } - getBounds:(NXRect *) aRect { *aRect = bounds; return self; } @end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.