This is SmallCard.m in view mode; [Download] [Up]
/* indent:4 tabsize:8 font:fixed-width */ #import "CardSet.h" #import "SmallCard.h" /*--------------------------------------------------------------------------- | | Card Globals | | The arrays _CardPipPositions and _CardCardPips provide information about | the positioning of pips on cards. There are 17 possible positions, | described in pipPositions, which are selectively refrerred to for each | of 13 possible card values by a character string. | | The letters A-Q are used to represent pips present in the given card. | | The id's _CardFront, _CardBack etc... are images shared by all instances | of Card | \---------------------------------------------------------------------------*/ static NSPoint _CardPipPositions[] = { {13, 91}, {30, 91}, {47, 91}, {30, 78}, {30, 71}, {13, 64}, {47, 64}, {13, 52}, {30, 52}, {47, 52}, {13, 39}, {47, 39}, {30, 32}, {30, 25}, {13, 13}, {30, 13}, {47, 13} }; extern char *_CardCardPips[]; // WARNING: Because these static variables have the same names as static // variables in the superclass, override any methods that access // them. The same goes for "_CardPipPositions" above. static NSImage* _CardFrontImage = nil; static NSImage* _CardBackImage = nil; static NSImage* _CardSymbolsImage = nil; static NSImage* _CardKingClubsImage = nil; static NSImage* _CardKingDiamondsImage = nil; static NSImage* _CardKingHeartsImage = nil; static NSImage* _CardKingSpadesImage = nil; static NSImage* _CardQueenClubsImage = nil; static NSImage* _CardQueenDiamondsImage = nil; static NSImage* _CardQueenHeartsImage = nil; static NSImage* _CardQueenSpadesImage = nil; static NSImage* _CardJackClubsImage = nil; static NSImage* _CardJackDiamondsImage = nil; static NSImage* _CardJackHeartsImage = nil; static NSImage* _CardJackSpadesImage = nil; static NSImage* _CardAceOfSpadesImage = nil; static NSImage* _preDrawnImage[52]; static BOOL _preDrawnImagesAvailable; @implementation SmallCard /*" Instances of this class provide the same functionality as our superclass Card, except that they draw themselves more compactly. The only methods that differ from our superclass are ones that are concerned with display. "*/ //------------------------------------------------------------------- // Initializing the class //------------------------------------------------------------------- + (void) initialize /*" Initializes the class object. The partial card images from CardSet TIFFS are loaded here. "*/ { if (self == [SmallCard class]) { NSBundle* bundle = [NSBundle bundleForClass:self]; NSString* imagePath = nil; imagePath = [bundle pathForResource:@"sCard" ofType:@"tiff"]; _CardFrontImage = [[NSImage alloc] initWithContentsOfFile:imagePath]; imagePath = [bundle pathForResource:@"sBack" ofType:@"tiff"]; _CardBackImage = [[NSImage alloc] initWithContentsOfFile:imagePath]; imagePath = [bundle pathForResource:@"sKingClubs" ofType:@"tiff"]; _CardKingClubsImage = [[NSImage alloc] initWithContentsOfFile:imagePath]; imagePath = [bundle pathForResource:@"sKingDiamonds" ofType:@"tiff"]; _CardKingDiamondsImage = [[NSImage alloc] initWithContentsOfFile:imagePath]; imagePath = [bundle pathForResource:@"sKingHearts" ofType:@"tiff"]; _CardKingHeartsImage = [[NSImage alloc] initWithContentsOfFile:imagePath]; imagePath = [bundle pathForResource:@"sKingSpades" ofType:@"tiff"]; _CardKingSpadesImage = [[NSImage alloc] initWithContentsOfFile:imagePath]; imagePath = [bundle pathForResource:@"sQueenClubs" ofType:@"tiff"]; _CardQueenClubsImage = [[NSImage alloc] initWithContentsOfFile:imagePath]; imagePath = [bundle pathForResource:@"sQueenDiamonds" ofType:@"tiff"]; _CardQueenDiamondsImage = [[NSImage alloc] initWithContentsOfFile:imagePath]; imagePath = [bundle pathForResource:@"sQueenHearts" ofType:@"tiff"]; _CardQueenHeartsImage = [[NSImage alloc] initWithContentsOfFile:imagePath]; imagePath = [bundle pathForResource:@"sQueenSpades" ofType:@"tiff"]; _CardQueenSpadesImage = [[NSImage alloc] initWithContentsOfFile:imagePath]; imagePath = [bundle pathForResource:@"sJackClubs" ofType:@"tiff"]; _CardJackClubsImage = [[NSImage alloc] initWithContentsOfFile:imagePath]; imagePath = [bundle pathForResource:@"sJackDiamonds" ofType:@"tiff"]; _CardJackDiamondsImage = [[NSImage alloc] initWithContentsOfFile:imagePath]; imagePath = [bundle pathForResource:@"sJackHearts" ofType:@"tiff"]; _CardJackHeartsImage = [[NSImage alloc] initWithContentsOfFile:imagePath]; imagePath = [bundle pathForResource:@"sJackSpades" ofType:@"tiff"]; _CardJackSpadesImage = [[NSImage alloc] initWithContentsOfFile:imagePath]; imagePath = [bundle pathForResource:@"sAceOfSpades" ofType:@"tiff"]; _CardAceOfSpadesImage = [[NSImage alloc] initWithContentsOfFile:imagePath]; imagePath = [bundle pathForResource:@"sSymbols" ofType:@"tiff"]; _CardSymbolsImage = [[NSImage alloc] initWithContentsOfFile:imagePath]; } } + (void) drawCardImages /*" Creates shared NSImage caches of all 52 cards in the deck. Uses the instance method #preDrawCards: to do the actual drawing. "*/ { Card* tempCard; int i,j; NSSize aSize; if(_preDrawnImagesAvailable) return; // don't draw again aSize = [_CardFrontImage size]; for(i=0; i<4; i++){ for(j=0; j<13; j++){ tempCard = [[SmallCard alloc] initSuit:i value:j faceUp:YES]; _preDrawnImage[(i*13)+j] = [[NSImage alloc] initWithSize:aSize]; [_preDrawnImage[(i*13)+j] addRepresentation: [[[NSCustomImageRep alloc] initWithDrawSelector:@selector(preDrawCard:) delegate:tempCard] autorelease]]; [_preDrawnImage[(i*13)+j] lockFocus]; [_preDrawnImage[(i*13)+j] unlockFocus]; [tempCard release]; } } _preDrawnImagesAvailable = YES; return; } + (void) freeCardImages /*" Frees the shared NSImage caches of all 52 cards. "*/ { int i; if(!_preDrawnImagesAvailable) return; // don't free again for(i=0; i<52; i++){ [_preDrawnImage[i] release]; } _preDrawnImagesAvailable = NO; return; } + (void) setCardBackImage:theImage /*" Sets a custom image used to draw the back of the card. "*/ { if(theImage) { [_CardBackImage autorelease]; _CardBackImage = [theImage copyWithZone:[self zone]]; } return; } + (void) setCardBack:(CardBack)aBack /*" Sets the card back used to draw the back of the card. _{#{Constant Image}} _{CS_DEFAULT Original image from version 1.0.} _{CS_TRAD Traditional pattern.} _{CS_SHIP Ship at sea.} _{CS_CUSTOM Custom image.} "*/ { NSBundle* bundle = [NSBundle bundleForClass:self]; NSString* imagePath = nil; switch (aBack) { case CS_DEFAULT: imagePath = [bundle pathForResource:@"sBack" ofType:@"tiff"]; break; case CS_TRAD: imagePath = [bundle pathForResource:@"sTradBack" ofType:@"tiff"]; break; case CS_SHIP: imagePath = [bundle pathForResource:@"sShip" ofType:@"tiff"]; break; default: imagePath = [bundle pathForResource:@"sBack" ofType:@"tiff"]; break; } if (imagePath != nil) { NSImage* newImage = [[NSImage alloc] initWithContentsOfFile:imagePath]; if (newImage != nil) { [self setCardBackImage:newImage]; } } } - (void) preDrawCard:(NSImage*)theImage /*" Pre-draws theSharedNSImage, both outline and contents, by calling #drawOutlineAt: and #drawContentsAt: for point {0.0, 0.0}. "*/ { NSPoint thePoint={0.,0.}; [self drawOutlineAt:thePoint]; [self drawContentsAt:thePoint]; } - (void)drawCardAt:(NSPoint)thePoint /*" Draws the card, both outline and contents, at thePoint, by calling #drawOutlineAt: and #drawContentsAt:. If the 52 cards of the deck have been pre-drawn, the shared NSImage cache is used. Otherwise, the card is drawn by compositing the partial images. "*/ { if(_preDrawnImagesAvailable && faceUp){ [_preDrawnImage[(suit*13)+value] compositeToPoint:thePoint operation:NSCompositeSourceOver]; return; } [self drawOutlineAt:thePoint]; [self drawContentsAt:thePoint]; } - (void) drawOutlineAt:(NSPoint)thePoint /*" Draws the card's border at thePoint. "*/ { [_CardFrontImage compositeToPoint:thePoint operation:NSCompositeSourceOver]; } - (void) drawContentsAt:(NSPoint)thePoint /*" Draws the contents of the card (but not the border) at thePoint. "*/ { if (!faceUp) { /*------------------------------------------------------ | | Draw the back of the card | \------------------------------------------------------*/ NSPoint destPoint = {thePoint.x + 6, thePoint.y + 5}; [_CardBackImage compositeToPoint:destPoint operation:NSCompositeSourceOver]; } else { /*--------------------------------------------------------- | | Draw the upper left / lower right value indicator | \---------------------------------------------------------*/ { NSRect sourceRect = {{value * 16, 60}, {8, 15}}; NSPoint destPoint = {thePoint.x + 3, thePoint.y + 106}; if (([self cardColor] == CS_RED)) { sourceRect.origin.x += 8; } [_CardSymbolsImage compositeToPoint:destPoint fromRect:sourceRect operation:NSCompositeSourceOver]; sourceRect.origin.y -= 16; destPoint.x = thePoint.x + 69; destPoint.y = thePoint.y + 6; [_CardSymbolsImage compositeToPoint:destPoint fromRect:sourceRect operation:NSCompositeSourceOver]; } /*---------------------------------------------------------- | | Draw the upper left / lower right suit indicator | \----------------------------------------------------------*/ { NSRect sourceRect = {{suit * 10, 10}, {10, 12}}; NSPoint destPoint = {thePoint.x + 2, thePoint.y + 94}; [_CardSymbolsImage compositeToPoint:destPoint fromRect:sourceRect operation:NSCompositeSourceOver]; sourceRect.origin.x += 40; destPoint.x = thePoint.x + 69; destPoint.y = thePoint.y + 21; [_CardSymbolsImage compositeToPoint:destPoint fromRect:sourceRect operation:NSCompositeSourceOver]; } /*--------------------------------------------------------- | | Draw special card images for face cards and the | ace of spades | \---------------------------------------------------------*/ { NSPoint destPoint = {thePoint.x + 12, thePoint.y + 12}; switch (value) { case CS_JACK: switch (suit) { case CS_CLUBS: [_CardJackClubsImage compositeToPoint:destPoint operation:NSCompositeSourceOver]; break; case CS_DIAMONDS: [_CardJackDiamondsImage compositeToPoint:destPoint operation:NSCompositeSourceOver]; break; case CS_HEARTS: [_CardJackHeartsImage compositeToPoint:destPoint operation:NSCompositeSourceOver]; break; case CS_SPADES: [_CardJackSpadesImage compositeToPoint:destPoint operation:NSCompositeSourceOver]; break; } return; case CS_QUEEN: switch (suit) { case CS_CLUBS: [_CardQueenClubsImage compositeToPoint:destPoint operation:NSCompositeSourceOver]; break; case CS_DIAMONDS: [_CardQueenDiamondsImage compositeToPoint:destPoint operation:NSCompositeSourceOver]; break; case CS_HEARTS: [_CardQueenHeartsImage compositeToPoint:destPoint operation:NSCompositeSourceOver]; break; case CS_SPADES: [_CardQueenSpadesImage compositeToPoint:destPoint operation:NSCompositeSourceOver]; break; } return; case CS_KING: switch (suit) { case CS_CLUBS: [_CardKingClubsImage compositeToPoint:destPoint operation:NSCompositeSourceOver]; break; case CS_DIAMONDS: [_CardKingDiamondsImage compositeToPoint:destPoint operation:NSCompositeSourceOver]; break; case CS_HEARTS: [_CardKingHeartsImage compositeToPoint:destPoint operation:NSCompositeSourceOver]; break; case CS_SPADES: [_CardKingSpadesImage compositeToPoint:destPoint operation:NSCompositeSourceOver]; break; } return; default: break; } /*---------------------------------------------------- | | Not only draw the special image for the ace of | spades, but avoid the standard suit pip drawing | \----------------------------------------------------*/ if ((value == CS_ACE) && (suit == CS_SPADES)) { [_CardAceOfSpadesImage compositeToPoint:destPoint operation:NSCompositeSourceOver]; return; } } /*------------------------------------------------------ | | Draw suit pips on the card based on patterns | defined by the _CardCardSymbols and | _CardCardPips arrays | \------------------------------------------------------*/ { NSRect suitRect = {{suit * 20, 23}, {20, 21}}; NSRect upsideSuitRect = {{80 + suit * 20, 23}, {20, 21}}; char *pipString = _CardCardPips[value]; while (*pipString) { NSPoint tempPoint = _CardPipPositions[*pipString - 'A']; tempPoint.x += thePoint.x; tempPoint.y += thePoint.y; [_CardSymbolsImage compositeToPoint:tempPoint fromRect:(*pipString < 'K') ? suitRect : upsideSuitRect operation:NSCompositeSourceOver]; pipString++; } } } } @end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.