X-Git-Url: https://git.saurik.com/winterboard.git/blobdiff_plain/05b58bf360402545448f7bd6d562fb824f15964a..57b2be4c2024a6b3473f963baed16164fda82c24:/Library.mm diff --git a/Library.mm b/Library.mm index 92d2f62..676a257 100644 --- a/Library.mm +++ b/Library.mm @@ -122,6 +122,7 @@ MSMetaClassHook(UIImage) MSClassHook(UINavigationBar) MSClassHook(UIToolbar) +MSClassHook(CKBalloonView) MSClassHook(CKMessageCell) MSClassHook(CKTimestampView) MSClassHook(CKTranscriptCell) @@ -199,7 +200,7 @@ static BOOL (*_GSFontGetUseLegacyFontMetrics)(); static bool Debug_ = false; static bool UIDebug_ = false; static bool Engineer_ = false; -static bool SummerBoard_ = true; +static bool SummerBoard_ = false; static bool SpringBoard_; static UIImage *(*_UIApplicationImageWithName)(NSString *name); @@ -241,7 +242,7 @@ static unsigned $getScale$(NSString *path) { } static NSArray *$useScale$(NSArray *files, bool use = true) { - if (Scale_ == 0) { + if (use && Scale_ == 0) { UIScreen *screen([UIScreen mainScreen]); if ([screen respondsToSelector:@selector(scale)]) Scale_ = [screen scale]; @@ -275,9 +276,10 @@ static NSArray *$useScale$(NSArray *files, bool use = true) { [scaled addObject:[NSString stringWithFormat:@"%@~iphone.%@", base, extension]]; [scaled addObject:file]; - NSString *rest([base substringWithRange:NSMakeRange(0, [base length] - 3)]); + // XXX: this actually can't be used, as the person loading the file doesn't realize that the @2x changed + /*NSString *rest([base substringWithRange:NSMakeRange(0, [base length] - 3)]); [scaled addObject:[NSString stringWithFormat:@"%@~iphone.%@", rest, extension]]; - [scaled addObject:[rest stringByAppendingPathExtension:extension]]; + [scaled addObject:[rest stringByAppendingPathExtension:extension]];*/ } else { // XXX: this code isn't really complete @@ -292,8 +294,13 @@ static NSArray *$useScale$(NSArray *files, bool use = true) { } static NSString *$getTheme$(NSArray *files, NSArray *themes = Themes_) { - if (NSString *path = [Themed_ objectForKey:files]) - return reinterpret_cast(path) == [NSNull null] ? nil : path; + // XXX: this is not reasonable; OMG + id key(files); + + @synchronized (Themed_) { + if (NSString *path = [Themed_ objectForKey:key]) + return reinterpret_cast(path) == [NSNull null] ? nil : path; + } if (Debug_) NSLog(@"WB:Debug: %@", [files description]); @@ -310,7 +317,10 @@ static NSString *$getTheme$(NSArray *files, NSArray *themes = Themes_) { path = nil; set: - [Themed_ setObject:(path == nil ? [NSNull null] : reinterpret_cast(path)) forKey:files]; + @synchronized (Themed_) { + [Themed_ setObject:(path == nil ? [NSNull null] : reinterpret_cast(path)) forKey:key]; + } + return path; } // }}} @@ -321,8 +331,12 @@ static NSString *$pathForFile$inBundle$(NSString *file, NSBundle *bundle, bool u if (identifier != nil) [names addObject:[NSString stringWithFormat:@"Bundles/%@/%@", identifier, file]]; - if (NSString *folder = [[bundle bundlePath] lastPathComponent]) + if (NSString *folder = [[bundle bundlePath] lastPathComponent]) { [names addObject:[NSString stringWithFormat:@"Folders/%@/%@", folder, file]]; + NSString *base([folder stringByDeletingPathExtension]); + if ([base hasSuffix:@"~iphone"]) + [names addObject:[NSString stringWithFormat:@"Folders/%@.%@/%@", [base substringWithRange:NSMakeRange(0, [base length] - 7)], [folder pathExtension], file]]; + } if (ui) [names addObject:[NSString stringWithFormat:@"UIImages/%@", file]]; @@ -342,6 +356,8 @@ static NSString *$pathForFile$inBundle$(NSString *file, NSBundle *bundle, bool u remapResourceName(Four_ ? @"SBDockBG-old.png" : @"SBDockBG.png", @"Dock") remapResourceName(@"SBWeatherCelsius.png", @"Icons/Weather") + [names addObject:[NSString stringWithFormat:@"Fallback/%@", file]]; + if (NSString *path = $getTheme$($useScale$(names, ui))) return path; @@ -660,6 +676,35 @@ MSInstanceMessageHook2(NSString *, NSBundle, pathForResource,ofType, NSString *, } // }}} +static void $drawLabel$(NSString *label, CGRect rect, NSString *style, NSString *custom) { + bool ellipsis(false); + float max = rect.size.width - 11, width; + width: + width = [(ellipsis ? [label stringByAppendingString:@"..."] : label) sizeWithStyle:style forWidth:320].width; + + if (width > max) { + size_t length([label length]); + float spacing((width - max) / (length - 1)); + + if (spacing > 1.25) { + ellipsis = true; + label = [label substringToIndex:(length - 1)]; + goto width; + } + + style = [style stringByAppendingString:[NSString stringWithFormat:@"letter-spacing: -%f; ", spacing]]; + } + + if (ellipsis) + label = [label stringByAppendingString:@"..."]; + + if (custom != nil) + style = [style stringByAppendingString:custom]; + + CGSize size = [label sizeWithStyle:style forWidth:rect.size.width]; + [label drawAtPoint:CGPointMake((rect.size.width - size.width) / 2 + rect.origin.x, rect.origin.y) withStyle:style]; +} + static struct WBStringDrawingState { WBStringDrawingState *next_; unsigned count_; @@ -667,45 +712,95 @@ static struct WBStringDrawingState { NSString *info_; } *stringDrawingState_; -MSInstanceMessageHook4(CGSize, NSString, drawAtPoint,forWidth,withFont,lineBreakMode, CGPoint, point, float, width, UIFont *, font, int, mode) { +MSInstanceMessageHook6(CGSize, NSString, drawAtPoint,forWidth,withFont,lineBreakMode,letterSpacing,includeEmoji, CGPoint, point, float, width, UIFont *, font, UILineBreakMode, mode, float, spacing, BOOL, emoji) { + //NSLog(@"XXX: @\"%@\" %g", self, spacing); + WBStringDrawingState *state(stringDrawingState_); if (state == NULL) - return MSOldCall(point, width, font, mode); + return MSOldCall(point, width, font, mode, spacing, emoji); if (--state->count_ == 0) stringDrawingState_ = state->next_; if (state->info_ == nil) - return MSOldCall(point, width, font, mode); + return MSOldCall(point, width, font, mode, spacing, emoji); NSString *info([Info_ objectForKey:state->info_]); if (info == nil) - return MSOldCall(point, width, font, mode); + return MSOldCall(point, width, font, mode, spacing, emoji); NSString *base(state->base_ ?: @""); - [self drawAtPoint:point withStyle:[NSString stringWithFormat:@"%@;%@;%@", [font markupDescription], base, info]]; + NSString *extra([NSString stringWithFormat:@"letter-spacing: %gpx", spacing]); + [self drawAtPoint:point withStyle:[NSString stringWithFormat:@"%@;%@;%@;%@", [font markupDescription], extra, base, info]]; return CGSizeZero; } -MSInstanceMessageHook2(CGSize, NSString, drawAtPoint,withFont, CGPoint, point, UIFont *, font) { +extern "C" NSString *NSStringFromCGRect(CGRect rect); + +MSInstanceMessageHook7(CGSize, NSString, _drawInRect,withFont,lineBreakMode,alignment,lineSpacing,includeEmoji,truncationRect, CGRect, rect, UIFont *, font, UILineBreakMode, mode, UITextAlignment, alignment, float, spacing, BOOL, emoji, CGRect, truncation) { + //NSLog(@"XXX: &\"%@\" %@ \"%@\" %u %u %g %u %@", self, NSStringFromCGRect(rect), font, mode, alignment, spacing, emoji, NSStringFromCGRect(truncation)); + WBStringDrawingState *state(stringDrawingState_); if (state == NULL) - return MSOldCall(point, font); + return MSOldCall(rect, font, mode, alignment, spacing, emoji, truncation); if (--state->count_ == 0) stringDrawingState_ = state->next_; if (state->info_ == nil) - return MSOldCall(point, font); + return MSOldCall(rect, font, mode, alignment, spacing, emoji, truncation); NSString *info([Info_ objectForKey:state->info_]); if (info == nil) - return MSOldCall(point, font); + return MSOldCall(rect, font, mode, alignment, spacing, emoji, truncation); + + NSString *textAlign; + switch (alignment) { + default: + case UITextAlignmentLeft: + textAlign = @"left"; + break; + case UITextAlignmentCenter: + textAlign = @"center"; + break; + case UITextAlignmentRight: + textAlign = @"right"; + break; + } NSString *base(state->base_ ?: @""); - [self drawAtPoint:point withStyle:[NSString stringWithFormat:@"%@;%@;%@", [font markupDescription], base, info]]; + NSString *extra([NSString stringWithFormat:@"text-align: %@", textAlign]); + + if (true) + $drawLabel$(self, rect, [NSString stringWithFormat:@"%@;%@", [font markupDescription], base], info); + else + [self drawInRect:rect withStyle:[NSString stringWithFormat:@"%@;%@;%@;%@", [font markupDescription], extra, base, info]]; + return CGSizeZero; } +MSInstanceMessageHook4(CGSize, NSString, sizeWithFont,forWidth,lineBreakMode,letterSpacing, UIFont *, font, float, width, UILineBreakMode, mode, float, spacing) { + //NSLog(@"XXX: #\"%@\" \"%@\" %g %u %g", self, font, width, mode, spacing); + + WBStringDrawingState *state(stringDrawingState_); + if (state == NULL) + return MSOldCall(font, width, mode, spacing); + + if (--state->count_ == 0) + stringDrawingState_ = state->next_; + if (state->info_ == nil) + return MSOldCall(font, width, mode, spacing); + + NSString *info([Info_ objectForKey:state->info_]); + if (info == nil) + return MSOldCall(font, width, mode, spacing); + + NSString *base(state->base_ ?: @""); + NSString *extra([NSString stringWithFormat:@"letter-spacing: %gpx", spacing]); + return [self sizeWithStyle:[NSString stringWithFormat:@"%@;%@;%@;%@", [font markupDescription], extra, base, info] forWidth:width]; +} + MSInstanceMessageHook1(CGSize, NSString, sizeWithFont, UIFont *, font) { + //NSLog(@"XXX: ?\"%@\"", self); + WBStringDrawingState *state(stringDrawingState_); if (state == NULL) return MSOldCall(font); @@ -867,6 +962,7 @@ MSHook(void, SBStatusBarContentsView$didMoveToSuperview, UIView *self, SEL sel) static NSArray *Wallpapers_; static bool Papered_; static bool Docked_; +static bool SMSBackgrounded_; static NSString *WallpaperFile_; static UIImageView *WallpaperImage_; static UIWebDocumentView *WallpaperPage_; @@ -1156,7 +1252,7 @@ extern "C" NSString *UIStyleStringFromColor(CGColorRef);*/ WBDelegate(time_) -- (CGSize) drawAtPoint:(CGPoint)point forWidth:(float)width withFont:(UIFont *)font lineBreakMode:(int)mode { +- (CGSize) drawAtPoint:(CGPoint)point forWidth:(float)width withFont:(UIFont *)font lineBreakMode:(UILineBreakMode)mode { if (NSString *custom = [Info_ objectForKey:@"TimeStyle"]) { BOOL &_mode(MSHookIvar(view_, "_mode"));; @@ -1203,7 +1299,7 @@ WBDelegate(time_) WBDelegate(badge_) -- (CGSize) drawAtPoint:(CGPoint)point forWidth:(float)width withFont:(UIFont *)font lineBreakMode:(int)mode { +- (CGSize) drawAtPoint:(CGPoint)point forWidth:(float)width withFont:(UIFont *)font lineBreakMode:(UILineBreakMode)mode { if (NSString *custom = [Info_ objectForKey:@"BadgeStyle"]) { [badge_ drawAtPoint:point withStyle:[NSString stringWithFormat:@"" "font-family: Helvetica; " @@ -1486,9 +1582,7 @@ MSInstanceMessageHook2(CGSize, WebCoreFrameBridge, renderedSizeOfNode,constraine } // }}} -MSInstanceMessageHook1(void, SBIconLabel, drawRect, CGRect, rect) { - CGRect bounds = [self bounds]; - +MSInstanceMessage1(void, SBIconLabel, drawRect, CGRect, rect) { static Ivar drawMoreLegibly = object_getInstanceVariable(self, "_drawMoreLegibly", NULL); int docked; @@ -1511,35 +1605,39 @@ MSInstanceMessageHook1(void, SBIconLabel, drawRect, CGRect, rect) { else if (docked) style = [style stringByAppendingString:@"text-shadow: rgba(0, 0, 0, 0.5) 0px -1px 0px; "]; - bool ellipsis(false); - float max = [self frame].size.width - 11, width; - width: - width = [(ellipsis ? [label stringByAppendingString:@"..."] : label) sizeWithStyle:style forWidth:320].width; + NSString *custom([Info_ objectForKey:(docked ? @"DockedIconLabelStyle" : @"UndockedIconLabelStyle")]); - if (width > max) { - size_t length([label length]); - float spacing((width - max) / (length - 1)); + $drawLabel$(label, [self bounds], style, custom); +} - if (spacing > 1.25) { - ellipsis = true; - label = [label substringToIndex:(length - 1)]; - goto width; - } +MSInstanceMessage0(CGImageRef, SBIconLabel, buildLabelImage) { + bool docked((MSHookIvar(self, "_inDock") & 0x2) != 0); - style = [style stringByAppendingString:[NSString stringWithFormat:@"letter-spacing: -%f; ", spacing]]; - } + WBStringDrawingState labelState = {NULL, 0, @"" + "color: white;" + , docked ? @"DockedIconLabelStyle" : @"UndockedIconLabelStyle"}; - if (ellipsis) - label = [label stringByAppendingString:@"..."]; + stringDrawingState_ = &labelState; - if (NSString *custom = [Info_ objectForKey:(docked ? @"DockedIconLabelStyle" : @"UndockedIconLabelStyle")]) - style = [style stringByAppendingString:custom]; + //NSLog(@"XXX: +"); + CGImageRef image(MSOldCall()); + //NSLog(@"XXX: -"); - CGSize size = [label sizeWithStyle:style forWidth:bounds.size.width]; - [label drawAtPoint:CGPointMake((bounds.size.width - size.width) / 2, 0) withStyle:style]; + stringDrawingState_ = NULL; + return image; } // ChatKit {{{ +MSInstanceMessageHook2(id, CKBalloonView, initWithFrame,delegate, CGRect, frame, id, delegate) { + if ((self = MSOldCall(frame, delegate)) != nil) { + [self setBackgroundColor:[UIColor clearColor]]; + } return self; +} + +MSInstanceMessageHook0(BOOL, CKBalloonView, _canUseLayerBackedBalloon) { + return SMSBackgrounded_ ? NO : MSOldCall(); +} + MSInstanceMessageHook0(void, CKTranscriptHeaderView, layoutSubviews) { [self wb$setBackgroundColor:[UIColor clearColor]]; return MSOldCall(); @@ -1593,6 +1691,8 @@ MSInstanceMessageHook0(void, CKTranscriptController, loadView) { if (NSString *path = $getTheme$($useScale$([NSArray arrayWithObjects:@"SMSBackground.png", @"SMSBackground.jpg", nil]))) if (UIImage *image = $getImage$(path)) { + SMSBackgrounded_ = true; + UIView *&_transcriptTable(MSHookIvar(self, "_transcriptTable")); UIView *&_transcriptLayer(MSHookIvar(self, "_transcriptLayer")); UIView *table; @@ -1711,7 +1811,7 @@ MSHook(bool, _Z24GetFileNameForThisActionmPcRb, unsigned long a0, char *a1, bool NSString *path([NSString stringWithFormat:@"%@/UISounds/%@", theme, file]); if ([Manager_ fileExistsAtPath:path]) { strcpy(a1, [path UTF8String]); - continue; + break; } } } @@ -1780,17 +1880,27 @@ static void NSString$drawAtPoint$withStyle$(NSString *self, SEL _cmd, CGPoint po WKSetCurrentGraphicsContext(UIGraphicsGetCurrentContext()); if (style == nil || [style length] == 0) style = @"font-family: Helvetica; font-size: 12px"; + //NSLog(@"XXX:draw(%@)", [style stringByReplacingOccurrencesOfString:@"\n" withString:@" "]); return [[WBMarkup sharedMarkup] drawString:self atPoint:point withStyle:style]; } +static void NSString$drawInRect$withStyle$(NSString *self, SEL _cmd, CGRect rect, NSString *style) { + WKSetCurrentGraphicsContext(UIGraphicsGetCurrentContext()); + if (style == nil || [style length] == 0) + style = @"font-family: Helvetica; font-size: 12px"; + return [[WBMarkup sharedMarkup] drawString:self inRect:rect withStyle:style]; +} + static CGSize NSString$sizeWithStyle$forWidth$(NSString *self, SEL _cmd, NSString *style, float width) { if (style == nil || [style length] == 0) style = @"font-family: Helvetica; font-size: 12px"; + //NSLog(@"XXX:size(%@)", [style stringByReplacingOccurrencesOfString:@"\n" withString:@" "]); return [[WBMarkup sharedMarkup] sizeOfString:self withStyle:style forWidth:width]; } static void SBInitialize() { class_addMethod($NSString, @selector(drawAtPoint:withStyle:), (IMP) &NSString$drawAtPoint$withStyle$, "v20@0:4{CGPoint=ff}8@16"); + class_addMethod($NSString, @selector(drawInRect:withStyle:), (IMP) &NSString$drawInRect$withStyle$, "v28@0:4{CGRect={CGSize=ff}{CGSize=ff}}8@24"); class_addMethod($NSString, @selector(sizeWithStyle:forWidth:), (IMP) &NSString$sizeWithStyle$forWidth$, "{CGSize=ff}16@0:4@8f12"); if (SummerBoard_) { @@ -1810,6 +1920,11 @@ static void SBInitialize() { WBRename(SBDockIconListView, setFrame:, setFrame$); MSHookMessage(object_getClass($SBDockIconListView), @selector(shouldShowNewDock), &$SBDockIconListView$shouldShowNewDock, &_SBDockIconListView$shouldShowNewDock); + if (kCFCoreFoundationVersionNumber < 600 || SummerBoard_) + WBRename(SBIconLabel, drawRect:, drawRect$); + else + WBRename(SBIconLabel, buildLabelImage, buildLabelImage); + WBRename(SBIconLabel, initWithSize:label:, initWithSize$label$); WBRename(SBIconLabel, setInDock:, setInDock$); @@ -1855,6 +1970,9 @@ MSInitialize { if (NSDictionary *settings = [NSDictionary dictionaryWithContentsOfFile:[NSString stringWithFormat:@"/User/Library/Preferences/com.saurik.WinterBoard.plist"]]) { if (NSNumber *value = [settings objectForKey:@"SummerBoard"]) SummerBoard_ = [value boolValue]; + else + SummerBoard_ = true; + if (NSNumber *value = [settings objectForKey:@"Debug"]) Debug_ = [value boolValue]; if (NSNumber *value = [settings objectForKey:@"RecordUI"]) @@ -1928,7 +2046,7 @@ MSInitialize { if (SpringBoard_) { Wallpapers_ = [[NSArray arrayWithObjects:@"Wallpaper.mp4", @"Wallpaper@2x.png", @"Wallpaper@2x.jpg", @"Wallpaper.png", @"Wallpaper.jpg", @"Wallpaper.html", nil] retain]; Papered_ = $getTheme$(Wallpapers_) != nil; - Docked_ = $getTheme$([NSArray arrayWithObjects:@"Dock.png", nil]); + Docked_ = $getTheme$([NSArray arrayWithObjects:@"Dock.png", nil]) != nil; CFNotificationCenterAddObserver( CFNotificationCenterGetDarwinNotifyCenter(),