-
Notifications
You must be signed in to change notification settings - Fork 0
/
macIconForFile.mm
executable file
·105 lines (85 loc) · 3.44 KB
/
macIconForFile.mm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
#import <AppKit/AppKit.h>
#import <nan.h>
#import <string>
#import <Cocoa/Cocoa.h>
#import <QuickLook/QuickLook.h>
class MacIconForFile: public Nan::AsyncWorker {
private:
std::string path;
int64_t size;
NSData* pngData;
public:
MacIconForFile(Nan::Callback *callback, std::string path, int64_t size): AsyncWorker(callback), path(path), size(size), pngData(nullptr) {
}
~MacIconForFile() {
if (pngData != nullptr) {
[pngData release];
pngData = nullptr;
}
}
void Execute() {
NSString* filePath = [NSString stringWithUTF8String:path.c_str()];
NSURL *fileURL = [NSURL fileURLWithPath:filePath];
NSDictionary *dict = [NSDictionary dictionaryWithObject:[NSNumber numberWithBool:true] forKey:(NSString *)kQLThumbnailOptionIconModeKey];
CGImageRef ref = QLThumbnailImageCreate(kCFAllocatorDefault, (CFURLRef)fileURL, CGSizeMake(size, size), (CFDictionaryRef)dict);
NSImage* sourceImage = nil;
if (ref != NULL) {
NSBitmapImageRep *bitmapImageRep = [[NSBitmapImageRep alloc] initWithCGImage:ref];
if (bitmapImageRep) {
sourceImage = [[NSImage alloc] initWithSize:[bitmapImageRep size]];
[sourceImage addRepresentation:bitmapImageRep];
[bitmapImageRep release];
}
CFRelease(ref);
}
if (!sourceImage) sourceImage = [[NSWorkspace sharedWorkspace] iconForFile:filePath];
NSSize newSize = NSMakeSize(size, size);
NSImage* targetImage = [[NSImage alloc] initWithSize: newSize];
[sourceImage setScalesWhenResized:YES];
[targetImage lockFocus];
[sourceImage setSize: newSize];
[[NSGraphicsContext currentContext] setImageInterpolation:NSImageInterpolationHigh];
[sourceImage drawAtPoint:NSZeroPoint fromRect:CGRectMake(0, 0, newSize.width, newSize.height) operation:NSCompositeCopy fraction:1.0];
[targetImage unlockFocus];
NSData* tiffData = [targetImage TIFFRepresentation];
NSBitmapImageRep* bitmapRep = [NSBitmapImageRep imageRepWithData:tiffData];
pngData = [bitmapRep representationUsingType:NSPNGFileType properties:[NSDictionary dictionary]];
[pngData retain];
}
void HandleOKCallback() {
Nan::HandleScope scope;
const char* rawBytes = reinterpret_cast<const char*>([pngData bytes]);
v8::Local<v8::Value> argv[] = {
Nan::CopyBuffer(rawBytes, [pngData length]).ToLocalChecked()
};
callback->Call(1, argv);
}
};
NAN_METHOD(GetIconForFile) {
v8::String::Utf8Value utf8Path(Nan::To<v8::String>(info[0]).ToLocalChecked());
std::string path(*utf8Path, utf8Path.length());
Nan::Callback *callback = new Nan::Callback(info[1].As<v8::Function>());
int64_t size = Nan::To<int64_t>(info[2]).FromJust();
Nan::AsyncQueueWorker(new MacIconForFile(callback, path, size));
}
NAN_METHOD(GetIconForFileSync) {
v8::String::Utf8Value utf8Path(Nan::To<v8::String>(info[0]).ToLocalChecked());
std::string path(*utf8Path, utf8Path.length());
Nan::Callback *callback = new Nan::Callback(info[1].As<v8::Function>());
int64_t size = Nan::To<int64_t>(info[2]).FromJust();
MacIconForFile* macIconForFile = new MacIconForFile(callback, path, size);
macIconForFile->Execute();
macIconForFile->HandleOKCallback();
delete macIconForFile;
}
void Init(v8::Local<v8::Object> exports) {
exports->Set(
Nan::New("getIconForFile").ToLocalChecked(),
Nan::New<v8::FunctionTemplate>(GetIconForFile)->GetFunction()
);
exports->Set(
Nan::New("getIconForFileSync").ToLocalChecked(),
Nan::New<v8::FunctionTemplate>(GetIconForFileSync)->GetFunction()
);
}
NODE_MODULE(macIconForFile, Init)