This is epsfwriter.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. */ /* * epsfwriter.c * * Version: 2.0 * Author: Ken Fromm * History: * 03-07-91 Added this comment. */ #import <appkit/NXBitmapImageRep.h> #import <appkit/color.h> #import <appkit/graphics.h> #import <appkit/nextstd.h> #import <appkit/tiff.h> #import <dpsclient/dpsclient.h> #import <dpsclient/wraps.h> #import <objc/List.h> #import <objc/hashtable.h> #import <streams/streamsimpl.h> #import <streams/streams.h> #import "ImportApp.h" #import "epsfstruct.h" #import "epsfwraps.h" #define MAX_CHARS 255 #define MAX_BYTES (MAX_CHARS/2) extern void GetDocumentComment(); extern NXColor GetColorAt(NXBitmapImageRep *image, int x, int y); extern void LogEpsfError(); /* * These arrays contain the proper instructions for including, initiating * and terminating procedure sets using the Adobe Illustrator format. */ const static char EpsfProcSetDef[ ] = "% EPSF_Illustrator_abbrev % Version 1.0 8/23/1990 % Copyright (C) 1987, 1988, 1989, 1990 % Adobe Systems Incorporated % All Rights Reserved userdict /EPSF_Illustrator_abbrev 14 dict dup begin put % initialization /initialize % - initialize - { userdict /EPSF_Illustrator_abbrev_vars 1 dict dup begin put /_i null def EPSF_Illustrator_abbrev begin EPSF_Illustrator_abbrev { dup xcheck { bind } if pop pop } forall end end EPSF_Illustrator_abbrev begin EPSF_Illustrator_abbrev_vars begin newpath } def /terminate % - terminate - { end end } def /ddef % key value ddef - { EPSF_Illustrator_abbrev_vars 3 1 roll put } def /npop % integer npop - { { pop } repeat } def % color operators /g % gray g - { setgray } def % graphic state operators /d % array phase d - { setdash } def /cf % - cf flatness currentflat def /i % flatness i - { dup 0 eq { pop cf } if setflat } def /j % linejoin j - { setlinejoin } def /J % linecap J - { setlinecap } def /M % miterlimit M - { setmiterlimit } def /w % linewidth w - { setlinewidth } def % place operators /` % matrix llx lly urx ury string ` - { /_i save ddef pop 5 -1 roll concat newpath 4 2 roll 2 copy moveto 3 1 roll 1 index lineto 2 index exch lineto lineto closepath clip newpath userdict begin /showpage {} def } def /~ % - ~ - { end _i restore } def currentdict readonly pop end\n"; const static char EpsfProcSetInit[ ] = "EPSF_Illustrator_abbrev /initialize get exec\n"; const static char EpsfProcSetTerm[ ] = "EPSF_Illustrator_abbrev /terminate get exec\n"; void WriteEpsfProcSetDef () { DPSWritePostScript(DPSGetCurrentContext(), EpsfProcSetDef, strlen(EpsfProcSetDef)); } void WriteEpsfProcSetInit () { DPSWritePostScript(DPSGetCurrentContext(), EpsfProcSetInit, strlen(EpsfProcSetInit)); } void WriteEpsfProcSetTerm () { DPSWritePostScript(DPSGetCurrentContext(), EpsfProcSetTerm, strlen(EpsfProcSetTerm)); } /* * Writes the Adobe Illustrator 88 imported document operator. */ void WriteEpsfIllustratorBeg(NXRect *bounds, NXRect *boundsOrig, float rotation, char *filename) { float a = 1.0, b = 0.0, c = 0.0, d = 1.0, sx = 1.0, sy = 1.0; NXPoint t; DPSContext ctxt; if (boundsOrig->size.width) sx = bounds->size.width/boundsOrig->size.width; if (boundsOrig->size.height) sy = bounds->size.height/boundsOrig->size.height; if (rotation != 0.0) { a = d = (float) cos(rotation); b = c = (float) sin(rotation); c = -c; } a = a * sx; b = b * sx; c = c * sy; d = d * sy; t.x = bounds->origin.x - boundsOrig->origin.x * sx; t.y = bounds->origin.y - boundsOrig->origin.y * sy; ctxt = DPSGetCurrentContext(); DPSPrintf(ctxt, "\n0 g 0 i 0 J 0 j 1 w 10 M [] 0 d\n"); DPSPrintf(ctxt, "[%g %g %g %g %g %g] %g %g %g %g", a, b, c, d, t.x, t.y, boundsOrig->origin.x, boundsOrig->origin.y, boundsOrig->origin.x + boundsOrig->size.width, boundsOrig->origin.y + boundsOrig->size.height); if (filename) DPSPrintf(ctxt, " (%s)", filename); else DPSPrintf(ctxt, " ( )"); DPSPrintf(ctxt, " `\n"); DPSPrintf(ctxt, "%%%%BeginDocument: "); if (filename) DPSPrintf(ctxt, "%s", filename); DPSPrintf(ctxt,"\n"); } void WriteEpsfIllustratorInclude(char *name) { DPSContext ctxt; ctxt = DPSGetCurrentContext(); DPSPrintf(ctxt, "%%%%IncludeFile: "); if (name) DPSPrintf(ctxt, "%s", name); DPSPrintf(ctxt, "\n"); } void WriteEpsfIllustratorEnd() { DPSContext ctxt; ctxt = DPSGetCurrentContext(); DPSPrintf(ctxt, "%%%%EndDocument\n"); DPSPrintf(ctxt, "~\n\n"); } void WriteEpsfResource(id list, int i, int j) { int k, count, linelen, datalen, commentlen; char comment[EPSF_MAXCOMMENTSUB]; NXAtom data; DPSContext ctxt; count = [list count]; if (count) { ctxt = DPSGetCurrentContext(); GetDocumentComment(comment, i, j); DPSPrintf(ctxt, comment); linelen = commentlen = strlen(comment); for (k = 0; k < count; k++) { data = (NXAtom) [list objectAt:k]; datalen = strlen(data); if (datalen + linelen > EPSF_MAXCOMMENT) { /* Prevents an infinite loop for a single large datalen. */ if (commentlen != linelen) { DPSPrintf(ctxt, "\n%%%%+"); linelen = commentlen = 3; } } DPSPrintf(ctxt, " %s", data); linelen += datalen; } DPSPrintf(ctxt, "\n"); } } static char GetBlackWhiteAt(NXBitmapImageRep *image, int x, int y) { int bps, spp, amask; unsigned char gray; spp = [image samplesPerPixel]; bps = [image bitsPerSample]; amask = (1 << bps) - 1; // 1, 3, 15, 255 for bps = 1, 2, 4, 8 if ([image isPlanar]) { int pixel = x * bps; int byteLoc = [image bytesPerRow] * y + (pixel >> 3); int bitLoc = pixel & 7; gray = ((*([image data]+byteLoc)) >> (8 - bitLoc - bps)) & amask; } else { unsigned char *byteLoc = [image data] + [image bytesPerRow] * y; int bitLoc = x * bps * spp; gray = ((byteLoc[bitLoc >> 3]) >> (8 - (bitLoc & 7) - bps)) & amask; } return (gray >> 1 ? 0 : 1); } void WriteEpsfPreview(id image) { int byte, orbyte; int i, j, width, height, pos, bytes; DPSContext ctxt; if (image) { ctxt = DPSGetCurrentContext(); width = [image pixelsWide]; height = [image pixelsHigh]; DPSPrintf(ctxt, "%%%%BeginPreview: %d %d %d %d", width, height, 1, (((width-1)/8)/MAX_BYTES + 1) *height); for (i = 0; i < height; i++) { DPSPrintf(ctxt, "\n%% "); pos = 7; byte = 0; bytes = 0; for (j = 0; j < width; j++, pos--) { orbyte = GetBlackWhiteAt(image, j, i) << pos; byte = byte | orbyte; if (pos == 0 || j == width - 1) { bytes++; if (bytes > MAX_BYTES) { bytes = 0; DPSPrintf(ctxt, "\n%% "); } DPSPrintf(ctxt, "%02x", byte); pos = 8; byte = 0; } } } DPSPrintf(ctxt, "\n%%%%EndPreview\n\n"); } } /* * This does nothing in the way of error recovery. It is used to demonstrate the * problems on not using a separate context. Eps files with errors can potentially * harm the application's context. The recommended approach is to use * the NXEPSImageRep object to image the file. */ int WriteEpsf(const char *name, NXRect *bounds, NXRect *boundsOrig) { BOOL trace; int error, len, maxlen; char *data; NXStream *stream; DPSContext ctxt; trace = [NXApp tracingFlag]; error = EPSF_OK; stream = NXMapFile(name, NX_READONLY); if (stream) { NXGetMemoryBuffer(stream, &data, &len, &maxlen); if (data && len) { ctxt = DPSGetCurrentContext(); error = EPSF_WRITEERROR; NX_DURING DPSTraceContext(ctxt, trace); PSWBeginEpsf(); PSWSetEpsf(bounds->origin.x, bounds->origin.y, bounds->size.width, bounds->size.height, boundsOrig->origin.x, boundsOrig->origin.y, boundsOrig->size.width, boundsOrig->size.height, 0); DPSPrintf(ctxt, "%%%%BeginDocument: %s\n", name); DPSPrintf(ctxt, "%%%% ...Included EPS file here... \n"); DPSTraceContext(ctxt, NO); DPSWritePostScript(ctxt, data, len); DPSTraceContext(ctxt, trace); DPSPrintf(ctxt, "%%%%EndDocument\n"); PSWEndEpsf(); DPSTraceContext(ctxt, NO); DPSFlushContext(ctxt); error = EPSF_OK; NX_HANDLER if (NXLocalHandler.code == dps_err_ps) LogEpsfError(&NXLocalHandler); else NX_RERAISE(); NX_ENDHANDLER } } return error; }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.