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.
source/GraphicImportDrawCode.c
/* |
File: GraphicImportDrawCode.c |
Description:Code that actually implements the drawing calls to the Graphic Importer |
components to draw many different image formats. |
Author: MC |
Copyright: © Copyright 1999-2000 Apple Computer, Inc. All rights reserved. |
Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc. |
("Apple") in consideration of your agreement to the following terms, and your |
use, installation, modification or redistribution of this Apple software |
constitutes acceptance of these terms. If you do not agree with these terms, |
please do not use, install, modify or redistribute this Apple software. |
In consideration of your agreement to abide by the following terms, and subject |
to these terms, Apple grants you a personal, non-exclusive license, under AppleÕs |
copyrights in this original Apple software (the "Apple Software"), to use, |
reproduce, modify and redistribute the Apple Software, with or without |
modifications, in source and/or binary forms; provided that if you redistribute |
the Apple Software in its entirety and without modifications, you must retain |
this notice and the following text and disclaimers in all such redistributions of |
the Apple Software. Neither the name, trademarks, service marks or logos of |
Apple Computer, Inc. may be used to endorse or promote products derived from the |
Apple Software without specific prior written permission from Apple. Except as |
expressly stated in this notice, no other rights or licenses, express or implied, |
are granted by Apple herein, including but not limited to any patent rights that |
may be infringed by your derivative works or by other works in which the Apple |
Software may be incorporated. |
The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO |
WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED |
WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN |
COMBINATION WITH YOUR PRODUCTS. |
IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR |
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE |
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION |
OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT |
(INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN |
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
Change History (most recent first): |
*/ |
#define TARGET_API_MAC_CARBON 1 |
#include <Windows.h> |
#include <Movies.h> |
#include <QuickTimeComponents.h> |
#include "GraphicImportDrawCode.h" |
#include "WindowCode.h" |
#include "LinkedList.h" |
#include "Structs.h" |
#include "Defines.h" |
// Globals |
extern PreferencesHandle gPreferences; |
extern long gNumGIComponents; |
extern OSType * gAcceptedFlavorTypes; |
static void MaxWindowSize (WindowPtr theWindow, Rect * maxBounds) { |
WindowInfoHandle winInfo; |
SInt8 hState; |
Rect standard, |
device, |
global, |
c, |
s, |
diffs; |
RgnHandle tempRgn; |
GDHandle theDevice; |
CGrafPtr wport; |
Point origin; |
if (theWindow != nil) { |
winInfo = (WindowInfoHandle)GetWRefCon (theWindow); |
} |
if (winInfo != nil && (**winInfo).sig == kMySig) { |
hState = HGetState ((Handle)winInfo); |
HLock ((Handle)winInfo); |
// make the window's port the current port |
wport = GetWindowPort (theWindow); |
SetPort (wport); |
SetPt (&origin, 0, 0); |
LocalToGlobal (&origin); |
// find the window's global coordinates |
GetPortBounds (wport, &global); |
OffsetRect (&global, origin.h, origin.v); |
// get the maximum intersecting screen |
theDevice = GetMaxDevice (&global); |
device = (**theDevice).gdRect; |
// if it's the main screen, adjust it for the menu bar height |
if (theDevice == GetMainDevice ()) |
device.top += GetMBarHeight (); |
// calculate the difference between the window's content rectangle and its frame |
tempRgn = NewRgn (); |
GetWindowRegion (theWindow, kWindowContentRgn, tempRgn); |
GetRegionBounds (tempRgn, &c); |
GetWindowRegion (theWindow, kWindowStructureRgn, tempRgn); |
GetRegionBounds (tempRgn, &s); |
DisposeRgn (tempRgn); |
SetRect (&diffs, (short)(c.left - s.left), (short)(c.top - s.top), |
(short)(s.right - c.right), (short)(s.bottom - c.bottom)); |
// calculate the maximum bounds for the standard rectangle |
SetRect (&standard, (short)(device.left + diffs.left), (short)(device.top + diffs.top), |
(short)(device.right - diffs.right), (short)(device.bottom - diffs.bottom)); |
// Move the origin back to 0,0 |
OffsetRect (&standard, (short)-standard.left, (short)-standard.top); |
ScaleImageToRect (&(**winInfo).winNatGraphicBoundsRect, &standard, maxBounds); |
HSetState ((Handle)winInfo, hState); |
} |
} |
static OSErr SizeGraphicWindow (WindowPtr theWindow) { |
ComponentResult err; |
WindowInfoHandle winInfo; |
SInt16 w, h; |
if (theWindow != nil) { |
winInfo = (WindowInfoHandle)GetWRefCon (theWindow); |
} |
if (winInfo != nil && (**winInfo).sig == kMySig) { |
err = GraphicsImportGetBoundsRect ((**winInfo).winGraphicImporter, &(**winInfo).winNatGraphicBoundsRect); |
if (err == noErr) { |
MaxWindowSize (theWindow, &(**winInfo).winBounds); |
w = (SInt16)((**winInfo).winBounds.right - (**winInfo).winBounds.left); |
h = (SInt16)((**winInfo).winBounds.bottom - (**winInfo).winBounds.top); |
SizeWindow (theWindow, w, h, false); |
} |
} |
return (OSErr)err; |
} |
#define USEGWORLDS 1 |
static OSErr AllocateGWorld (WindowInfoHandle winInfo) { |
OSErr err; |
(**winInfo).winGWorld = nil; |
#if USEGWORLDS |
err = NewGWorld (&((**winInfo).winGWorld), 32, &(**winInfo).winNatGraphicBoundsRect, |
nil, nil, pixPurge | useTempMem); |
#endif |
if ((**winInfo).winGWorld == nil) { |
err = memFullErr; |
} |
return err; |
} |
static OSErr DoDraw (WindowInfoHandle winInfo) { |
ComponentResult err; |
Boolean locked; |
PixMapHandle pixMap; |
err = AllocateGWorld (winInfo); |
if (err == noErr) { |
pixMap = GetGWorldPixMap ((**winInfo).winGWorld); |
if (LockPixels (pixMap)) { |
locked = true; |
} else { |
locked = false; |
// Memory is gone, so forget about using a GWorld |
// use the current window set by the function calling this routine |
DisposeGWorld ((**winInfo).winGWorld); |
(**winInfo).winGWorld = nil; |
} |
} else if (err == memFullErr) { |
err = noErr; |
} |
if ((**winInfo).winGWorld != nil) { |
err = GraphicsImportSetGWorld ((**winInfo).winGraphicImporter, (**winInfo).winGWorld, nil); |
} else { |
err = GraphicsImportSetBoundsRect ((**winInfo).winGraphicImporter, &(**winInfo).winBounds); |
} |
if (err == noErr) { |
(void)GraphicsImportSetQuality ((**winInfo).winGraphicImporter, (**gPreferences).quality); |
} |
if (err == noErr) { |
err = GraphicsImportDraw ((**winInfo).winGraphicImporter); |
} |
if (locked == true) { |
UnlockPixels (pixMap); |
} |
return (OSErr)err; |
} |
OSErr FindAllGIComponents (void) { |
Component aComponent; |
ComponentDescription looking, |
cDesc; |
OSErr err; |
looking.componentType = GraphicsImporterComponentType; |
looking.componentSubType = 0; |
looking.componentManufacturer = 0; |
looking.componentFlags = 0; |
looking.componentFlagsMask = 1 << 12; |
gNumGIComponents = CountComponents (&looking); |
gAcceptedFlavorTypes = (OSType*)NewPtr ((long)(gNumGIComponents * sizeof (OSType))); |
err = MemError (); |
if (err == noErr) { |
long i = 0; |
aComponent = 0; // start search from the top |
do { |
aComponent = FindNextComponent (aComponent, &looking); |
if (aComponent != 0) { |
err = GetComponentInfo (aComponent, &cDesc, nil, nil, nil); |
if (err == noErr) { |
gAcceptedFlavorTypes[i++] = cDesc.componentSubType; |
} |
} |
} while (aComponent != 0 && err == noErr); |
} |
return err; |
} |
void ScaleImageToRect (Rect * origBounds, Rect * maxBounds, Rect * newBounds) { |
double scale; |
scale = 1.0; // default is no scaling |
newBounds->right = origBounds->right; |
newBounds->left = origBounds->left; |
newBounds->bottom = origBounds->bottom; |
newBounds->top = origBounds->top; |
if ((newBounds->right - newBounds->left) > (maxBounds->right - maxBounds->left)) { |
scale = (maxBounds->right - maxBounds->left) / (float)(newBounds->right - newBounds->left); |
newBounds->right *= scale; |
newBounds->left *= scale; |
newBounds->bottom *= scale; |
newBounds->top *= scale; |
} |
if ((newBounds->bottom - newBounds->top) > (maxBounds->bottom - maxBounds->top)) { |
scale = (maxBounds->bottom - maxBounds->top) / (float)(newBounds->bottom - newBounds->top); |
newBounds->right *= scale; |
newBounds->left *= scale; |
newBounds->bottom *= scale; |
newBounds->top *= scale; |
} |
// Move the adjusted rect so that it fits in the original Rect. |
// This is needed in the Nav Preview window. |
newBounds->right += maxBounds->left; |
newBounds->left += maxBounds->left; |
newBounds->bottom += maxBounds->top; |
newBounds->top += maxBounds->top; |
} |
OSErr NewWindowWithPict (FSSpec * theFileSpec, WindowPtr behindWindow) { |
WindowPtr theWindow; |
WindowInfoHandle winInfo; |
OSErr err; |
err = MakeNewWindow (theFileSpec->name, false, behindWindow, &theWindow); |
if (err == noErr) { |
if (theWindow != nil) { |
winInfo = (WindowInfoHandle)GetWRefCon (theWindow); |
} |
if (winInfo != nil && (**winInfo).sig == kMySig) { |
BlockMoveData (theFileSpec, &((**winInfo).winSpec), sizeof (FSSpec)); |
} else { |
err = paramErr; |
} |
} |
if (err == noErr) { |
CursHandle cursor = nil; |
cursor = GetCursor (watchCursor); |
SetCursor (*cursor); |
err = DrawFile (theWindow); |
ObscureCursor (); |
cursor = (CursHandle)NewHandle (sizeof (Cursor)); |
GetQDGlobalsArrow (*cursor); |
SetCursor (*cursor); |
DisposeHandle ((Handle)cursor); |
} |
return err; |
} |
OSErr DrawHandle (WindowPtr theWindow) { |
WindowInfoHandle winInfo; |
ComponentResult err; |
SInt8 hState; |
Rect winRect; |
if (theWindow != nil) { |
winInfo = (WindowInfoHandle)GetWRefCon (theWindow); |
} |
if (winInfo != nil && (**winInfo).sig == kMySig) { |
hState = HGetState ((Handle)winInfo); |
HLock ((Handle)winInfo); |
SetPort (GetWindowPort(theWindow)); |
(**winInfo).winGraphicImporter = OpenDefaultComponent (GraphicsImporterComponentType, (**winInfo).winGraphicType); |
if ((**winInfo).winGraphicImporter != nil) { |
err = GraphicsImportSetDataHandle ((**winInfo).winGraphicImporter, (**winInfo).winDataHandle); |
} else { |
err = couldntGetRequiredComponent; |
} |
if (err == noErr) { |
SizeGraphicWindow (theWindow); |
GetWindowPortBounds (theWindow, &winRect); |
} |
if (err == noErr) { |
err = DoDraw (winInfo); |
} |
if (err == noErr) { |
if ((**winInfo).winGWorld != nil) { |
// We drew into a GWorld, not the window, so an update event is needed |
InvalWindowRect (theWindow, &winRect); |
} |
} |
if ((**winInfo).winGraphicImporter != nil) { |
(void)CloseComponent ((**winInfo).winGraphicImporter); |
(**winInfo).winGraphicImporter = nil; |
} |
HSetState ((Handle)winInfo, hState); |
if (err != noErr) { |
ReleaseMemory (winInfo, true); |
} |
} |
return (OSErr)err; |
} |
OSErr DrawFile (WindowPtr theWindow) { |
WindowInfoHandle winInfo; |
ComponentResult err; |
SInt8 hState; |
if (theWindow != nil) { |
winInfo = (WindowInfoHandle)GetWRefCon (theWindow); |
} |
if (winInfo != nil && (**winInfo).sig == kMySig) { |
hState = HGetState ((Handle)winInfo); |
HLock ((Handle)winInfo); |
SetPort (GetWindowPort(theWindow)); |
err = GetGraphicsImporterForFile (&(**winInfo).winSpec, &(**winInfo).winGraphicImporter); |
if (err == noErr) { |
err = SizeGraphicWindow (theWindow); |
} |
if (err == noErr) { |
err = DoDraw (winInfo); |
} |
// Generates the update event needed to get us to draw into the window. |
ShowWindow (theWindow); |
if ((**winInfo).winGraphicImporter != nil) { |
(void)CloseComponent ((**winInfo).winGraphicImporter); |
(**winInfo).winGraphicImporter = nil; |
} |
HSetState ((Handle)winInfo, hState); |
} |
return (OSErr)err; |
} |
OSErr UpdateGraphWindow (WindowPtr theWindow, RgnHandle updateRgn) { |
#pragma unused (updateRgn) |
OSErr err; |
WindowInfoHandle winInfo; |
SInt8 hState; |
Rect winBounds; |
PixMapHandle pixMap; |
if (theWindow != nil) { |
winInfo = (WindowInfoHandle)GetWRefCon (theWindow); |
} |
if (winInfo != nil && (**winInfo).sig == kMySig) { |
hState = HGetState ((Handle)winInfo); |
HLock ((Handle)winInfo); |
SetPort (GetWindowPort(theWindow)); |
if ((**winInfo).winMovie != nil) { |
err = UpdateMovie ((**winInfo).winMovie); |
MoviesTask (DoTheRightThing, DoTheRightThing); |
} else { |
if ((**winInfo).winGWorld != nil) { |
pixMap = GetGWorldPixMap ((**winInfo).winGWorld); |
if (LockPixels (pixMap)) { |
GetWindowPortBounds (theWindow, &winBounds); |
CopyBits ((BitMap*)*GetPortPixMap ((**winInfo).winGWorld), |
(BitMap*)*GetPortPixMap (GetWindowPort(theWindow)), |
&(**winInfo).winNatGraphicBoundsRect, &winBounds, srcCopy, nil); |
UnlockPixels (pixMap); |
err = noErr; |
} else { |
DisposeGWorld ((**winInfo).winGWorld); |
(**winInfo).winGWorld = nil; |
if ((**winInfo).winDataHandle != nil) { |
err = DrawHandle (theWindow); |
} else { |
err = DrawFile (theWindow); |
} |
if ((**winInfo).winGWorld != nil) { |
pixMap = GetGWorldPixMap ((**winInfo).winGWorld); |
if (LockPixels (pixMap)) { |
GetWindowPortBounds (theWindow, &winBounds); |
CopyBits ((BitMap*)*GetPortPixMap ((**winInfo).winGWorld), |
(BitMap*)*GetPortPixMap (GetWindowPort(theWindow)), |
&(**winInfo).winNatGraphicBoundsRect, &winBounds, srcCopy, nil); |
UnlockPixels (pixMap); |
} |
} |
} |
} else { |
if ((**winInfo).winDataHandle != nil) { |
err = DrawHandle (theWindow); |
} else { |
err = DrawFile (theWindow); |
} |
} |
} |
HSetState ((Handle)winInfo, hState); |
} |
return err; |
} |
Copyright © 2003 Apple Computer, Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2003-01-14