-
Notifications
You must be signed in to change notification settings - Fork 0
/
FConvenience.m
136 lines (115 loc) · 4.02 KB
/
FConvenience.m
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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
#import "FConvenience.h"
#import <QuartzCore/QuartzCore.h>
#import <asl.h>
static pthread_key_t _ASLClientThreadLocal;
static void _aslClientCleanup(void *client)
{
asl_close(client);
}
void _FLog(enum FLogLevel const aLevel,
const char * const aFile,
int const aLine,
NSString * const aFormat, ...)
{
Once(^{ pthread_key_create(&_ASLClientThreadLocal, &_aslClientCleanup); });
aslclient client = pthread_getspecific(_ASLClientThreadLocal);
if(!client) {
client = asl_open(NULL,
[[Bundle bundleIdentifier] UTF8String],
ASL_OPT_STDERR|ASL_OPT_NO_DELAY);
pthread_setspecific(_ASLClientThreadLocal, client);
#ifndef DEBUG
asl_set_filter(client, ASL_FILTER_MASK_UPTO(ASL_LEVEL_WARNING));
#endif
}
#ifndef DEBUG
// For some reason, asl_set_filter isn't doing its job.. so for now I'm just
// not logging anything above warning in production builds
if(aLevel <= ASL_LEVEL_WARNING) {
#endif
va_list argList;
va_start(argList, aFormat);
NSString * const message = [[NSString alloc] initWithFormat:aFormat
arguments:argList];
va_end(argList);
aslmsg const msg = asl_new(ASL_TYPE_MSG);
asl_set(msg, ASL_KEY_READ_UID, "-1");
asl_log(client, msg, aLevel,
"%10.15s:%u: %s",
[[@(aFile) lastPathComponent] UTF8String], aLine, [message UTF8String]);
asl_free(msg);
#ifndef DEBUG
}
#endif
}
@implementation NSUserDefaults (Subscripts)
- (id)objectForKeyedSubscript:(id)aKey
{
return [self objectForKey:aKey];
}
- (void)setObject:(id)aObj forKeyedSubscript:(id)aKey
{
[self setObject:aObj forKey:aKey];
}
@end
@implementation NSCache (Subscripts)
- (id)objectForKeyedSubscript:(id)aKey
{
return [self objectForKey:aKey];
}
- (void)setObject:(id)aObj forKeyedSubscript:(id)aKey
{
[self setObject:aObj forKey:aKey];
}
@end
#if TARGET_OS_IPHONE && defined(__OBJC__)
UIImage *FScreenshot(float const aScale)
{
CGSize const imageSize = [[UIScreen mainScreen] bounds].size;
UIGraphicsBeginImageContextWithOptions(imageSize, YES, aScale);
CGContextRef const context = UIGraphicsGetCurrentContext();
UIGraphicsPushContext(context);
for(UIWindow * const window in UIApp.windows)
{
CGContextSaveGState(context);
[window drawViewHierarchyInRect:window.bounds afterScreenUpdates:YES];
CGContextRestoreGState(context);
}
UIGraphicsPopContext();
const uint8_t * const pixels = CGBitmapContextGetData(context);
size_t const bpr = CGBitmapContextGetBytesPerRow(context);
UIInterfaceOrientation const orien = UIApp.statusBarOrientation;
BOOL const upsideDown = (orien == UIInterfaceOrientationPortraitUpsideDown)
|| (orien == UIInterfaceOrientationLandscapeRight);
size_t startIdx;
if(UIInterfaceOrientationIsLandscape(orien) && upsideDown)
startIdx = 4 * (CGBitmapContextGetWidth(context) - 21);
else if(UIInterfaceOrientationIsLandscape(orien))
startIdx = 21 * 4;
else if(upsideDown)
startIdx = bpr * (CGBitmapContextGetHeight(context) - 21);
else
startIdx = bpr * 21;
CGFloat topColor[4] = {
pixels[startIdx ] / 255.0f,
pixels[startIdx + 1] / 255.0f,
pixels[startIdx + 2] / 255.0f,
pixels[startIdx + 3] / 255.0f
};
CGContextSetFillColorWithColor(context,
RGBA(topColor[2], topColor[1], topColor[0], topColor[3]).CGColor);
if(UIInterfaceOrientationIsLandscape(orien)) CGContextFillRect(context, (CGRect) {
upsideDown ? imageSize.width - 20.0f : 0.0f,
0,
20, imageSize.height
});
else CGContextFillRect(context, (CGRect) {
0,
upsideDown ? imageSize.height - 20.0f : 0,
imageSize.width, 20
});
UIImage * const image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;
}
#endif