diff --git a/demos/mac/README b/demos/mac/README new file mode 100644 index 000000000..9674240ae --- /dev/null +++ b/demos/mac/README @@ -0,0 +1,22 @@ +This folder contains supporting code and CodeWarrior Pro 4 project +files to build the FreeType demo programs ftlint and ftview for MacOS. + +Building +To build these apps, you'll first need to build the FreeType library +(see config/mac). The applications get built in the demos/bin folder. + +Notes +Since the Mac doesn't have the notion of argc/argv, we'll emulate +this: each file dropped onto the application will be translated +to a command line argument. Both ftlint and ftview take a ppem +value as their first command line argument: for the Mac version +this has been hard-coded into the source. Also: the additional +options for ftview cannot be set. + +Have fun with FreeType on the Mac! + +Just van Rossum, + +DISCLAIMER: this subdirectory is *not* being maintained by the +FreeType team, but by Just van Rossum. It's being released under +the same terms as FreeType (see license.txt). diff --git a/demos/mac/codewarrior/ftlint.prj b/demos/mac/codewarrior/ftlint.prj new file mode 100644 index 000000000..a76742e67 Binary files /dev/null and b/demos/mac/codewarrior/ftlint.prj differ diff --git a/demos/mac/codewarrior/ftview.prj b/demos/mac/codewarrior/ftview.prj new file mode 100644 index 000000000..3eedd83e9 Binary files /dev/null and b/demos/mac/codewarrior/ftview.prj differ diff --git a/demos/mac/ftlint_m.c b/demos/mac/ftlint_m.c new file mode 100644 index 000000000..258b0286d --- /dev/null +++ b/demos/mac/ftlint_m.c @@ -0,0 +1,59 @@ +/* minimal Mac wrapper for the ftlint.c program */ + + +int original_main( int argc, char** argv ); + +/* We rename the original main() program to original_main, + so we can provide a wrapper around it */ +#define main original_main +#include "ftlint.c" +#undef main + + +#define PPEM "24" /* hard-code the ppem size */ + + +#include +#include "getargv.h" +#include +#include +#include +#include + +static void +init_toolbox() +{ + InitGraf(&qd.thePort); + InitFonts(); + InitWindows(); + TEInit(); + InitDialogs((long)0); + InitMenus(); + InitCursor(); + SIOUXSettings.asktosaveonclose = 0; +} + +int main() +{ + int argc, i; + char** argv; + + init_toolbox(); + + /* put paths of all files dropped onto the app into argv */ + argc = FTMac_GetArgv(&argv); + if (argc < 2) + { + printf("Please drop one or more font files onto the app (but quit first!)\n"); + exit(1); + } + /* move argv[1:] to argv[2:] and fill in the ppem arg */ + for (i = argc; i > 1; i--) + { + argv[i] = argv[i-1]; + } + argc++; + argv[1] = PPEM; + /* call the original main() program */ + original_main(argc, argv); +} diff --git a/demos/mac/ftview_m.c b/demos/mac/ftview_m.c new file mode 100644 index 000000000..c4edc7e60 --- /dev/null +++ b/demos/mac/ftview_m.c @@ -0,0 +1,59 @@ +/* minimal Mac wrapper for the ftview.c program */ + + +int original_main( int argc, char** argv ); + +/* We rename the original main() program to original_main, + so we can provide a wrapper around it */ +#define main original_main +#include "ftview.c" +#undef main + + +#define PPEM "24" /* hard-code the ppem size */ + + +#include +#include "getargv.h" +#include +#include +#include +#include + +static void +init_toolbox() +{ + InitGraf(&qd.thePort); + InitFonts(); + InitWindows(); + TEInit(); + InitDialogs((long)0); + InitMenus(); + InitCursor(); + SIOUXSettings.asktosaveonclose = 0; +} + +int main() +{ + int argc, i; + char** argv; + + init_toolbox(); + + /* put paths of all files dropped onto the app into argv */ + argc = FTMac_GetArgv(&argv); + if (argc < 2) + { + printf("Please drop one or more font files onto the app (but quit first!)\n"); + exit(1); + } + /* move argv[1:] to argv[2:] and fill in the ppem arg */ + for (i = argc; i > 1; i--) + { + argv[i] = argv[i-1]; + } + argc++; + argv[1] = PPEM; + /* call the original main() program */ + original_main(argc, argv); +} diff --git a/demos/mac/getargv.c b/demos/mac/getargv.c new file mode 100644 index 000000000..7ff18e03b --- /dev/null +++ b/demos/mac/getargv.c @@ -0,0 +1,312 @@ +/*********************************************************** +Copyright 1991-1997 by Stichting Mathematisch Centrum, Amsterdam, +The Netherlands. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the names of Stichting Mathematisch +Centrum or CWI not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior permission. + +STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO +THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE +FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +******************************************************************/ + +/* Construct argc and argv for main() by using Apple Events */ +/* From Jack's implementation for STDWIN */ + +/* Modified for use with FreeType from MacPython's macgetargv.c + by Just van Rossum */ + +#include +#include +#include "getargv.h" + +#include +#include +#include +#include +#include +#include +#include + +#ifdef GENERATINGCFM /* Defined to 0 or 1 in Universal headers */ +#define HAVE_UNIVERSAL_HEADERS +#endif + +#ifndef HAVE_UNIVERSAL_HEADERS +#define NewAEEventHandlerProc(x) (x) +#define AEEventHandlerUPP EventHandlerProcPtr +#endif + +static int arg_count; +static char *arg_vector[256]; +static char app_name[256]; +static int app_name_inited; + + +/* Duplicate a string to the heap. */ + +static char * +strdup(char *src) +{ + char *dst = malloc(strlen(src) + 1); + if (dst) + strcpy(dst, src); + return dst; +} + + +/* Given an FSSpec, return the FSSpec of the parent folder */ + +static OSErr +get_folder_parent (FSSpec * fss, FSSpec * parent) +{ + CInfoPBRec rec; + short err; + + * parent = * fss; + rec.hFileInfo.ioNamePtr = parent->name; + rec.hFileInfo.ioVRefNum = parent->vRefNum; + rec.hFileInfo.ioDirID = parent->parID; + rec.hFileInfo.ioFDirIndex = -1; + rec.hFileInfo.ioFVersNum = 0; + if (err = PBGetCatInfoSync (& rec)) + return err; + parent->parID = rec.dirInfo.ioDrParID; +/* parent->name[0] = 0; */ + return 0; +} + + +/* Given an FSSpec return a full, colon-separated pathname */ + +static OSErr +FTMac_GetFullPath (FSSpec *fss, char *buf) +{ + short err; + FSSpec fss_parent, fss_current; + char tmpbuf[256]; + int plen; + + fss_current = *fss; + plen = fss_current.name[0]; + memcpy(buf, &fss_current.name[1], plen); + buf[plen] = 0; + /* Special case for disk names */ + if ( fss_current.parID <= 1 ) { + buf[plen++] = ':'; + buf[plen] = 0; + return 0; + } + while (fss_current.parID > 1) { + /* Get parent folder name */ + if (err = get_folder_parent(&fss_current, &fss_parent)) + return err; + fss_current = fss_parent; + /* Prepend path component just found to buf */ + plen = fss_current.name[0]; + if (strlen(buf) + plen + 1 > 256) { + /* Oops... Not enough space (shouldn't happen) */ + *buf = 0; + return -1; + } + memcpy(tmpbuf, &fss_current.name[1], plen); + tmpbuf[plen] = ':'; + strcpy(&tmpbuf[plen+1], buf); + strcpy(buf, tmpbuf); + } + return 0; +} + + +/* Initialize name of current application */ + +static OSErr +init_app_name() +{ + ProcessSerialNumber currentPSN; + ProcessInfoRec info; + OSErr err; + FSSpec appSpec; + + if ( app_name_inited ) return 0; + currentPSN.highLongOfPSN = 0; + currentPSN.lowLongOfPSN = kCurrentProcess; + info.processInfoLength = sizeof(ProcessInfoRec); + info.processName = NULL; + info.processAppSpec = &appSpec; + if ( err=GetProcessInformation(¤tPSN, &info)) + return err; + strncpy(app_name, (char*)appSpec.name + 1, appSpec.name[0]); + app_name[appSpec.name[0]] = '\0'; + app_name_inited = 1; + return 0; +} + + +/* Check that there aren't any args remaining in the event */ + +static OSErr +get_missing_params(AppleEvent *theAppleEvent) +{ + DescType theType; + Size actualSize; + OSErr err; + + err = AEGetAttributePtr(theAppleEvent, keyMissedKeywordAttr, typeWildCard, + &theType, nil, 0, &actualSize); + if (err == errAEDescNotFound) + return noErr; + else + return errAEEventNotHandled; +} + +static int got_one; /* Flag that we can stop getting events */ + + +/* Handle the Print or Quit events (by failing) */ + +static pascal OSErr +handle_not(AppleEvent *theAppleEvent, AppleEvent *reply, long refCon) +{ + #pragma unused (reply, refCon) + got_one = 1; + return errAEEventNotHandled; +} + + +/* Handle the Open Application event (by ignoring it) */ + +static pascal OSErr +handle_open_app(AppleEvent *theAppleEvent, AppleEvent *reply, long refCon) +{ + #pragma unused (reply, refCon) +#if 0 + /* Test by Jack: would removing this facilitate debugging? */ + got_one = 1; +#endif + return get_missing_params(theAppleEvent); +} + + +/* Handle the Open Document event, by adding an argument */ + +static pascal OSErr +handle_open_doc(AppleEvent *theAppleEvent, AppleEvent *reply, long refCon) +{ + #pragma unused (reply, refCon) + OSErr err; + AEDescList doclist; + AEKeyword keywd; + DescType rttype; + long i, ndocs, size; + FSSpec fss; + char path[256]; + + got_one = 1; + if (err = AEGetParamDesc(theAppleEvent, + keyDirectObject, typeAEList, &doclist)) + return err; + if (err = get_missing_params(theAppleEvent)) + return err; + if (err = AECountItems(&doclist, &ndocs)) + return err; + for(i = 1; i <= ndocs; i++) { + err = AEGetNthPtr(&doclist, i, typeFSS, + &keywd, &rttype, &fss, sizeof(fss), &size); + if (err) + break; + FTMac_GetFullPath(&fss, path); + arg_vector[arg_count++] = strdup(path); + } + return err; +} + + +/* Install standard core event handlers */ +static AEEventHandlerUPP open_doc_upp; +static AEEventHandlerUPP open_app_upp; +static AEEventHandlerUPP not_upp; + +static void +set_ae_handlers() +{ + open_doc_upp = NewAEEventHandlerProc(handle_open_doc); + open_app_upp = NewAEEventHandlerProc(handle_open_app); + not_upp = NewAEEventHandlerProc(handle_not); + + AEInstallEventHandler(kCoreEventClass, kAEOpenApplication, + open_app_upp, 0L, false); + AEInstallEventHandler(kCoreEventClass, kAEOpenDocuments, + open_doc_upp, 0L, false); + AEInstallEventHandler(kCoreEventClass, kAEPrintDocuments, + not_upp, 0L, false); + AEInstallEventHandler(kCoreEventClass, kAEQuitApplication, + not_upp, 0L, false); +} + +/* Uninstall standard core event handlers */ + +static void +reset_ae_handlers() +{ + AERemoveEventHandler(kCoreEventClass, kAEOpenApplication, + open_app_upp, false); + AERemoveEventHandler(kCoreEventClass, kAEOpenDocuments, + open_doc_upp, false); + AERemoveEventHandler(kCoreEventClass, kAEPrintDocuments, + not_upp, false); + AERemoveEventHandler(kCoreEventClass, kAEQuitApplication, + not_upp, false); +} + +/* Wait for events until a core event has been handled */ + +static void +event_loop() +{ + EventRecord event; + int n; + int ok; + + got_one = 0; + for (n = 0; n < 100 && !got_one; n++) { + SystemTask(); + ok = GetNextEvent(everyEvent, &event); + if (ok && event.what == kHighLevelEvent) { + AEProcessAppleEvent(&event); + } + } +} + +/* Get the argv vector, return argc. See macgetargv.h for more doco. */ + +int +FTMac_GetArgv(pargv) + char ***pargv; +{ + + arg_count = 0; + (void)init_app_name(); + arg_vector[arg_count++] = strdup(app_name); + + set_ae_handlers(); + event_loop(); + reset_ae_handlers(); + + arg_vector[arg_count] = NULL; + + *pargv = arg_vector; + return arg_count; +} diff --git a/demos/mac/getargv.h b/demos/mac/getargv.h new file mode 100644 index 000000000..a13289dd8 --- /dev/null +++ b/demos/mac/getargv.h @@ -0,0 +1,19 @@ +/* + + FTMac_GetArgv + + + argc/argv emulation for the Mac. Converts files dropped + onto the application to full paths, and stuff them into + argv. + + + pargv :: a pointer to an argv array. The array doesn't need to + exist before calling this function. + + + The number of files dropped onto the app (ie. argc) +*/ + +int FTMac_GetArgv(char ***pargv); + diff --git a/demos/mac/resource.hqx b/demos/mac/resource.hqx new file mode 100644 index 000000000..cde902da4 --- /dev/null +++ b/demos/mac/resource.hqx @@ -0,0 +1,38 @@ +(This file must be converted with BinHex 4.0) +:$(*PFfpeFQ0P,R0TG!"6594%8dP8)3%!!!!'[!!!!!!REP0*9#%!!J!!"Vab6'& +e!RX!!!!@EhX0!!YQG'aTER3ZFR0bB`K"ST!!!%9qHJ!!!)!!!!!!#%PXcPl2#BB +!!!!!!!!!!!!!!!!!!!!!!!!"R`!!!!$rrrrrFR0bBe*6483"!,6HlZHdhZmk!!! +"Q3!!!!!!!!%C!!!!!"2I!!!!!!!!!!#2I4%!#"`XG3MLeZTM1d$2c[ec0aXql5S +ShPIL[&U,h14S@fT@KjEj-dK+IjNHBG)R-N9+9!`J2MP%TSHT%#Nd-qT*elC3-#N +4JA)Hkc6qlRVSqDHb&A*3a9&1cdmjhEbBUHN9ad&X+`E&1ceI!Y68j0ki6qFA)(r +b,FRGeI4f6k%5&4RNVXbJD-emb41U6CZldibq,@I[0+0[hAC1Pd8qb1GJMXlkGX[ +Qi$6*5FhCV+hMcp9GjDB!CG6%FFi-Y%hSD+RR#(40DQ1''@VI1VRml-&F9CdAA5b +'mAYaP!drhR!2h3*kJDG9FQ)R4mZIfD4`CM-&4Q9IJU0XbMdc06QfE,r!c)B,BXZ +5lI0h(XbS`)*QmLcRP#B"!!!!$3!,CR4fD@9h,R*cFQ-)3D+3!!"&IRS!!!#!!!! +!!!K*E-kIZJQ'!!!!!!!!!!!!!!!!!!!!&J!!!!!!!!!!rrrrrh*cFQ058d9%!3# +dhZlRY0pi`J!!#Fd!!!!!!!!%V3!!!!#NcJ!!!!!!!!!!i8X,3,6cZVA1c0lNY)[ +f+j[)D@pq&ff8&[hml++YG5DRR()cQTfYCHr*j#YEf5Jc%CLIXrbFjqFX2cmr2dr +ZTpFJfU$ca31a!b+85iiI35I(Bq'a#e!!VJ6J!#F!VSd!Nr('42m&cC%BQfS+kII +X%,b5(HDLA-XlBDbP"ISMY'LUSfGRDkm!HhGl5NUk05!P)laE*h[lM)b!S+!8DhG +VJA4q'GFk-X)*HFCMl1QrCp29l+`h+kl(I3FBqcaJl-h0E-YliEX#cZ%fH-9NHb2 +[J5A*h#if"qk@8jD%["I4@8lH[MDBr'c`$(5cE+ral1fF[*0$mqINR4`FEH`P-!" +ZaYZ$[j86fKM'6M`k&3TTDRc[bEfDM@PAb0Zc`KL$6e6mrPk'RD,L)U0H$fC!XbD +@b[N$+ecGH0iXmEpL-Vhq#F#BEGiV"UHAIc%8q2X*3m(RMaLFRfBcZ16HC5Mdq$C +$iBFh'%`j9aPFlepL+(,[2%241fFBh,*1-"5lGC6"rHBKKZ,Apc&iA0[&81,+GSD +5PlF`P,UiJF(c`PU'dZG@-ALGAFE`cZP&$0iRjc'816k,SHbaD3c[(TR%i(0i(%1 +jJk-BbZmIaP"Klb!'mqlq$"9hpQ@SY+-R3q9YGSBU@fd-96GhBI$GQ-V`h[S1$(l +VNKLUV@R$8(ee!N10PDdBr*HhB+LjY"P$`1*)KX#&B3a"md-BDXeY`&"lGKf'pfI +@BJLHAT1KcY4U$(8R9f@S0l%L3rhaj4JDM#h$d("dDBB24TCJD$5m'%2)8&H'aS0 +G'$iFk-33f[mP3eLrj`cKIA-CQ[4qb"$4mcj$T1-13j6p&N26c1X-dEBV$-h5,c) +dlh+1iD1dd``aUFFC@R3m`Q$TF*!!)6Cj,d2,T*d-VGTZBiKVXjQKGH*kK[L%03` +IakpJ5)KE`["*b`8-LCBj$*r'c'"Sdh`+`fI4%aMD4SeKq$aL"%05q"#'GU%$'*) +Epf0ShkJh3iH'$SD8qTN-(HZQ-eL$daK5DhGNk"58c*!!&Y#@SE0r)N1Ak[%-AIe +D-U6laM"N9)PQX&@+B1KQ$QA),0q)i3ZIqJcfXX%-hEf$'"aHrJ`p22dBHTDX`Y$ +,`mc3fpf(SBqE0d2I)Ti-AjSm'2S9FQ2ibYR%d,q!-m2A1KN-d2PQS$a)(L`2NBI ++`q6KmJKjT$a+(Lf2NFI+iq6amJ4jSMa*RLa2NDI+dq6TmJajTMa,RLh2NHI+mq6 +jmJ*jSEa)AL`[NCI+bq6PmJTjTEa+ALer)kq4emVVj'rPpI)'HD1m5GiXEj'hbYr +*fq6YmJljHhQR[%[H,Hq4pmVlj2hb!IQJI%Jq,2mJ(j'2bXIN(qAMmJRjT(a+2Lf +INFr+2mRRj22b"IPRqD*m5EiXrb*INDr+eq4IjH[b$IQQr*Ym5liYCmQrbhINZr) +pq3rj[T`YjmJ2j)Ib)rQar+HF+cq4RmV2j1IbAr,ImJ[jTIa+cVrAq2IZa#8h`e( +[M,(L!aX+KPXLBSbe5VT9#0!Y3m18p"i1`e(jTiGr6K,QYpFN0E5riJD$A(+l,R' +2l@@cfXefDrGZ2H`TeP*4GUXe[NqQe4`@CXjXRfje1+cr!`IL!!!: