reactos/rosapps/smartpdf/fitz/apps/macosx/macpdf.c
Daniel Reimer a7fddf9c07 Delete all Trailing spaces in code.
svn path=/trunk/; revision=29689
2007-10-19 23:05:02 +00:00

439 lines
10 KiB
C

#include <Carbon/Carbon.h>
#include <fitz.h>
#include <mupdf.h>
#include "pdfapp.h"
#define gDefaultFilename "/Users/giles/projects/ghostscript/tiger.pdf"
#define kViewClassID CFSTR("com.artofcode.ghostpdf.View")
#define kViewPrivate 'MU_v'
/* the pdfapp abstraction currently uses magic callbacks, so we have
to use a a global state for our own data, or subclass pdfapp_t and
do a lot of casting */
/* pdfapp callbacks - error handling */
void winwarn(pdfapp_t *pdf, char *msg)
{
fprintf(stderr, "ghostpdf warning: %s\n", msg);
}
void winerror(pdfapp_t *pdf, char *msg)
{
fprintf(stderr, "ghostpdf error: %s\n", msg);
exit(1);
}
/* pdfapp callbacks - drawing */
void wintitle(pdfapp_t *pdf, char *title)
{
/* set new document title */
}
void winresize(pdfapp_t *pdf, int w, int h)
{
/* pdfapp as been asked to shrinkwrap the document image;
we're called to actually apply the new window size. */
}
void winconvert(pdfapp_t *pdf, fz_pixmap *image)
{
/* notification that page drawing is complete */
/* do nothing */
}
void winrepaint(pdfapp_t *pdf)
{
/* image needs repainting */
HIViewSetNeedsDisplay((HIViewRef)pdf->userdata, true);
}
char* winpassword(pdfapp_t *pdf, char *filename)
{
/* prompt user for document password */
return NULL;
}
void winopenuri(pdfapp_t *pdf, char *s)
{
/* user clicked on an external uri */
/* todo: launch browser and/or open a new window if it's a PDF */
}
void wincursor(pdfapp_t *pdf, int curs)
{
/* cursor status change notification */
}
void windocopy(pdfapp_t *pdf)
{
/* user selected some text; copy it to the clipboard */
}
static OSStatus
view_construct(EventRef inEvent)
{
OSStatus err;
pdfapp_t *pdf;
pdf = (pdfapp_t *)malloc(sizeof(pdfapp_t));
require_action(pdf != NULL, CantMalloc, err = memFullErr);
pdfapp_init(pdf);
err = GetEventParameter(inEvent, kEventParamHIObjectInstance,
typeHIObjectRef, NULL, sizeof(HIObjectRef), NULL,
(HIObjectRef *)&pdf->userdata);
require_noerr(err, ParameterMissing);
err = SetEventParameter(inEvent, kEventParamHIObjectInstance,
typeVoidPtr, sizeof(pdfapp_t *), &pdf);
ParameterMissing:
if (err != noErr)
free(pdf);
CantMalloc:
return err;
}
static OSStatus
view_destruct(EventRef inEvent, pdfapp_t *pdf)
{
pdfapp_close(pdf);
free(pdf);
return noErr;
}
static OSStatus
view_initialize(EventHandlerCallRef inCallRef, EventRef inEvent,
pdfapp_t *pdf)
{
OSStatus err;
HIRect bounds;
HIViewRef view = (HIViewRef)pdf->userdata;
err = CallNextEventHandler(inCallRef, inEvent);
require_noerr(err, TroubleInSuperClass);
HIViewGetBounds (view, &bounds);
pdf->scrw = bounds.size.width;
pdf->scrh = bounds.size.height;
pdfapp_open(pdf, gDefaultFilename);
TroubleInSuperClass:
return err;
}
static void
cgcontext_set_rgba(CGContextRef ctx, unsigned int rgba)
{
const double norm = 1.0 / 255;
CGContextSetRGBFillColor(ctx,
((rgba >> 24) & 0xff) * norm,
((rgba >> 16) & 0xff) * norm,
((rgba >> 8) & 0xff) * norm,
(rgba & 0xff) * norm);
}
static void
draw_rect(CGContextRef ctx, double x0, double y0, double x1, double y1,
unsigned int rgba)
{
HIRect rect;
cgcontext_set_rgba(ctx, rgba);
rect.origin.x = x0;
rect.origin.y = y0;
rect.size.width = x1 - x0;
rect.size.height = y1 - y0;
CGContextFillRect(ctx, rect);
}
static OSStatus
view_draw(EventRef inEvent, pdfapp_t *pdf)
{
OSStatus err;
CGContextRef gc;
CGDataProviderRef provider;
CGImageRef image;
CGColorSpaceRef colorspace;
CGRect rect;
err = GetEventParameter(inEvent, kEventParamCGContextRef, typeCGContextRef,
NULL, sizeof(CGContextRef), NULL, &gc);
require_noerr(err, cleanup);
colorspace = CGColorSpaceCreateDeviceRGB();
provider = CGDataProviderCreateWithData(NULL, pdf->image->samples,
pdf->image->w * pdf->image->h * 4,
NULL);
image = CGImageCreate(pdf->image->w, pdf->image->h,
8, 32, pdf->image->w * 4,
colorspace, kCGImageAlphaNoneSkipFirst, provider,
NULL, 0, kCGRenderingIntentDefault);
rect.origin.x = 0;
rect.origin.y = 0;
rect.size.width = pdf->image->w;
rect.size.height = pdf->image->h;
HIViewDrawCGImage(gc, &rect, image);
CGColorSpaceRelease(colorspace);
CGDataProviderRelease(provider);
cleanup:
return err;
}
static OSStatus
view_get_data(EventRef inEvent, pdfapp_t *pdf)
{
OSStatus err;
OSType tag;
Ptr ptr;
Size outSize;
/* Probably could use a bit more error checking here, for type
and size match. Also, just returning a viewctx seems a
little hacky. */
err = GetEventParameter(inEvent, kEventParamControlDataTag, typeEnumeration,
NULL, sizeof(OSType), NULL, &tag);
require_noerr(err, ParameterMissing);
err = GetEventParameter(inEvent, kEventParamControlDataBuffer, typePtr,
NULL, sizeof(Ptr), NULL, &ptr);
if (tag == kViewPrivate) {
*((pdfapp_t **)ptr) = pdf;
outSize = sizeof(pdfapp_t *);
} else
err = errDataNotSupported;
if (err == noErr)
err = SetEventParameter(inEvent, kEventParamControlDataBufferSize, typeLongInteger,
sizeof(Size), &outSize);
ParameterMissing:
return err;
}
static OSStatus
view_set_data(EventRef inEvent, pdfapp_t *pdf)
{
OSStatus err;
Ptr ptr;
OSType tag;
err = GetEventParameter(inEvent, kEventParamControlDataTag, typeEnumeration,
NULL, sizeof(OSType), NULL, &tag);
require_noerr(err, ParameterMissing);
err = GetEventParameter(inEvent, kEventParamControlDataBuffer, typePtr,
NULL, sizeof(Ptr), NULL, &ptr);
require_noerr(err, ParameterMissing);
/* we think we don't use this */
err = errDataNotSupported;
ParameterMissing:
return err;
}
static OSStatus
view_hittest(EventRef inEvent, pdfapp_t *pdf)
{
OSStatus err;
HIPoint where;
HIRect bounds;
ControlPartCode part;
err = GetEventParameter(inEvent, kEventParamMouseLocation, typeHIPoint,
NULL, sizeof(HIPoint), NULL, &where);
require_noerr(err, ParameterMissing);
err = HIViewGetBounds(pdf->userdata, &bounds);
require_noerr(err, ParameterMissing);
if (CGRectContainsPoint(bounds, where))
part = 1;
else
part = kControlNoPart;
err = SetEventParameter(inEvent, kEventParamControlPart,
typeControlPartCode, sizeof(ControlPartCode),
&part);
printf("hittest %g, %g!\n", where.x, where.y);
ParameterMissing:
return err;
}
pascal OSStatus
view_handler(EventHandlerCallRef inCallRef,
EventRef inEvent,
void* inUserData )
{
OSStatus err = eventNotHandledErr;
UInt32 eventClass = GetEventClass(inEvent);
UInt32 eventKind = GetEventKind(inEvent);
pdfapp_t *pdf = (pdfapp_t *)inUserData;
switch (eventClass) {
case kEventClassHIObject:
switch (eventKind) {
case kEventHIObjectConstruct:
err = view_construct(inEvent);
break;
case kEventHIObjectInitialize:
err = view_initialize(inCallRef, inEvent, pdf);
break;
case kEventHIObjectDestruct:
err = view_destruct(inEvent, pdf);
break;
}
break;
case kEventClassControl:
switch (eventKind) {
case kEventControlInitialize:
err = noErr;
break;
case kEventControlDraw:
err = view_draw(inEvent, pdf);
break;
case kEventControlGetData:
err = view_get_data(inEvent, pdf);
break;
case kEventControlSetData:
err = view_set_data(inEvent, pdf);
break;
case kEventControlHitTest:
err = view_hittest(inEvent, pdf);
break;
/*...*/
}
break;
}
return err;
}
OSStatus
view_register(void)
{
OSStatus err = noErr;
static HIObjectClassRef view_ClassRef = NULL;
if (view_ClassRef == NULL) {
EventTypeSpec eventList[] = {
{ kEventClassHIObject, kEventHIObjectConstruct },
{ kEventClassHIObject, kEventHIObjectInitialize },
{ kEventClassHIObject, kEventHIObjectDestruct },
{ kEventClassControl, kEventControlActivate },
{ kEventClassControl, kEventControlDeactivate },
{ kEventClassControl, kEventControlDraw },
{ kEventClassControl, kEventControlHiliteChanged },
{ kEventClassControl, kEventControlHitTest },
{ kEventClassControl, kEventControlInitialize },
{ kEventClassControl, kEventControlGetData },
{ kEventClassControl, kEventControlSetData },
};
err = HIObjectRegisterSubclass(kViewClassID,
kHIViewClassID,
NULL,
view_handler,
GetEventTypeCount(eventList),
eventList,
NULL,
&view_ClassRef);
}
return err;
}
OSStatus view_create(
WindowRef inWindow,
const HIRect* inBounds,
HIViewRef* outView)
{
OSStatus err;
EventRef event;
err = view_register();
require_noerr(err, CantRegister);
err = CreateEvent(NULL, kEventClassHIObject, kEventHIObjectInitialize,
GetCurrentEventTime(), 0, &event);
require_noerr(err, CantCreateEvent);
if (inBounds != NULL) {
err = SetEventParameter(event, 'Boun', typeHIRect, sizeof(HIRect),
inBounds);
require_noerr(err, CantSetParameter);
}
err = HIObjectCreate(kViewClassID, event, (HIObjectRef*)outView);
require_noerr(err, CantCreate);
if (inWindow != NULL) {
HIViewRef root;
err = GetRootControl(inWindow, &root);
require_noerr(err, CantGetRootView);
err = HIViewAddSubview(root, *outView);
}
CantCreate:
CantGetRootView:
CantSetParameter:
CantCreateEvent:
ReleaseEvent(event);
CantRegister:
return err;
}
int main(int argc, char *argv[])
{
IBNibRef nibRef;
OSStatus err;
WindowRef window;
pdfapp_t pdf;
fz_cpudetect();
fz_accelerate();
err = view_register();
require_noerr(err, CantRegisterView);
err = CreateNibReference(CFSTR("main"), &nibRef);
printf("err = %d\n", (int)err);
require_noerr(err, CantGetNibRef);
err = SetMenuBarFromNib(nibRef, CFSTR("MenuBar"));
require_noerr(err, CantSetMenuBar);
err = CreateWindowFromNib(nibRef, CFSTR("MainWindow"), &window);
require_noerr(err, CantCreateWindow);
//openpdf(window, gDefaultFilename);
DisposeNibReference(nibRef);
pdfapp_init(&pdf);
pdfapp_open(&pdf, gDefaultFilename);
ShowWindow(window);
RunApplicationEventLoop();
pdfapp_close(&pdf);
CantGetNibRef:
CantSetMenuBar:
CantCreateWindow:
CantRegisterView:
return err;
}