// cyber.c // // by John D. de Boer #include "common.h" #include "cstring.h" #include "cyber.h" // Cursors static CCrsrHandle rescursor(int ID) { CCrsrHandle C; C=GetCCursor(ID); if (!C) halt(cat(0,"Couldn't find cursor #",fig(ID))); //unpurgeable(C); DetachResource((Handle)C); return C; } cursor getcursor(const char *Name) { long Q; if (parseinteger(Name,&Q)) return rescursor(Q); beep(); return NULL; } void setcursor(cursor C) { SetCCursor(C); } void defaultcursor(void) { InitCursor(); } // Text resources #include "disk.h" string gettext(const char *S) { CFStringRef Name; CFBundleRef Bundle; CFURLRef URL; FSRef FSR; file F; bool R; string T; if (!S || !*S) return NULL; Bundle=CFBundleGetMainBundle(); if (!Bundle) return NULL; Name=macstring(S); URL=CFBundleCopyResourceURL(Bundle,Name,CFSTR("txt"),NULL); if (!URL) return NULL; R=CFURLGetFSRef(URL,&FSR); if (!R) return NULL; //release Bundle, URL, Name R=openfile(&FSR,&F); // calling up to disk.c here. Not ideal if (!R) return NULL; setpath(&F); T=filetocharpointer(); closefile(&F); return T; } // GDevices static void stddevicerect(GDHandle Dev, Rect *R) { GDHandle Main; if (!R) return; Main=GetMainDevice(); if (!Dev) Dev=Main; *R=(*Dev)->gdRect; if (Dev==Main) R->top+=GetMBarHeight(); InsetRect(R,5,5); } void findzoomrect(WindowPtr WP, Rect *R) { int TITLEHEIGHT; //GDHandle ZoomDev; Rect SR,CR; OSStatus err; if (!R) return; //err=GetWindowGreatestAreaDevice(WP,kWindowContentRgn,&ZoomDev,R); //if (WP) { // err=GetWindowBounds(WP,kWindowStructureRgn,&SR); // err=GetWindowBounds(WP,kWindowContentRgn,&CR); // SR=((WindowPeek)WP)->strucRgn; // TITLEHEIGHT= CR.top - SR.top - 1; // ZoomDev=deviceofmaxintersection(R); // err=GetWindowGreatestAreaDevice(WP,kWindowContentRgn,&ZoomDev,R); // stddevicerect(ZoomDev,R); R->top+=TITLEHEIGHT; // } //else { TITLEHEIGHT=20; stddevicerect(NULL,R); R->top+=TITLEHEIGHT; //} } // Images enum { extNR,extPNG,extJPG }; picture urlpicture(CFURLRef URL, int TYPE) { CGDataProviderRef Prov; CGImageRef Im; if (!URL) return NULL; Prov=CGDataProviderCreateWithURL(URL); if (!Prov) return NULL; switch (TYPE) { case extPNG: Im=CGImageCreateWithPNGDataProvider(Prov,NULL,0,kCGRenderingIntentAbsoluteColorimetric); break; case extJPG: Im=CGImageCreateWithJPEGDataProvider(Prov,NULL,0,kCGRenderingIntentAbsoluteColorimetric); break; default: return NULL; } //release Provider return Im; } picture getpicture(const char *S) { CFStringRef Name; CFBundleRef Bundle; CFURLRef URL; int TYPE; CGImageRef Im; if (!S || !*S) return NULL; Bundle=CFBundleGetMainBundle(); if (!Bundle) return NULL; Name=macstring(S); TYPE=extNR; URL=CFBundleCopyResourceURL(Bundle,Name,CFSTR("png"),NULL); if (URL) TYPE=extPNG; if (!URL) { URL=CFBundleCopyResourceURL(Bundle,Name,CFSTR("jpg"),NULL); if (URL) TYPE=extJPG; } if (!URL) { URL=CFBundleCopyResourceURL(Bundle,Name,CFSTR("jpeg"),NULL); if (URL) TYPE=extJPG; } if (!URL) return NULL; Im=urlpicture(URL,TYPE); //release Bundle, URL, Name return Im; } picture filepicture(FSRef *F) { CFURLRef URL; OSErr err; HFSUniStr255 outName; int i,TYPE; char *S; CGImageRef Im; if (!F) return NULL; URL=CFURLCreateFromFSRef(NULL,F); if (!URL) return NULL; err=FSGetCatalogInfo(F,kFSCatInfoNone,NULL,&outName,NULL,NULL); if (err) return NULL; S=pointer(outName.length + 1); for (i=0;iwidth=W; B->height=H; B->rowbytes= 4 * W; B->bytes= B->rowbytes * H; B->rect.origin.x=0.0; B->rect.origin.y=0.0; B->rect.size.width=W; B->rect.size.height=H; B->data=pointer(B->bytes); B->space=CGColorSpaceCreateDeviceRGB(); B->context=CGBitmapContextCreate(B->data,B->width,B->height,8,B->rowbytes,B->space,kCGImageAlphaPremultipliedLast); if (!B->context) halt("newbitmap() error #1"); setcolour(&Grey,grey); CGContextSetStrokeColorSpace(B->context,B->space); CGContextSetFillColorSpace(B->context,B->space); CGContextSetStrokeColor(B->context,Grey.c); CGContextSetFillColor(B->context,Grey.c); CGContextSetShouldAntialias(B->context,0); setpixels(B,B->rect,&Grey); return B; } bitmap *extractbitmap(picture P) { bitmap *B; if (!P) return NULL; B=newbitmap(CGImageGetWidth(P),CGImageGetHeight(P)); if (!B) return NULL; CGContextDrawImage(B->context,B->rect,P); return B; } picture wrapbitmap(bitmap *B) { CGDataProviderRef P; CGImageRef Im; if (!B) return NULL; P=CGDataProviderCreateWithData(NULL,B->data,B->bytes,NULL); if (!P) halt("wrapbitmap() error #1"); Im=CGImageCreate(B->width,B->height,8,32,B->rowbytes,B->space,kCGImageAlphaPremultipliedLast,P,NULL,0,kCGRenderingIntentAbsoluteColorimetric); if (!Im) halt("wrapbitmap() error #2"); //CGDataProviderRelease(P); // can release? return Im; } bitmap *getbitmap(const char *S) { CGImageRef Im; bitmap *B; Im=getpicture(S); if (!Im) return NULL; B=extractbitmap(Im); CGImageRelease(Im); return B; } void oldbitmap(bitmap *B) { if (!B) return; old(B->data); CGContextRelease(B->context); old(B); } void setpixels(bitmap *B, rect R, const colour *C) { if (!B || !B->context || !C) return; CGContextSetFillColor(B->context,C->c); CGContextFillRect(B->context,R); } void setpixel(bitmap *B, int X, int Y, const colour *C) { CGRect R; setrect(&R,X,Y,1,1); setpixels(B,R,C); } bool getpixel(const bitmap *B, int X, int Y, colour *C) { long OFF; UInt16 *I,i,j; if (!B || !B->data || !C) return 0; if (!range(X,B->width) || !range(Y,B->height)) return 0; Y= B->height - Y - 1; OFF= (Y * B->rowbytes) + (X * 4); I=((void *)B->data) + OFF; i=I[0]; j=I[1]; C->c[0]= (i & 0xFF) / (float)0xFF; C->c[1]= (i >> 8) / (float)0xFF; C->c[2]= (j & 0xFF) / (float)0xFF; C->c[3]= (j >> 8) / (float)0xFF; return 1; } void drawbitmap(bitmap *B, CGContextRef WQ, rect R) { CGDataProviderRef P; CGImageRef Im; if (!B || !WQ) return; P=CGDataProviderCreateWithData(NULL,B->data,B->bytes,NULL); if (!P) halt("drawbitmap() error #1"); Im=CGImageCreate(B->width,B->height,8,32,B->rowbytes,B->space,kCGImageAlphaPremultipliedLast,P,NULL,0,kCGRenderingIntentAbsoluteColorimetric); if (!Im) halt("drawbitmap() error #2"); CGDataProviderRelease(P); CGContextDrawImage(WQ,R,Im); CGImageRelease(Im); } // MLTE static void setmargins(TXNObject Obj, int MARG) { OSStatus err; TXNControlTag Tags[1]; TXNControlData Data[1]; TXNMargins Margins; Margins.topMargin=MARG; Margins.leftMargin=MARG; Margins.bottomMargin=MARG; Margins.rightMargin=MARG; Tags[0]=kTXNMarginsTag; Data[0].marginsPtr=&Margins; err=TXNSetTXNObjectControls(Obj,0,1,Tags,Data); } void setTEfont(TXNObject TE, TXNOffset START, TXNOffset END, SInt16 FONT) { OSStatus err; TXNTypeAttributes Attr; if (!TE) return; Attr.tag=kTXNQDFontFamilyIDAttribute; Attr.size=kTXNQDFontFamilyIDAttributeSize; Attr.data.dataValue=FONT; err=TXNSetTypeAttributes(TE,1,&Attr,START,END); } void setTEsize(TXNObject TE, TXNOffset START, TXNOffset END, SInt16 SIZE) { OSStatus err; TXNTypeAttributes Attr; if (!TE) return; Attr.tag=kTXNQDFontSizeAttribute; Attr.size=kTXNFontSizeAttributeSize; Attr.data.dataValue= SIZE << 16; // Fixed format err=TXNSetTypeAttributes(TE,1,&Attr,START,END); } void setTEstyle(TXNObject TE, TXNOffset START, TXNOffset END, Style STYLE) { OSStatus err; TXNTypeAttributes Attr; if (!TE) return; Attr.tag=kTXNQDFontStyleAttribute; Attr.size=kTXNQDFontStyleAttributeSize; Attr.data.dataValue=STYLE; err=TXNSetTypeAttributes(TE,1,&Attr,START,END); } void setTEcolour(TXNObject TE, TXNOffset START, TXNOffset END, colour *C) { OSStatus err; TXNTypeAttributes Attr; RGBColor RGB; if (!TE || !C) return; RGB.red= 0xFFFF * C->c[0]; RGB.green= 0xFFFF * C->c[1]; RGB.blue= 0xFFFF * C->c[2]; Attr.tag=kTXNQDFontColorAttribute; Attr.size=kTXNQDFontColorAttributeSize; Attr.data.dataPtr=&RGB; err=TXNSetTypeAttributes(TE,1,&Attr,START,END); } #define GenevaFontID (3) TXNObject createtextobj(WindowPtr WP, char *Text, int LEN, int TLEN, float Size, float Margin) { TXNObject TE; OSStatus err; TXNFrameOptions TOpt; TXNFrameID ID; if (!WP) return NULL; TOpt= kTXNDrawGrowIconMask | kTXNWantVScrollBarMask | kTXNNoSelectionMask | kTXNAlwaysWrapAtViewEdgeMask | kTXNDoNotInstallDragProcsMask; //err=TXNCreateObject(NULL,TOpt,&TE); //if (!TE) return NULL; //err=TXNAttachObjectToWindowRef(TE,WP); // Initial view rect always incorrect. TXNNewObject() worked better. :-( err=TXNNewObject(NULL,WP,NULL,TOpt,kTXNTextEditStyleFrameType,kTXNTextFile,1,&TE,&ID,0); if (!TE) return NULL; err=TXNSetData(TE,kTXNTextData,Text,LEN,0,0); setTEfont(TE,0,LEN,GenevaFontID); setTEsize(TE,0,LEN,Size); setTEstyle(TE,0,TLEN,bold); setmargins(TE,Margin); err=TXNSetSelection(TE,0,0); TXNShowSelection(TE,0); // not reqr with TXNCreateObject() return TE; } // Preferences static void setprefnumber(const char *Key, void *Value, CFNumberType Type) { CFStringRef CFK; CFNumberRef CFN; if (!Key || !*Key || !Value) return; CFK=CFStringCreateWithCString(NULL,Key,kCFStringEncodingMacRoman); if (!CFK) return; CFN=CFNumberCreate(NULL,Type,Value); if (!CFN) return; CFPreferencesSetAppValue(CFK,CFN,kCFPreferencesCurrentApplication); CFRelease(CFK); CFRelease(CFN); } void setprefbool(const char *Key, bool Value) { SInt8 V; V=Value; setprefnumber(Key,&V,kCFNumberSInt8Type); } void setprefshort(const char *Key, short Value) { SInt16 V; V=Value; setprefnumber(Key,&V,kCFNumberSInt16Type); } void setpreflong(const char *Key, long Value) { SInt32 V; V=Value; setprefnumber(Key,&V,kCFNumberSInt32Type); } void setpreffloat(const char *Key, float Value) { Float32 V; V=Value; setprefnumber(Key,&V,kCFNumberFloat32Type); } void saveprefs(void) { CFPreferencesAppSynchronize(kCFPreferencesCurrentApplication); } bool getprefnumber(const char *Key, void *Value, CFNumberType Type) { CFStringRef CFK; CFNumberRef CFN; bool Ok; if (!Key || !*Key || !Value) return 0; CFK=CFStringCreateWithCString(NULL,Key,kCFStringEncodingMacRoman); if (!CFK) return 0; CFN=(CFNumberRef)CFPreferencesCopyAppValue(CFK,kCFPreferencesCurrentApplication); if (!CFN) { CFRelease(CFK); return 0; } Ok=CFNumberGetValue(CFN,Type,Value); CFRelease(CFK); CFRelease(CFN); return Ok; } bool getprefbool(const char *Key, bool *Value) { bool Ok; SInt8 V; Ok=getprefnumber(Key,&V,kCFNumberSInt8Type); if (Ok) *Value=V; return Ok; } bool getprefshort(const char *Key, short *Value) { bool Ok; SInt16 V; Ok=getprefnumber(Key,&V,kCFNumberSInt16Type); if (Ok) *Value=V; return Ok; } bool getpreflong(const char *Key, long *Value) { bool Ok; SInt32 V; Ok=getprefnumber(Key,&V,kCFNumberSInt32Type); if (Ok) *Value=V; return Ok; } bool getpreffloat(const char *Key, float *Value) { bool Ok; Float32 V; Ok=getprefnumber(Key,&V,kCFNumberFloat32Type); if (Ok) *Value=V; return Ok; }