#include <QuickTime/QuickTime.h>
//////////
//
// drawMultiPagePDF
//
// Open the multi-page PDF document file as a movie, then
// step through each page and draw the page to the
// specified port
//
//////////
void drawMultiPagePDFtoPort(FSSpec *pdfFileSpec, CGrafPtr thePort)
{
OSErr err = noErr;
Movie theMovie = nil;
short movieFileRefNum = 0;
Track firstVideoTrack = nil;
// open the PDF file
err = OpenMovieFile(pdfFileSpec, &movieFileRefNum, fsRdPerm);
if (err) goto bail;
// create a movie from that file
err = NewMovieFromFile(&theMovie,
movieFileRefNum,
NULL,
NULL,
newMovieActive,
NULL);
if (err) goto bail;
// set the drawing port for the movie
SetMovieGWorld(theMovie,thePort,nil);
if (GetMoviesError()) goto bail;
// get the first video track in the movie
firstVideoTrack = GetMovieIndTrackType(theMovie,
1,
VideoMediaType,
movieTrackMediaType);
if (firstVideoTrack)
{
long frameCount = 0;
// get the video track frame count
frameCount = getFrameCount (firstVideoTrack);
for ( ; frameCount > 0; frameCount--)
{
// draw a frame (PDF page) into the port
drawMovieFrameNextOrPrev (theMovie, fixed1);
}
}
bail:
if (movieFileRefNum)
{
CloseMovieFile(movieFileRefNum);
}
if (theMovie)
{
DisposeMovie(theMovie);
}
}
//////////
//
// getFrameCount
// Get the number of frames in the specified movie track.
// We return the value -1 if an error occurs and we cannot
// determine the number of frames in the track.
//
// Based (loosely) on frame-counting code in ConvertToMovie
// Jr.c.
//
// We count the frames in the track by stepping through all
// of its interesting times (the places where the track
// displays a new sample).
//
//////////
long getFrameCount (Track theTrack)
{
long myCount = -1;
short myFlags;
TimeValue myTime = 0;
if (theTrack == NULL)
goto bail;
// we want to begin with the first frame (sample) in the track
myFlags = nextTimeMediaSample + nextTimeEdgeOK;
while (myTime >= 0) {
myCount++;
// look for the next frame in the track; when there are no more
// frames, myTime is set to -1, so we'll exit the while loop
GetTrackNextInterestingTime(theTrack,
myFlags,
myTime,
fixed1,
&myTime,
NULL);
// after the first interesting time, don't include the time we're
// currently at
myFlags = nextTimeStep;
}
bail:
return(myCount);
}
//////////
//
// drawMovieFrameNextOrPrev
// Draw the next or previous video sample of a QuickTime movie.
// If theRate is 1, the next video sample is drawn; if theRate is -1,
// the previous sample is drawn.
//
//////////
OSErr drawMovieFrameNextOrPrev (Movie theMovie, Fixed theRate)
{
TimeValue myCurrTime;
TimeValue myNextTime;
short myFlags;
OSType myTypes[1];
OSErr myErr = noErr;
if (theMovie == NULL)
return(invalidMovie);
// want the next frame in the movie's media
myFlags = nextTimeStep;
// we want video samples
myTypes[0] = VisualMediaCharacteristic;
myCurrTime = GetMovieTime(theMovie, NULL);
GetMovieNextInterestingTime(theMovie,
myFlags,
1,
myTypes,
myCurrTime,
theRate,
&myNextTime,
NULL);
myErr = GetMoviesError();
if (myErr != noErr)
return(myErr);
myErr = drawMovieFrameAtTime(theMovie, myNextTime);
return(myErr);
}
//////////
//
// drawMovieFrameAtTime
// Draw the video sample of a QuickTime movie at the specified time.
//
//////////
OSErr drawMovieFrameAtTime (Movie theMovie, TimeValue theTime)
{
OSErr myErr = noErr;
if (theMovie == NULL)
return(invalidMovie);
// make sure that the specified time lies within the movie's
// temporal bounds
if ((theTime < 0) || (theTime > GetMovieDuration(theMovie)))
return(paramErr);
SetMovieTimeValue(theMovie, theTime);
myErr = GetMoviesError();
if (myErr != noErr)
goto bail;
// the following call to MoviesTask is not necessary if you
// are handling movie controller events in your main event
// loop (by passing the event to MCIsPlayerEvent);
// they don't hurt, however.
// redraw the movie immediately by calling MoviesTask
MoviesTask(theMovie, 0L);
myErr = GetMoviesError();
bail:
return(myErr);
}
|