|
Packit |
df99a1 |
#include <CoreFoundation/CoreFoundation.h>
|
|
Packit |
df99a1 |
#include <CoreServices/CoreServices.h>
|
|
Packit |
df99a1 |
#include <QuickLook/QuickLook.h>
|
|
Packit |
df99a1 |
#import <Cocoa/Cocoa.h>
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
#include "ddjvuRef.h"
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
/* -----------------------------------------------------------------------------
|
|
Packit |
df99a1 |
Generate a preview for file
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
This function's job is to create preview for designated file
|
|
Packit |
df99a1 |
----------------------------------------------------------------------------- */
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
OSStatus
|
|
Packit |
df99a1 |
GeneratePreviewForURL(void *thisInterface,
|
|
Packit |
df99a1 |
QLPreviewRequestRef preview,
|
|
Packit |
df99a1 |
CFURLRef url,
|
|
Packit |
df99a1 |
CFStringRef contentTypeUTI,
|
|
Packit |
df99a1 |
CFDictionaryRef options)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
CFBundleRef bundle = QLPreviewRequestGetGeneratorBundle(preview);
|
|
Packit |
df99a1 |
char *ddjvu = ddjvuPath(bundle);
|
|
Packit |
df99a1 |
if (ddjvu != NULL) {
|
|
Packit |
df99a1 |
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
|
|
Packit |
df99a1 |
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
|
|
Packit |
df99a1 |
NSDictionary *domain = [defaults persistentDomainForName:@"org.djvu.qlgenerator"];
|
|
Packit |
df99a1 |
CFUUIDRef uuid = NULL;
|
|
Packit |
df99a1 |
CFStringRef uuidString;
|
|
Packit |
df99a1 |
BOOL debug = FALSE;
|
|
Packit |
df99a1 |
NSString *tmpPath = nil;
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
if (domain && [domain objectForKey:@"previewpages"])
|
|
Packit |
df99a1 |
if ([[domain objectForKey:@"previewpages"] intValue] == 0)
|
|
Packit |
df99a1 |
goto poppool;
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
if (domain && [domain objectForKey:@"debug"]) {
|
|
Packit |
df99a1 |
debug = [[domain objectForKey:@"debug"] boolValue];
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
uuid = CFUUIDCreate(kCFAllocatorDefault);
|
|
Packit |
df99a1 |
if (uuid) {
|
|
Packit |
df99a1 |
uuidString = CFUUIDCreateString(kCFAllocatorDefault, uuid);
|
|
Packit |
df99a1 |
if (uuidString) {
|
|
Packit |
df99a1 |
tmpPath = [NSTemporaryDirectory() stringByAppendingPathComponent:
|
|
Packit |
df99a1 |
[NSString stringWithFormat:@"djvuql-%@", uuidString]];
|
|
Packit |
df99a1 |
CFRelease(uuidString);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
CFRelease(uuid);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
if (tmpPath) {
|
|
Packit |
df99a1 |
const char *cmd = NULL;
|
|
Packit |
df99a1 |
CFStringRef cmdRef;
|
|
Packit |
df99a1 |
int page = 0;
|
|
Packit |
df99a1 |
int pages = 1;
|
|
Packit |
df99a1 |
int maxpages = 5;
|
|
Packit |
df99a1 |
int width = 612; // default 8.5x11 in points
|
|
Packit |
df99a1 |
int height = 792;
|
|
Packit |
df99a1 |
CGSize size;
|
|
Packit |
df99a1 |
MDItemRef mditem = NULL;
|
|
Packit |
df99a1 |
NSString *source = (NSString *)CFURLCopyFileSystemPath(url, kCFURLPOSIXPathStyle);
|
|
Packit |
df99a1 |
NSString *dest = nil;
|
|
Packit |
df99a1 |
NSFileManager *fmgr = [NSFileManager defaultManager];
|
|
Packit |
df99a1 |
[fmgr createDirectoryAtPath:tmpPath attributes:nil];
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
mditem = MDItemCreate(kCFAllocatorDefault, (CFStringRef)source);
|
|
Packit |
df99a1 |
if (mditem) {
|
|
Packit |
df99a1 |
CFTypeRef ref = NULL;
|
|
Packit |
df99a1 |
ref = MDItemCopyAttribute(mditem, kMDItemNumberOfPages);
|
|
Packit |
df99a1 |
if (ref) {
|
|
Packit |
df99a1 |
CFNumberGetValue(ref, kCFNumberIntType, &pages);
|
|
Packit |
df99a1 |
CFRelease(ref);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
ref = MDItemCopyAttribute(mditem, kMDItemPageWidth);
|
|
Packit |
df99a1 |
if (ref) {
|
|
Packit |
df99a1 |
CFNumberGetValue(ref, kCFNumberIntType, &width);
|
|
Packit |
df99a1 |
CFRelease(ref);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
ref = MDItemCopyAttribute(mditem, kMDItemPageHeight);
|
|
Packit |
df99a1 |
if (ref) {
|
|
Packit |
df99a1 |
CFNumberGetValue(ref, kCFNumberIntType, &height);
|
|
Packit |
df99a1 |
CFRelease(ref);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
CFRelease(mditem);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
if (domain && [domain objectForKey:@"previewpages"])
|
|
Packit |
df99a1 |
maxpages = [[domain objectForKey:@"previewpages"] intValue];
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
if (debug) {
|
|
Packit |
df99a1 |
NSLog(@"metadata: pages=%d, width=%d, height=%d", pages, width, height);
|
|
Packit |
df99a1 |
NSLog(@"maxpages=%d", maxpages);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
CGRect rect = CGRectMake(0, 0, width, height);
|
|
Packit |
df99a1 |
CGContextRef c;
|
|
Packit |
df99a1 |
c = QLPreviewRequestCreatePDFContext(preview, &rect, NULL, NULL);
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
page = 0;
|
|
Packit |
df99a1 |
do {
|
|
Packit |
df99a1 |
page++;
|
|
Packit |
df99a1 |
dest = [tmpPath stringByAppendingPathComponent:[[source lastPathComponent] stringByAppendingFormat:@"_t_p%04d.tiff", page]];
|
|
Packit |
df99a1 |
size = CGSizeMake(width, height);
|
|
Packit |
df99a1 |
cmdRef = CFStringCreateWithFormat(NULL, NULL, CFSTR("\"%s\" -format=tiff -page=%d -size=%dx%d \"%s\" \"%s\""), ddjvu, page, width, height, [source fileSystemRepresentation], [dest fileSystemRepresentation]);
|
|
Packit |
df99a1 |
cmd = CFStringGetCStringPtr(cmdRef, CFStringGetSystemEncoding());
|
|
Packit |
df99a1 |
if (cmd != NULL) {
|
|
Packit |
df99a1 |
if (debug)
|
|
Packit |
df99a1 |
NSLog(@"%s", cmd);
|
|
Packit |
df99a1 |
if ((system(cmd) == 0) && ([fmgr fileExistsAtPath:dest])) {
|
|
Packit |
df99a1 |
NSURL *durl = [NSURL fileURLWithPath:dest];
|
|
Packit |
df99a1 |
CGImageSourceRef sourceRef;
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
sourceRef = CGImageSourceCreateWithURL((CFURLRef)durl, NULL);
|
|
Packit |
df99a1 |
if(sourceRef) {
|
|
Packit |
df99a1 |
CGImageRef imageRef = NULL;
|
|
Packit |
df99a1 |
imageRef = CGImageSourceCreateImageAtIndex(sourceRef, 0, NULL);
|
|
Packit |
df99a1 |
if (imageRef) {
|
|
Packit |
df99a1 |
CGFloat offset = height * (page-1);
|
|
Packit |
df99a1 |
CGRectOffset(rect, 0.0, offset);
|
|
Packit |
df99a1 |
CGPDFContextBeginPage(c, NULL);
|
|
Packit |
df99a1 |
CGContextSaveGState(c);
|
|
Packit |
df99a1 |
CGContextDrawImage(c, rect, imageRef);
|
|
Packit |
df99a1 |
if (page == maxpages && maxpages < pages) {
|
|
Packit |
df99a1 |
CGAffineTransform m;
|
|
Packit |
df99a1 |
CFURLRef more = CFBundleCopyResourceURL(bundle, CFSTR("more_pages"), CFSTR("pdf"), NULL);
|
|
Packit |
df99a1 |
CGPDFDocumentRef doc = CGPDFDocumentCreateWithURL(more);
|
|
Packit |
df99a1 |
CGPDFPageRef pdf = CGPDFDocumentGetPage(doc, 1);
|
|
Packit |
df99a1 |
CGFloat offset = height * page;
|
|
Packit |
df99a1 |
CGRectOffset(rect, 0.0, offset);
|
|
Packit |
df99a1 |
CGContextSaveGState(c);
|
|
Packit |
df99a1 |
m = CGPDFPageGetDrawingTransform(pdf, kCGPDFMediaBox, rect, 0, true);
|
|
Packit |
df99a1 |
CGContextConcatCTM(c, m);
|
|
Packit |
df99a1 |
CGContextDrawPDFPage(c, pdf);
|
|
Packit |
df99a1 |
CGContextRestoreGState(c);
|
|
Packit |
df99a1 |
CFRelease(doc);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
CGContextRestoreGState(c);
|
|
Packit |
df99a1 |
CGPDFContextEndPage(c);
|
|
Packit |
df99a1 |
CFRelease(imageRef);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
CFRelease(sourceRef);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
CFRelease(cmdRef);
|
|
Packit |
df99a1 |
} while (page < pages && page < maxpages);
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
CGPDFContextClose(c);
|
|
Packit |
df99a1 |
QLPreviewRequestFlushContext(preview, c);
|
|
Packit |
df99a1 |
CFRelease(c);
|
|
Packit |
df99a1 |
[fmgr removeFileAtPath:tmpPath handler:nil];
|
|
Packit |
df99a1 |
[source release];
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
poppool:
|
|
Packit |
df99a1 |
[pool release];
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
return noErr;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
void CancelPreviewGeneration(void* thisInterface, QLPreviewRequestRef preview)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
// implement only if supported
|
|
Packit |
df99a1 |
}
|