ftp.nice.ch/pub/next/connectivity/news/Alexandra-0.9.s.tar.gz#/alex/FaceView.m

This is FaceView.m in view mode; [Download] [Up]

#import "FaceView.h"
#import <c.h>
#import <ctype.h>
#import "FaceFileCache.h"

@implementation FaceView

//-----------------------------------------------------------------------
// PRIVATE METHODS
//-----------------------------------------------------------------------

// In Ermangelung der passenden RFC eine einfache Heuristik. Vom '@' ausgehend
// wird der Anfang und das Ende des Logins gesucht.
// Fuer eine "richtige" Loesung: Was gibt's fuer Formate?
//   1) login 
//   2) login (real name)
//   3) "real name" <login>
//   4) real name <login>
//   ...

#define islogin(c) (isalnum(c) || (c)=='.' || (c)=='_' || (c)=='%' || (c)=='-')

- (char *)loginForName:(const char *)userName;
	{
	char		login[300],*at,*p;
	int			n;
	
	at=strchr(userName,'@');
	if(at)
		{
		n=1;
		for(p=at+1;islogin(*p);p++)
			n++;
		for(p=at-1;p>=userName && islogin(*p);p--)
			n++;
		strncpy(login,p+1,MIN(n,sizeof(login)));
		login[MIN(n,sizeof(login)-1)]='\0';
		for(p=login;*p;p++)
#if 0 // [TRH 20-Jan-97] disabled for use with FaceFileCache
			if(*p=='!' || *p=='@')
				*p='.';
			else
#endif
				*p=NXToLower(*p);
		at=NXCopyStringBufferFromZone(login,[self zone]);
		}
	return at;
	}


- (FaceFileCache *)globalFaceFileCache
{
	static FaceFileCache *theCache;

	if (theCache == nil)
	{
		theCache = [[FaceFileCache allocFromZone:[self zone]]
			    initWithDirectory:"/LocalLibrary/Images/People"];
	}
	return theCache;
}

- (FaceFileCache *)userFaceFileCache
{
	static FaceFileCache *theCache;

	if (theCache == nil)
	{
		theCache = [[FaceFileCache allocFromZone:[self zone]]
			    initWithDirectory:"~/Library/Images/People"];
	}
	return theCache;
}

// NewsGrazer Methode. Mail ist cleverer und sieht noch in der Aliases-Datei nach
// und testet auf lokalen Benutzer...
// [TRH 20-Jan-97] fixed by the use of FaceFileCache

- (const char *)filenameForLogin:(const char *)login
	{
#if 0
	char buf[MAXPATHLEN+1];
	
	sprintf(buf,"/LocalLibrary/Images/People/%s.tiff",login);
	return NXCopyStringBufferFromZone(buf,[self zone]);	
#endif
	const char *result = [[self userFaceFileCache] filenameForLogin:login];

	if (result == NULL)
		{
		result = [[self globalFaceFileCache] filenameForLogin:login];
		}
	return result;
	}


//-----------------------------------------------------------------------
// INSTANCE VAR
//-----------------------------------------------------------------------

- setImage:(NXImage *)anImage;
	{
	myImage=anImage;
	return self;
	}


- (NXImage *)image;
	{
	return myImage;
	}


//-----------------------------------------------------------------------
// SET IMAGE FROM LOGIN NAME
//-----------------------------------------------------------------------
- (BOOL)showFaceForName:(const char *)name;
	{
	NXImage		*image=nil;
	const char	*imageFile,*login;

	if(name && (login=[self loginForName:name])!=NULL)
		{
		image=[NXImage findImageNamed:login];
		if(!image)
			{
			imageFile=[self filenameForLogin:login];
			if (imageFile)
				{
			image=[[NXImage allocFromZone:[self zone]] initFromFile:imageFile];
				NXZoneFree([self zone],(void*)imageFile);
				}
			if(image && [image lockFocus])
				{
				NXSize size, newsize={64,64};

				[image unlockFocus];
				// [TRH] Don't scale image if it isn't necessary,
				// and keep size/width proportions intact if it is.
				[image getSize:&size];
				if (size.height > newsize.height || size.width > newsize.width)
					{
					if (size.height > size.width)
						newsize.width=newsize.width*size.width/size.height;
					else if (size.height < size.width)
						newsize.height = newsize.height*size.height/size.width;
					[image setScalable:YES];
					[image setSize:&newsize];
					}
				[image setName:login];
				}
			else
				image=[image free];
			}
		NXZoneFree([self zone],(void*)login);
		}
	[self setImage:image];
	[self display];
	return image? TRUE : FALSE;
	}


//-----------------------------------------------------------------------
// DRAWING
//-----------------------------------------------------------------------

- drawSelf:(const NXRect *)rects :(int)rectCount
	{
	//[super drawSelf:rects:rectCount];
	PSsetgray(NX_LTGRAY);
	NXRectFill(&bounds);
	if(myImage)
		{
#define NR_RECTS 6
		NXRect frects[NR_RECTS];
		float	fgrays[NR_RECTS]={NX_DKGRAY,NX_DKGRAY,NX_DKGRAY,NX_DKGRAY,NX_BLACK,NX_BLACK};
		NXPoint p = bounds.origin; //={1,2};
		NXSize size;

		// [TRH] Shrinkwrap rects around image.
		[myImage getSize:&size];
		// left-align horizontally, center vertically.
		p.x += 1;
		p.y += 2 + (bounds.size.height - 3 - size.height)/2;
		NXSetRect(&frects[0],p.x+2,p.y-2,size.width+1,1);
		NXSetRect(&frects[1],p.x+size.width+1,p.y-2,2,size.height+1);
		NXSetRect(&frects[2],p.x-1,p.y-1,1,size.height+2);
		NXSetRect(&frects[3],p.x-1,p.y+size.height,size.width+2,1);
		NXSetRect(&frects[4],p.x-1,p.y-1,size.width+1,1);
		NXSetRect(&frects[5],p.x+size.width,p.y-1,1,size.height+2);
		NXRectFillListWithGrays(frects,fgrays,NR_RECTS);
		[myImage composite:NX_SOVER toPoint:&p];

		}
	else
		{
		NXPoint imgorigin={0,2};
		[[NXImage findImageNamed:"of"] composite:NX_SOVER toPoint:&imgorigin];
		}
	return self;
	}
	

//-----------------------------------------------------------------------
// THAT'S IT
//-----------------------------------------------------------------------

@end

These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.