Retired Document
Important: This sample code may not represent best practices for current development. The project may use deprecated symbols and illustrate technologies and techniques that are no longer recommended.
CodecTestMain.c
/* |
File: CodecTestMain.c |
Contains: |
Written by: Mark Krueger |
Copyright: Copyright © 1992-1999 by Apple Computer, Inc., All Rights Reserved. |
You may incorporate this Apple sample source code into your program(s) without |
restriction. This Apple sample source code has been provided "AS IS" and the |
responsibility for its operation is yours. You are not permitted to redistribute |
this Apple sample source code as "Apple sample source code" after having made |
changes. If you're going to re-distribute the source, we require that you make |
it clear in the source that the code was descended from Apple sample source |
code, but that you've made changes. |
Change History (most recent first): |
7/29/1999 Karl Groethe Updated for Metrowerks Codewarror Pro 2.1 |
*/ |
#ifdef THINK_C |
//#define OpenStdCompression OPENSTDCOMPRESSION |
#endif |
#include <QuickTimeComponents.h> |
#include <ImageCompression.h> |
#include "DrawTextCodec.h" |
#define dangerousPattern |
//#define DONT_SHOW_PICTURE |
//#define DONT_DO_PREVIEW |
#include <Types.h> |
#include <Files.h> |
#include <Quickdraw.h> |
#include <Packages.h> |
#include <Memory.h> |
#include <Fonts.h> |
#include <Events.h> |
#include <OSUtils.h> |
#include <ToolUtils.h> |
#include <Menus.h> |
#include <Dialogs.h> |
#include <stdio.h> |
#include <Errors.h> |
#include <Scrap.h> |
#include <Desk.h> |
#include <string.h> |
#include <GestaltEqu.h> |
#include <Resources.h> |
#include <Finder.h> |
#include <palettes.h> |
#include <PictUtils.h> |
#include <QDOffscreen.h> |
#include <Windows.h> |
#include <FixMath.h> |
#include <ImageCodec.h> |
#ifndef THINK_C |
#include <Strings.h> |
#endif |
#include <ImageCompression.h> |
#define appleMenuID 128 |
#define fileMenuID 129 |
#define editMenuID 130 |
#define M_OPEN 1 |
#define M_CLOSE 3 |
#define M_SAVE 4 |
#define M_COMP 6 |
#define M_QUIT 8 |
#define M_COPY 4 |
#define M_PASTE 5 |
#define M_FIT 10 |
Boolean gDitherFlag = false; |
StandardFileReply gOriginalSFR; |
short gOriginalFile; |
Cursor **gWatch; |
short gCompressedFile; |
Boolean gExitFlag = false; |
MenuHandle gMenus[3]; // our menus |
CWindowPtr gActiveWindow = nil; |
CWindowPtr gOrigWindow = nil; |
CWindowPtr gCompWindow = nil; |
Rect gOriginalPicFrame; |
Rect gZoomedPictureFrame; |
Boolean gZoomed = false; |
Boolean gFitToWindow = true; |
Boolean gHasNewStdFile = false; |
PicHandle gOriginalPicture = nil; |
Boolean gCompressed = false; |
Boolean gSevenOh = false; |
short gDepth = 1; |
ComponentInstance gSCComponent; |
SCParams gSCParams; |
Boolean gDidError = false; |
GWorldPtr gworld,compgworld; |
int Initialize(); |
void Error(char *msg); |
pascal OSErr |
Progress(short progressMsg,Fixed progressPercent,long refcon); |
int DoCompression(CWindowPtr window); |
void DoError(); |
void FitRect(Rect *rect,short w,short h); |
void DoOpen(FSSpec *fsp); |
void DoClose(CWindowPtr w); |
void DoSave(CWindowPtr w) ; |
void FixMenus(); |
void DoPaste(); |
void DoCopy(CWindowPtr w); |
void DoUpdate(CWindowPtr w); |
void DoSizeWindow(CWindowPtr wind,short h,short v,Boolean fup); |
void DoZoom(WindowPtr wind); |
void DoGrow(WindowPtr wind,Point *where); |
void DoCommand(long mResult); |
/************************************************ |
* |
* Set up application environment. |
* |
************************************************/ |
int Initialize() |
{ |
Ptr size; |
size = GetApplLimit(); |
SetApplLimit(size - 32*1024); /* make room on stack so Quickdraw can do big pictures */ |
MaxApplZone(); |
/* initialize managers */ |
InitGraf(&qd.thePort); |
InitFonts(); |
InitWindows(); |
InitMenus(); |
InitDialogs(nil); |
InitCursor(); |
ErrorSound(nil); |
/* install menus */ |
if ( (gMenus[0] = GetMenu(appleMenuID)) == nil ) |
return(-1); |
AppendResMenu(gMenus[0], (ResType) 'DRVR'); |
InsertMenu(gMenus[0], 0); |
if ( (gMenus[1] = GetMenu(fileMenuID)) == nil ) |
return(-1); |
InsertMenu(gMenus[1], 0); |
if ( (gMenus[2] = GetMenu(editMenuID)) == nil ) |
return(-1); |
InsertMenu(gMenus[2], 0); |
DrawMenuBar(); |
if ( (gWatch = GetCursor(watchCursor)) == nil ) |
return(-1); |
HNoPurge((Handle)gWatch); |
return(0); |
} |
/************************************************ |
* |
* Report errors as needed. |
* |
************************************************/ |
void Error(char *msg) |
{ |
SysBeep(1); |
ParamText("\pError:",c2pstr(msg),nil,nil); /* oops da baby */ |
Alert(128,nil); |
} |
/************************************************ |
* |
* Progress proc called from the Image Compression manager. |
* |
************************************************/ |
pascal OSErr |
Progress(short progressMsg,Fixed progressPercent,long refcon) |
{ |
OSErr result = noErr; |
short kind; |
Handle h; |
Rect r; |
CGrafPtr savePort,wmgPort; |
GDHandle saveGD; |
static DialogPtr progressDialog = 0; |
KeyMap keys; |
switch (progressMsg) { |
case codecProgressOpen: |
progressDialog = 0; |
GetGWorld(&savePort,&saveGD); |
GetCWMgrPort(&wmgPort); |
SetGWorld(wmgPort,nil); |
if ( refcon != -1 && (progressDialog = GetNewDialog(5002, 0, (WindowPtr)-1)) != nil ) { |
ShowWindow((WindowPtr)progressDialog); |
SetGWorld((CGrafPtr)progressDialog,nil); |
DrawDialog(progressDialog); |
GetDialogItem(progressDialog, 1, &kind, &h, &r); |
InsetRect(&r, -1, -1); |
FrameRect(&r); |
InsetRect(&r, 1, 1); |
} |
SetGWorld(savePort,saveGD); |
break; |
case codecProgressUpdatePercent: |
if ( progressDialog ) { |
GetGWorld(&savePort,&saveGD); |
SetGWorld((CGrafPtr)progressDialog,nil); |
GetDialogItem(progressDialog, 1, &kind, &h, &r); |
FillRect(&r,&qd.gray); |
r.right = r.left + FixRound( FixMul(progressPercent, FixRatio(r.right-r.left,1))); |
PaintRect(&r); |
SetGWorld(savePort,saveGD); |
} |
/* check for command period - not the best way, but it works */ |
GetKeys(keys); |
if ( (keys[1] & 0x8000) && ((0x800000 & keys[1]) || (0x2000000 & keys[1]) ) ) |
result = codecAbortErr; |
break; |
case codecProgressClose: |
if ( progressDialog ) |
DisposeDialog(progressDialog); |
progressDialog = 0; |
break; |
} |
return(result); |
} |
/************************************************ |
* |
* Allow the user to specify compression and an output file, and then |
* compress the picture and save the result in that file. |
* |
************************************************/ |
int DoCompression(CWindowPtr window) |
{ |
/* StdFile stuff */ |
CGrafPtr savePort; |
GDHandle saveGD; |
/* for sepecifying compression */ |
Rect pictureFrame; |
OSErr result; |
Point where; |
ImageDescriptionHandle desc = nil; |
Ptr data = nil; |
long cdsize; |
ICMProgressProcRecord *progP,progressRec; |
Str255 buf; |
GrafPtr wmPort; |
progressRec.progressProc = NewICMProgressProc(Progress); |
progressRec.progressRefCon = 0; |
progP = &progressRec; |
if ( window == nil ) |
return -1; |
pictureFrame = ((CGrafPtr)window)->portRect; |
/************************************************ |
* |
* Ask how the user wants to compress it. |
* |
************************************************/ |
SetCursor(&qd.arrow); |
if (SCSetTestImagePixMap(gSCComponent,gworld->portPixMap,&gworld->portRect,0)) |
goto done; |
GetWMgrPort(&wmPort); |
SetPort(wmPort); |
where.h = where.v = -2; // position dialog on the best device |
if (SCGetCompression(gSCComponent,&gSCParams,where)) |
goto done; |
/************************************************ |
* |
* Ask her for the name of the new file. |
* |
************************************************/ |
SetCursor(*gWatch); |
if ( (result=GetMaxCompressionSize(gworld->portPixMap,&gworld->portRect, |
gSCParams.depth,gSCParams.spatialQuality,gSCParams.theCodecType, |
gSCParams.theCodec,&cdsize)) != noErr ) { |
Error("getting max comp size"); |
goto done; |
} |
if ( (data=NewPtr(cdsize)) == nil ) { |
Error("no mem for picture"); |
goto done; |
} |
desc = (ImageDescriptionHandle)NewHandle(sizeof(ImageDescription)); |
if ( desc == nil ) { |
DisposePtr(data); |
Error("no mem for picture"); |
goto done; |
} |
if ( (result=FCompressImage(gworld->portPixMap,&gworld->portRect, |
gSCParams.depth,gSCParams.spatialQuality,gSCParams.theCodecType, |
gSCParams.theCodec,nil,0,0,nil,progP, |
desc,data)) != noErr ) { |
DisposePtr(data); |
DisposeHandle((Handle)desc); |
if ( result != codecAbortErr ) |
Error("compressing picture"); |
goto done; |
} |
NumToString((*desc)->dataSize,buf); |
ParamText("\pCompressed to ",buf,"\pBytes",nil); |
Alert(128,nil); |
GetGWorld(&savePort,&saveGD); |
SetGWorld(compgworld,nil); |
if ( (result=DecompressImage(data,desc,compgworld->portPixMap, |
&gworld->portRect,&compgworld->portRect,ditherCopy,nil)) != noErr ) { |
DisposePtr(data); |
DisposeHandle((Handle)desc); |
Error("compressing picture"); |
goto done; |
} |
DisposePtr(data); |
DisposeHandle((Handle)desc); |
SetGWorld(gCompWindow,nil); |
InvalRect(&gCompWindow->portRect); |
SetGWorld(savePort,saveGD); |
done: |
gDidError = false; |
SetCursor(&qd.arrow); |
return(result); |
} |
void DoError() |
{ |
CGrafPtr savePort; |
GDHandle saveGD; |
RGBColor opColor; |
GetGWorld(&savePort,&saveGD); |
SetGWorld(compgworld,nil); |
if ( !gDidError ) { |
gDidError = true; |
opColor.red = opColor.green = opColor.blue = 0; |
OpColor(&opColor); |
CopyBits((BitMap *)*gworld->portPixMap,(BitMap *)*((CGrafPtr)compgworld)->portPixMap, |
&gworld->portRect,&compgworld->portRect,subPin,nil); |
} |
opColor.red = opColor.green = opColor.blue = 0xffff; |
OpColor(&opColor); |
CopyBits((BitMap *)*compgworld->portPixMap,(BitMap *)*((CGrafPtr)compgworld)->portPixMap, |
&compgworld->portRect,&compgworld->portRect,addPin,nil); |
SetGWorld(gCompWindow,nil); |
InvalRect(&gCompWindow->portRect); |
SetGWorld(savePort,saveGD); |
} |
/************************************************ |
* |
* Massage a rectangle to fit on a device's screen. |
* |
************************************************/ |
void FitRect(Rect *rect,short w,short h) |
{ |
short n; |
Rect dRect; |
GDHandle gd; |
// dRect = *rect; |
gd = GetGDevice(); |
dRect =(*gd)->gdRect; |
dRect.top += 40; /* make way for title bar */ |
InsetRect(&dRect,16,16); |
if ( w < (dRect.right-dRect.left) && h < (dRect.bottom-dRect.top) ) { |
dRect.right = dRect.left + w; |
dRect.bottom = dRect.top + h; |
} else if ( gFitToWindow ) { |
n = dRect.top + ((dRect.right -dRect.left) * h)/w; |
if ( n > dRect.bottom ) |
dRect.right = dRect.left +((dRect.bottom -dRect.top) * w)/h; |
else |
dRect.bottom = n; |
} |
*rect = dRect; |
} |
/************************************************ |
* |
* Ask the user for a pict file to open and open it. |
* |
************************************************/ |
void DoOpen(FSSpec *fsp) |
{ |
OpenCPicParams originalPicHeader; |
SFTypeList types = { 'PICT',0 }; |
OSErr result = noErr; |
long size; |
CGrafPtr savePort; |
GDHandle saveGD; |
Rect rect; |
if ( fsp == nil ) { |
if ( gHasNewStdFile ) |
StandardGetFile(nil,1,types,&gOriginalSFR); |
else { |
SFReply osfr; |
Point pt = {100,100}; |
SFGetFile(pt,(ConstStr255Param)"",nil,1,types,nil,&osfr); |
gOriginalSFR.sfGood = osfr.good; |
gOriginalSFR.sfReplacing = osfr.copy; |
gOriginalSFR.sfType = osfr.fType; |
if ( osfr.good ) |
FSMakeFSSpec(osfr.vRefNum,0L,osfr.fName,&gOriginalSFR.sfFile); |
} |
if ( !gOriginalSFR.sfGood ) { |
return ; |
} |
} else { |
gOriginalSFR.sfFile = *fsp; |
} |
SetCursor(*gWatch); |
if ((result=FSpOpenDF(&gOriginalSFR.sfFile,fsRdPerm,&gOriginalFile)) != noErr ) { |
goto done; |
} |
/************************************************ |
* |
* Get the picture frame, to see how big of a window to make. |
* |
************************************************/ |
if ( (result=GetPictureFileHeader(gOriginalFile,&gOriginalPicFrame,&originalPicHeader)) != noErr ) { |
FSClose(gOriginalFile); |
goto done; |
} |
/************************************************ |
* |
* Figure out the best screen to show the picture on, and if |
* it doesn't fit, then scale it to fit while maintaining aspect ratio. |
* |
************************************************/ |
SetRect(&gZoomedPictureFrame,-32767,-32767,32767,32767); |
FitRect(&gZoomedPictureFrame,gOriginalPicFrame.right-gOriginalPicFrame.left, |
gOriginalPicFrame.bottom-gOriginalPicFrame.top); |
gZoomed = false; |
/************************************************ |
* |
* Create a window for the picture, and set our port to it. |
* |
************************************************/ |
if ( (gOrigWindow = (CWindowPtr)NewCWindow(nil,&gZoomedPictureFrame,gOriginalSFR.sfFile.name,true, |
zoomDocProc,(WindowPtr)-1,true,0)) == nil ) { |
FSClose(gOriginalFile); |
result = -1; |
goto done; |
} |
rect = gZoomedPictureFrame; |
// OffsetRect(&rect,(rect.right-rect.left)+10,0); |
OffsetRect(&rect,50,50); |
if ( (gCompWindow = (CWindowPtr)NewCWindow(nil,&rect,"\pCompressed",true, |
zoomDocProc,(WindowPtr)-1,true,0)) == nil ) { |
FSClose(gOriginalFile); |
result = -1; |
goto done; |
} |
SetPort((GrafPtr)gActiveWindow); |
if ( GetEOF(gOriginalFile,&size) == noErr ) { |
size -= 512; |
if ( gOriginalPicture = (PicHandle)NewHandle(size) ) { |
HLock((Handle)gOriginalPicture); |
SetFPos(gOriginalFile,fsFromStart,512); |
FSRead(gOriginalFile,&size,*(Handle)gOriginalPicture); |
HUnlock((Handle)gOriginalPicture); |
HPurge((Handle)gOriginalPicture); |
} |
} |
rect = gZoomedPictureFrame; |
OffsetRect(&rect,-rect.left,-rect.top); |
if ( (result=NewGWorld(&gworld,gDepth,&rect,nil,nil,0)) != 0 ) { |
if ( (result=NewGWorld(&gworld,gDepth,&rect,nil,nil,8)) != 0 ) { |
Error("No mem for gworld"); |
goto done; |
} |
} |
if ( (result=NewGWorld(&compgworld,gDepth,&rect,nil,nil,0)) != 0 ) { |
if ( (result=NewGWorld(&compgworld,gDepth,&rect,nil,nil,8)) != 0 ) { |
Error("No mem for gworld"); |
DisposeGWorld(gworld); |
gworld = nil; |
goto done; |
} |
} |
GetGWorld(&savePort,&saveGD); |
SetGWorld(gworld,nil); |
if ( gOriginalPicture && *gOriginalPicture) { |
HNoPurge((Handle)gOriginalPicture); |
if ( (result=DrawTrimmedPicture(gOriginalPicture,&rect,nil,gDitherFlag,nil)) != noErr && result != codecAbortErr) { |
SysBeep(1); |
} |
HPurge((Handle)gOriginalPicture); |
}else { |
if ( (result=DrawTrimmedPictureFile(gOriginalFile,&rect,nil,gDitherFlag,nil)) != noErr && result != codecAbortErr) { |
SysBeep(1); |
} |
} |
SetGWorld(compgworld,nil); |
EraseRect(&compgworld->portRect); |
SetGWorld(savePort,saveGD); |
SetWRefCon((WindowPtr)gCompWindow,(long)compgworld); |
SetWRefCon((WindowPtr)gOrigWindow,(long)gworld); |
FSClose(gOriginalFile); |
if ( gOriginalPicture ) { |
DisposeHandle((Handle)gOriginalPicture); |
gOriginalPicture = nil; |
} |
done: |
SetCursor(&qd.arrow); |
if ( result ) { |
SysBeep(1); |
} |
} |
/************************************************ |
* |
* Close the window and the file and get rid of any temporary file we may have. |
* |
************************************************/ |
void DoClose(CWindowPtr w) |
{ |
GWorldPtr gw; |
if ( w == nil ) |
return; |
gw = (GWorldPtr)GetWRefCon((WindowPtr)w); |
if ( gw ) { |
DisposeGWorld(gw); |
} |
CloseWindow((WindowPtr)w); |
if ( w == gActiveWindow ) { |
gActiveWindow = nil; |
} |
if ( w == gOrigWindow ) |
gOrigWindow = nil; |
if ( w == gCompWindow ) |
gCompWindow = nil; |
return; |
} |
void DoSave(CWindowPtr w) |
{ |
long l,k; |
OSErr e = 0; |
PicHandle pict = nil; |
long i; |
short f = 0; |
static Str255 name = "\pPICT"; |
StandardFileReply sfr; |
CGrafPtr savePort; |
GDHandle saveGD; |
GWorldPtr gw; |
long zero = 0; |
gw = (GWorldPtr)GetWRefCon((WindowPtr)w); |
if ( gw == nil ) |
return; |
StandardPutFile((ConstStr255Param)"",name,&sfr); |
if ( sfr.sfGood ) { |
GetGWorld(&savePort,&saveGD); |
SetGWorld(gw,nil); |
pict = OpenPicture(&gw->portRect); |
ClipRect(&gw->portRect); |
CopyBits((BitMap *)*gw->portPixMap,(BitMap *)*((CGrafPtr)gw)->portPixMap, |
&gw->portRect,&gw->portRect,ditherCopy,nil); |
ClosePicture(); |
SetGWorld(savePort,saveGD); |
if ( (l=GetHandleSize((Handle)pict)) <= 10 ) { |
DisposeHandle((Handle)pict); |
Error("Making Pict"); |
return; |
} |
FSpDelete(&sfr.sfFile); |
if ( (e=FSpCreate(&sfr.sfFile,'ppxi','PICT',0)) != noErr ) { |
Error("Creating file"); |
return; |
} |
if ( (e=FSpOpenDF(&sfr.sfFile,fsRdWrPerm,&f)) != noErr ) { |
Error("Opening file"); |
goto bail; |
} |
SetFPos(f,fsFromStart,0); |
k = 4; |
for ( i=0; i < 512/4; i++ ) { |
if ( (e=FSWrite(f,&k,(char *)&zero)) != noErr ) { |
Error("Writing file"); |
goto bail; |
} |
} |
HLock((Handle)pict); |
if ( (e=FSWrite(f,&l,(Ptr)*pict)) != noErr) { |
Error("Writing file"); |
goto bail; |
} |
SetEOF(f,l+512); |
bail: |
if ( pict ) |
DisposeHandle((Handle)pict); |
if ( f ) |
FSClose(f); |
if ( e ) |
FSpDelete(&sfr.sfFile); |
FlushVol(nil,sfr.sfFile.vRefNum); |
} |
} |
/************************************************ |
* |
* Fix the menu hiliting based on conditions. |
* |
************************************************/ |
void FixMenus() |
{ |
if ( gActiveWindow == nil ) { |
EnableItem(gMenus[1],M_OPEN); |
DisableItem(gMenus[1],M_CLOSE); |
DisableItem(gMenus[1],M_SAVE); |
DisableItem(gMenus[2],M_COPY); |
} else { |
DisableItem(gMenus[1],M_OPEN); |
EnableItem(gMenus[1],M_CLOSE); |
EnableItem(gMenus[1],M_SAVE); |
// EnableItem(gMenus[2],M_COPY); |
} |
if ( gOrigWindow != nil && gCompWindow != nil ) |
EnableItem(gMenus[1],M_COMP); |
else |
DisableItem(gMenus[1],M_COMP); |
EnableItem(gMenus[2],M_FIT); |
// if ( GetScrap(nil,'PICT',&offset) > 0 ) |
// EnableItem(gMenus[2],M_PASTE); |
// else |
DisableItem(gMenus[2],M_PASTE); |
} |
/************************************************ |
* |
* Paste the PICT from the clip board into a new window, making a temporary |
* file for it. |
* |
************************************************/ |
void DoPaste() |
{ |
} |
/************************************************ |
* |
* Copy the open PICT onto the clip board. |
* |
************************************************/ |
void DoCopy(CWindowPtr w) |
{ |
#pragma unused(w) |
} |
/************************************************ |
* |
* Update the window from the PICT file. |
* |
************************************************/ |
void DoUpdate(CWindowPtr w) |
{ |
CGrafPtr savePort; |
GDHandle saveGD; |
Rect srcRect; |
GWorldPtr gw; |
if ( w == nil ) |
return; |
SetCursor(*gWatch); |
GetGWorld(&savePort,&saveGD); |
SetGWorld((CGrafPtr)w,nil); |
gw = (GWorldPtr)GetWRefCon((WindowPtr)w); |
if ( gw ) { |
srcRect = gw->portRect; |
BeginUpdate((WindowPtr)w); |
CopyBits((BitMap *)*gw->portPixMap,(BitMap *)*((CGrafPtr)w)->portPixMap, |
&srcRect,&((CGrafPtr)w)->portRect,ditherCopy,nil); |
EndUpdate((WindowPtr)w); |
} |
SetGWorld(savePort,saveGD); |
SetCursor(&qd.arrow); |
} |
/************************************************ |
* |
* Resize the window and remember the old size, and force it to update. |
* |
************************************************/ |
void DoSizeWindow(CWindowPtr wind,short h,short v,Boolean fup) |
{ |
GrafPtr savePort; |
gZoomed = false; |
GetPort(&savePort); |
SetPort((GrafPtr)wind); |
SizeWindow((WindowPtr)wind,h,v,false); |
gZoomedPictureFrame = ((CGrafPtr)wind)->portRect; |
LocalToGlobal((Point *)&gZoomedPictureFrame.top); |
LocalToGlobal((Point *)&gZoomedPictureFrame.bottom); |
if ( fup ) |
InvalRect(&((CWindowPtr)wind)->portRect); |
SetPort(savePort); |
} |
/************************************************ |
* |
* Handle clicks in the window zoom box. |
* |
************************************************/ |
void DoZoom(WindowPtr wind) |
{ |
Rect rect; |
Rect saveRect; |
GrafPtr savePort; |
KeyMap keys; |
Boolean doOriginal; |
GetPort(&savePort); |
SetPort((GrafPtr)wind); |
GetKeys(keys); |
doOriginal = (( keys[1] & 4 ) != 0); /* option key */ |
if ( doOriginal ) { |
gZoomed = false; |
FitRect(&gZoomedPictureFrame,gOriginalPicFrame.right-gOriginalPicFrame.left, |
gOriginalPicFrame.bottom-gOriginalPicFrame.top); |
} else { |
if ( gZoomed ) { |
gZoomed = false; |
} else { |
rect = gZoomedPictureFrame; |
rect.top += 16; /* make way for title bar */ |
InsetRect(&rect,16,16); |
ShowHide(wind,0); |
MoveWindow(wind,rect.left,rect.top,true); |
saveRect = gZoomedPictureFrame; |
DoSizeWindow((CWindowPtr)wind,rect.right-rect.left,rect.bottom-rect.top,true); |
gZoomedPictureFrame = saveRect; |
gZoomed = true; |
goto done; |
} |
} |
ShowHide(wind,0); |
MoveWindow(wind,gZoomedPictureFrame.left,gZoomedPictureFrame.top,true); |
DoSizeWindow((CWindowPtr)wind,gZoomedPictureFrame.right-gZoomedPictureFrame.left, |
gZoomedPictureFrame.bottom-gZoomedPictureFrame.top,true); |
done: |
ShowHide(wind,1); |
SetPort(savePort); |
} |
/************************************************ |
* |
* Grow the window (constrain aspect ratio if option key pressed. |
* |
************************************************/ |
void DoGrow(WindowPtr wind,Point *where) |
{ |
unsigned long size; |
Rect sizeRect; |
GrafPtr savePort; |
short h,v; |
short height = gOriginalPicFrame.bottom - gOriginalPicFrame.top; |
short width = gOriginalPicFrame.right - gOriginalPicFrame.left; |
KeyMap keys; |
short minH = 128,minV = 128,maxH = 4096,maxV = 4096; |
Boolean maintainAspect; |
Rect rect; |
GetPort(&savePort); |
SetPort((GrafPtr)wind); |
GetKeys(keys); |
maintainAspect = (( keys[1] & 4 ) != 0); |
if ( maintainAspect ) { |
Rect oRect; |
rect = ((CGrafPtr)wind)->portRect; |
LocalToGlobal((Point *)&rect.top); |
LocalToGlobal((Point *)&rect.bottom); |
oRect = rect; |
if ( width > 2048 || height > 2048 ) |
FitRect(&rect,width,height); |
else if ( width < 1024 && height < 1024 ) |
FitRect(&rect,width<<4,height<<4); |
else |
FitRect(&rect,width<<2,height<<2); |
maxH = (rect.right - rect.left); |
maxV = (rect.bottom - rect.top); |
if ( maxV < minV || maxH < minH ) { |
minV = maxV; |
minH = maxH; |
} |
maxV = (maxH * height)/width; |
minV = (minH * height)/width; |
} |
SetRect(&sizeRect,minH,minV,maxH,maxV); |
if ( (size = GrowWindow(wind,*where,&sizeRect)) != 0 ) { |
h = size & 0xffff; |
v = size >> 16; |
if ( maintainAspect ) |
v = (h * height)/width; |
DoSizeWindow((CWindowPtr)wind,h,v,true); |
} |
SetPort(savePort); |
FixMenus(); |
} |
/************************************************ |
* |
* Handle menu commands. |
* |
************************************************/ |
void DoCommand(long mResult) |
{ |
short theMenu, theItem; |
GrafPtr savePort; |
Str255 daName; |
theItem = ((mResult) & 0xFFFF); |
theMenu = (((mResult) >> 16) & 0xFFFF); /* This is the resource ID */ |
switch (theMenu) { |
case appleMenuID: |
if ( theItem != 1 ) { |
GetMenuItemText(gMenus[0], theItem, daName); |
GetPort(&savePort); |
(void) OpenDeskAcc(daName); |
SetPort(savePort); |
} |
break; |
case fileMenuID: |
{ |
switch (theItem) { |
case M_OPEN: |
DoOpen(nil); |
break; |
case M_CLOSE: |
DoClose(gActiveWindow); |
break; |
case M_COMP: |
DoCompression(gActiveWindow); |
break; |
case M_SAVE: |
DoSave(gActiveWindow); |
break; |
case M_QUIT: |
gExitFlag = true; /* Request exit */ |
break; |
} |
FixMenus(); |
} |
break; |
case editMenuID: |
if ( !SystemEdit(theItem-1) ) { |
switch ( theItem ) { |
case M_COPY: |
DoCopy(gActiveWindow); |
break; |
case M_PASTE: |
DoPaste(); |
break; |
case M_FIT: |
DoError(); |
break; |
default: |
break; |
} |
} |
FixMenus(); |
break; |
default: |
break; |
} |
HiliteMenu(0); |
} |
extern pascal ComponentResult DRAWTEXTCODEC(ComponentParameters *params,Handle storage); |
/************************************************ |
* |
* Our program. |
* |
************************************************/ |
void main() |
{ |
GrafPtr savePort; |
EventRecord myEvent; |
Rect dragRect; |
WindowPtr whichWindow; |
long resp; |
if ( Initialize() ) { |
SysBeep(1); |
ExitToShell(); |
} |
if ( Gestalt(gestaltSystemVersion, &resp) != noErr || resp < 0x700 ) { |
gSevenOh = false; |
} else { |
gSevenOh = true; |
} |
/* Check to make sure the image compression manager is installed. */ |
if ( Gestalt(gestaltCompressionMgr, &resp) != noErr || resp < 15 ) { |
SysBeep(1); |
ExitToShell(); |
} |
/* Check to see if new style standard file is around. */ |
gHasNewStdFile = ( Gestalt(gestaltStandardFileAttr,&resp) == 0 ); |
/* Install and open the standard compression component. */ |
gSCComponent = OpenDefaultComponent('scdi',0); |
if (!gSCComponent) { |
SysBeep(1); |
ExitToShell(); |
} |
/* Set up the first defaults for compression dialog. */ |
gSCParams.flags = scListEveryCodec; |
gSCParams.theCodecType = 'dtxt'; |
gSCParams.theCodec = anyCodec; |
gSCParams.spatialQuality = codecNormalQuality; |
gSCParams.temporalQuality = 0; |
gSCParams.depth = 32; |
/* install CoDec to test */ |
{ |
ComponentDescription td; |
Handle cname = NewHandle(sizeof(CODEC_NAME)); |
Handle dname = NewHandle(sizeof(CODEC_NAME)); |
td.componentType = 'imco'; |
td.componentSubType = 'dtxt'; |
td.componentManufacturer = 'mark'; |
td.componentFlags = codecInfoDoes1; |
td.componentFlagsMask = 0; |
BlockMove(CODEC_NAME,*cname,sizeof(CODEC_NAME)); |
RegisterComponent(&td,NewComponentRoutineProc(DRAWTEXTCODEC), 0,cname,nil, nil); |
td.componentType = 'imdc'; |
td.componentFlags = codecInfoDoes1; |
BlockMove(CODEC_NAME,*dname,sizeof(CODEC_NAME)); |
RegisterComponent(&td,NewComponentRoutineProc(DRAWTEXTCODEC), 0,dname,nil, nil); |
} |
FixMenus(); |
DoOpen(nil); |
while (!gExitFlag ) { |
if ( WaitNextEvent( everyEvent, &myEvent, 1, nil) == 0 ) |
continue; |
switch (myEvent.what) { |
case mouseDown: |
switch ((short)FindWindow(myEvent.where, &whichWindow)) { |
case inSysWindow: |
SystemClick(&myEvent, whichWindow); |
FixMenus(); |
break; |
case inMenuBar: |
DoCommand(MenuSelect(myEvent.where)); |
break; |
case inDrag: |
GetPort(&savePort); |
SetPort((GrafPtr)whichWindow); |
SetRect(&dragRect, 4, 20 + 4, qd.screenBits.bounds.right-4, qd.screenBits.bounds.bottom-4); |
DragWindow(whichWindow, myEvent.where, &dragRect); |
gZoomedPictureFrame = ((CGrafPtr)whichWindow)->portRect; |
LocalToGlobal((Point *)&gZoomedPictureFrame.top); |
LocalToGlobal((Point *)&gZoomedPictureFrame.bottom); |
SetPort(savePort); |
break; |
case inGrow: |
DoGrow(whichWindow,&myEvent.where); |
break; |
case inGoAway: |
if ( TrackGoAway(whichWindow,myEvent.where) ) |
DoClose((CWindowPtr)whichWindow); |
FixMenus(); |
break; |
case inZoomIn: |
if ( TrackBox(whichWindow,myEvent.where,inZoomIn) ) |
DoZoom(whichWindow); |
break; |
case inZoomOut: |
if ( TrackBox(whichWindow,myEvent.where,inZoomOut) ) |
DoZoom(whichWindow); |
break; |
case inContent: |
if (whichWindow != FrontWindow()) |
SelectWindow(whichWindow); |
break; |
default: |
break; |
} |
break; |
case keyDown: |
if ( ((myEvent.modifiers & cmdKey) != 0) ) { |
char key = myEvent.message & charCodeMask; |
DoCommand(MenuKey(key)); |
} |
break; |
case updateEvt : |
DoUpdate((CWindowPtr)myEvent.message); |
break; |
case activateEvt: |
whichWindow=(WindowPtr)myEvent.message; |
if ( (myEvent.modifiers & activeFlag) == 0 ) |
gActiveWindow = nil; |
else |
gActiveWindow = (CWindowPtr)whichWindow; |
FixMenus(); |
break; |
default: |
break; |
} |
} |
DoClose(gActiveWindow); |
CloseComponent(gSCComponent); |
ExitToShell(); |
} |
Copyright © 2003 Apple Computer, Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2003-01-14