diff --git a/.travis.yml b/.travis.yml index 9d25a169c..9fae405f8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,11 +3,10 @@ language: objective-c before_install: - brew update + - brew upgrade xctool install: - - brew upgrade xctool - sudo easy_install cpp-coveralls - - curl -sL https://gist.github.com/henrikhodne/7ac6d02ff9a24a94720c/raw/install_appledoc.sh | sh script: - xctool -project DTCoreText.xcodeproj -scheme DemoApp build test -sdk iphonesimulator -arch i386 ONLY_ACTIVE_ARCH=NO diff --git a/Core/Source/DTAttributedTextContentView.m b/Core/Source/DTAttributedTextContentView.m index 7d5e95f36..50c5f2559 100644 --- a/Core/Source/DTAttributedTextContentView.m +++ b/Core/Source/DTAttributedTextContentView.m @@ -1005,8 +1005,14 @@ - (NSInteger)accessibilityElementCount - (id)accessibilityElementAtIndex:(NSInteger)index { - DTAccessibilityElement *element = [[self accessibilityElements] objectAtIndex:index]; - return element; + NSUInteger count = [self accessibilityElementCount]; + + if (count > 0 && index < count) + { + return [[self accessibilityElements] objectAtIndex:index]; + } + + return nil; } - (NSInteger)indexOfAccessibilityElement:(id)element diff --git a/Core/Source/DTCoreTextFontDescriptor.m b/Core/Source/DTCoreTextFontDescriptor.m index 50cfc80de..98d287580 100644 --- a/Core/Source/DTCoreTextFontDescriptor.m +++ b/Core/Source/DTCoreTextFontDescriptor.m @@ -462,45 +462,45 @@ - (BOOL)supportsNativeSmallCaps return YES; } - CTFontRef tmpFont = [self newMatchingFont]; - BOOL smallCapsSupported = NO; - // check if this font supports small caps - CFArrayRef fontFeatures = CTFontCopyFeatures(tmpFont); + CTFontRef tmpFont = [self newMatchingFont]; - if (fontFeatures) + if (tmpFont) { - for (NSDictionary *oneFeature in (__bridge NSArray *)fontFeatures) + // check if this font supports small caps + CFArrayRef fontFeatures = CTFontCopyFeatures(tmpFont); + + if (fontFeatures) { - NSInteger featureTypeIdentifier = [[oneFeature objectForKey:(id)kCTFontFeatureTypeIdentifierKey] integerValue]; - - if (featureTypeIdentifier == 3) // Letter Case + for (NSDictionary *oneFeature in (__bridge NSArray *)fontFeatures) { - NSArray *featureSelectors = [oneFeature objectForKey:(id)kCTFontFeatureTypeSelectorsKey]; + NSInteger featureTypeIdentifier = [[oneFeature objectForKey:(id)kCTFontFeatureTypeIdentifierKey] integerValue]; - for (NSDictionary *oneFeatureSelector in featureSelectors) + if (featureTypeIdentifier == 3) // Letter Case { - NSInteger featureSelectorIdentifier = [[oneFeatureSelector objectForKey:(id)kCTFontFeatureSelectorIdentifierKey] integerValue]; + NSArray *featureSelectors = [oneFeature objectForKey:(id)kCTFontFeatureTypeSelectorsKey]; - if (featureSelectorIdentifier == 3) // Small Caps + for (NSDictionary *oneFeatureSelector in featureSelectors) { - // hooray, small caps supported! - smallCapsSupported = YES; + NSInteger featureSelectorIdentifier = [[oneFeatureSelector objectForKey:(id)kCTFontFeatureSelectorIdentifierKey] integerValue]; - break; + if (featureSelectorIdentifier == 3) // Small Caps + { + // hooray, small caps supported! + smallCapsSupported = YES; + + break; + } } + + break; } - - break; } + + CFRelease(fontFeatures); } - - CFRelease(fontFeatures); - } - if (tmpFont) - { CFRelease(tmpFont); } diff --git a/Core/Source/DTHTMLElement.m b/Core/Source/DTHTMLElement.m index d969a5cc3..cc653e632 100644 --- a/Core/Source/DTHTMLElement.m +++ b/Core/Source/DTHTMLElement.m @@ -867,64 +867,69 @@ - (void)applyStyleDictionary:(NSDictionary *)styles // check if this is a known font family CTFontRef font = [_fontDescriptor newMatchingFont]; - NSString *foundFamily = CFBridgingRelease(CTFontCopyFamilyName(font)); - if ([foundFamily isEqualToString:fontFamily]) + if (font) { - foundFontFamily = YES; - break; - } - - NSString *lowercaseFontFamily = [fontFamily lowercaseString]; - - if ([lowercaseFontFamily rangeOfString:@"geneva"].length) - { - _fontDescriptor.fontFamily = @"Helvetica"; - foundFontFamily = YES; - } - else if ([lowercaseFontFamily rangeOfString:@"cursive"].length) - { - _fontDescriptor.stylisticClass = kCTFontScriptsClass; - _fontDescriptor.fontFamily = nil; - foundFontFamily = YES; - } - else if ([lowercaseFontFamily rangeOfString:@"sans-serif"].length) - { - // too many matches (24) - // fontDescriptor.stylisticClass = kCTFontSansSerifClass; - _fontDescriptor.fontFamily = @"Helvetica"; - foundFontFamily = YES; - } - else if ([lowercaseFontFamily rangeOfString:@"serif"].length) - { - // kCTFontTransitionalSerifsClass = Baskerville - // kCTFontClarendonSerifsClass = American Typewriter - // kCTFontSlabSerifsClass = Courier New - // - // strangely none of the classes yields Times - _fontDescriptor.fontFamily = @"Times New Roman"; - foundFontFamily = YES; - } - else if ([lowercaseFontFamily rangeOfString:@"fantasy"].length) - { - _fontDescriptor.fontFamily = @"Papyrus"; // only available on iPad - foundFontFamily = YES; - } - else if ([lowercaseFontFamily rangeOfString:@"monospace"].length) - { - _fontDescriptor.monospaceTrait = YES; - _fontDescriptor.fontFamily = @"Courier"; - foundFontFamily = YES; - } - else if ([lowercaseFontFamily rangeOfString:@"times"].length) - { - _fontDescriptor.fontFamily = @"Times New Roman"; - foundFontFamily = YES; - } - else if ([lowercaseFontFamily isEqualToString:@"inherit"]) - { - _fontDescriptor.fontFamily = self.parentElement.fontDescriptor.fontFamily; - foundFontFamily = YES; + NSString *foundFamily = CFBridgingRelease(CTFontCopyFamilyName(font)); + CFRelease(font); + + if ([foundFamily isEqualToString:fontFamily]) + { + foundFontFamily = YES; + break; + } + + NSString *lowercaseFontFamily = [fontFamily lowercaseString]; + + if ([lowercaseFontFamily rangeOfString:@"geneva"].length) + { + _fontDescriptor.fontFamily = @"Helvetica"; + foundFontFamily = YES; + } + else if ([lowercaseFontFamily rangeOfString:@"cursive"].length) + { + _fontDescriptor.stylisticClass = kCTFontScriptsClass; + _fontDescriptor.fontFamily = nil; + foundFontFamily = YES; + } + else if ([lowercaseFontFamily rangeOfString:@"sans-serif"].length) + { + // too many matches (24) + // fontDescriptor.stylisticClass = kCTFontSansSerifClass; + _fontDescriptor.fontFamily = @"Helvetica"; + foundFontFamily = YES; + } + else if ([lowercaseFontFamily rangeOfString:@"serif"].length) + { + // kCTFontTransitionalSerifsClass = Baskerville + // kCTFontClarendonSerifsClass = American Typewriter + // kCTFontSlabSerifsClass = Courier New + // + // strangely none of the classes yields Times + _fontDescriptor.fontFamily = @"Times New Roman"; + foundFontFamily = YES; + } + else if ([lowercaseFontFamily rangeOfString:@"fantasy"].length) + { + _fontDescriptor.fontFamily = @"Papyrus"; // only available on iPad + foundFontFamily = YES; + } + else if ([lowercaseFontFamily rangeOfString:@"monospace"].length) + { + _fontDescriptor.monospaceTrait = YES; + _fontDescriptor.fontFamily = @"Courier"; + foundFontFamily = YES; + } + else if ([lowercaseFontFamily rangeOfString:@"times"].length) + { + _fontDescriptor.fontFamily = @"Times New Roman"; + foundFontFamily = YES; + } + else if ([lowercaseFontFamily isEqualToString:@"inherit"]) + { + _fontDescriptor.fontFamily = self.parentElement.fontDescriptor.fontFamily; + foundFontFamily = YES; + } } if (foundFontFamily) @@ -1329,6 +1334,12 @@ - (void)applyStyleDictionary:(NSDictionary *)styles { self.paragraphStyle.paragraphSpacing = _margins.bottom; } + + NSString *coretextFontString = [styles objectForKey:@"-coretext-fontname"]; + if (coretextFontString) + { + _fontDescriptor.fontName = [styles objectForKey:@"-coretext-fontname"]; + } } - (DTCSSListStyle *)listStyle diff --git a/Core/Source/DTImageTextAttachment.m b/Core/Source/DTImageTextAttachment.m index 93b87ec0c..c89946000 100644 --- a/Core/Source/DTImageTextAttachment.m +++ b/Core/Source/DTImageTextAttachment.m @@ -46,11 +46,7 @@ - (id)initWithElement:(DTHTMLElement *)element options:(NSDictionary *)options if (self) { - // get base URL - NSURL *baseURL = [options objectForKey:NSBaseURLDocumentOption]; - NSString *src = [element.attributes objectForKey:@"src"]; - - [self _decodeImageSrc:src relativeToBaseURL:baseURL]; + [self _decodeImageFromElement:element options:options]; } return self; @@ -69,8 +65,12 @@ - (id)initWithImage:(DTImage *)image } -- (void)_decodeImageSrc:(NSString *)src relativeToBaseURL:(NSURL *)baseURL +- (void)_decodeImageFromElement:(DTHTMLElement *)element options:(NSDictionary *)options { + // get base URL + NSURL *baseURL = [options objectForKey:NSBaseURLDocumentOption]; + NSString *src = [element.attributes objectForKey:@"src"]; + NSURL *contentURL = nil; // decode content URL @@ -101,7 +101,52 @@ - (void)_decodeImageSrc:(NSString *)src relativeToBaseURL:(NSURL *)baseURL // if we have image data, get the default display size if (decodedData) { - self.image = [[DTImage alloc] initWithData:decodedData]; + DTImage *decodedImage = [[DTImage alloc] initWithData:decodedData]; + + // we don't know the content scale from such images, need to infer it from size in style + NSString *styles = [element.attributes objectForKey:@"style"]; + + // that only works if there is a style dictionary + if (styles) + { + NSDictionary *attributes = [styles dictionaryOfCSSStyles]; + + NSString *widthStr = attributes[@"width"]; + NSString *heightStr = attributes[@"height"]; + + if ([widthStr hasSuffix:@"px"] && [heightStr hasSuffix:@"px"]) + { + CGSize sizeAccordingToStyle; + + // those style size values are the original image size + sizeAccordingToStyle.width = [widthStr pixelSizeOfCSSMeasureRelativeToCurrentTextSize:0 textScale:1]; + sizeAccordingToStyle.height = [heightStr pixelSizeOfCSSMeasureRelativeToCurrentTextSize:0 textScale:1]; + + // if _orgiginal width and height are a fraction of decode image size, it must be a scaled image + if (sizeAccordingToStyle.width && sizeAccordingToStyle.width < decodedImage.size.width && + sizeAccordingToStyle.height && sizeAccordingToStyle.height < decodedImage.size.height) + { + // determine image scale + CGFloat scale = round(decodedImage.size.width/sizeAccordingToStyle.width); + + // sanity check, accept from @2x - @5x + if (scale>=2.0 && scale<=5.0) + { +#if TARGET_OS_IPHONE + // on iOS change the scale by making a new image with same pixels + decodedImage = [DTImage imageWithCGImage:decodedImage.CGImage scale:scale orientation:decodedImage.imageOrientation]; +#else + // on OS X we can set the size + [decodedImage setSize:sizeAccordingToStyle]; +#endif + } + } + } + } + + self.image = decodedImage; + + // prevent remote loading of image _contentURL = nil; } } diff --git a/Core/Source/DTListItemHTMLElement.m b/Core/Source/DTListItemHTMLElement.m index 305e6d71c..e6c3577c9 100644 --- a/Core/Source/DTListItemHTMLElement.m +++ b/Core/Source/DTListItemHTMLElement.m @@ -141,18 +141,21 @@ - (NSAttributedString *)_listPrefix CTFontRef font = [fontDescriptor newMatchingFont]; -#if DTCORETEXT_SUPPORT_NS_ATTRIBUTES && __IPHONE_OS_VERSION_MAX_ALLOWED > __IPHONE_5_1 - if (___useiOS6Attributes) + if (font) { - UIFont *uiFont = [UIFont fontWithCTFont:font]; - [newAttributes setObject:uiFont forKey:NSFontAttributeName]; - - CFRelease(font); - } - else +#if DTCORETEXT_SUPPORT_NS_ATTRIBUTES && __IPHONE_OS_VERSION_MAX_ALLOWED > __IPHONE_5_1 + if (___useiOS6Attributes) + { + UIFont *uiFont = [UIFont fontWithCTFont:font]; + [newAttributes setObject:uiFont forKey:NSFontAttributeName]; + + CFRelease(font); + } + else #endif - { - [newAttributes setObject:CFBridgingRelease(font) forKey:(id)kCTFontAttributeName]; + { + [newAttributes setObject:CFBridgingRelease(font) forKey:(id)kCTFontAttributeName]; + } } CGColorRef textColor = (__bridge CGColorRef)[attributes objectForKey:(id)kCTForegroundColorAttributeName]; diff --git a/Core/Source/DTTextHTMLElement.m b/Core/Source/DTTextHTMLElement.m index 209e480bf..3442ed4a3 100644 --- a/Core/Source/DTTextHTMLElement.m +++ b/Core/Source/DTTextHTMLElement.m @@ -80,22 +80,26 @@ - (NSAttributedString *)attributedString { DTCoreTextFontDescriptor *smallDesc = [self.fontDescriptor copy]; smallDesc.smallCapsFeature = YES; - - CTFontRef smallerFont = [smallDesc newMatchingFont]; + NSMutableDictionary *smallAttributes = [attributes mutableCopy]; - -#if DTCORETEXT_SUPPORT_NS_ATTRIBUTES && TARGET_OS_IPHONE - if (___useiOS6Attributes) + + CTFontRef smallerFont = [smallDesc newMatchingFont]; + + if (smallerFont) { - UIFont *font = [UIFont fontWithCTFont:smallerFont]; - - [smallAttributes setObject:font forKey:NSFontAttributeName]; - CFRelease(smallerFont); - } - else +#if DTCORETEXT_SUPPORT_NS_ATTRIBUTES && TARGET_OS_IPHONE + if (___useiOS6Attributes) + { + UIFont *font = [UIFont fontWithCTFont:smallerFont]; + + [smallAttributes setObject:font forKey:NSFontAttributeName]; + CFRelease(smallerFont); + } + else #endif - { - [smallAttributes setObject:CFBridgingRelease(smallerFont) forKey:(id)kCTFontAttributeName]; + { + [smallAttributes setObject:CFBridgingRelease(smallerFont) forKey:(id)kCTFontAttributeName]; + } } return [[NSAttributedString alloc] initWithString:_text attributes:smallAttributes]; diff --git a/Core/Source/NSAttributedString+DTCoreText.m b/Core/Source/NSAttributedString+DTCoreText.m index f6cb2cb07..a9966bd48 100644 --- a/Core/Source/NSAttributedString+DTCoreText.m +++ b/Core/Source/NSAttributedString+DTCoreText.m @@ -386,18 +386,21 @@ + (NSAttributedString *)prefixForListItemWithCounter:(NSUInteger)listCounter lis font = [fontDesc newMatchingFont]; -#if DTCORETEXT_SUPPORT_NS_ATTRIBUTES && __IPHONE_OS_VERSION_MAX_ALLOWED > __IPHONE_5_1 - if (___useiOS6Attributes) + if (font) { - UIFont *uiFont = [UIFont fontWithCTFont:font]; - [newAttributes setObject:uiFont forKey:NSFontAttributeName]; - - CFRelease(font); - } - else +#if DTCORETEXT_SUPPORT_NS_ATTRIBUTES && __IPHONE_OS_VERSION_MAX_ALLOWED > __IPHONE_5_1 + if (___useiOS6Attributes) + { + UIFont *uiFont = [UIFont fontWithCTFont:font]; + [newAttributes setObject:uiFont forKey:NSFontAttributeName]; + + CFRelease(font); + } + else #endif - { - [newAttributes setObject:CFBridgingRelease(font) forKey:(id)kCTFontAttributeName]; + { + [newAttributes setObject:CFBridgingRelease(font) forKey:(id)kCTFontAttributeName]; + } } } diff --git a/Core/Source/NSMutableAttributedString+HTML.m b/Core/Source/NSMutableAttributedString+HTML.m index 826a573bc..78f90c0d8 100644 --- a/Core/Source/NSMutableAttributedString+HTML.m +++ b/Core/Source/NSMutableAttributedString+HTML.m @@ -77,19 +77,22 @@ - (void)appendString:(NSString *)string withParagraphStyle:(DTCoreTextParagraphS { CTFontRef newFont = [fontDescriptor newMatchingFont]; -#if DTCORETEXT_SUPPORT_NS_ATTRIBUTES && TARGET_OS_IPHONE - if (___useiOS6Attributes) + if (newFont) { - // convert to UIFont - UIFont *uiFont = [UIFont fontWithCTFont:newFont]; - [attributes setObject:uiFont forKey:NSFontAttributeName]; - - CFRelease(newFont); - } - else +#if DTCORETEXT_SUPPORT_NS_ATTRIBUTES && TARGET_OS_IPHONE + if (___useiOS6Attributes) + { + // convert to UIFont + UIFont *uiFont = [UIFont fontWithCTFont:newFont]; + [attributes setObject:uiFont forKey:NSFontAttributeName]; + + CFRelease(newFont); + } + else #endif - { - [attributes setObject:CFBridgingRelease(newFont) forKey:(id)kCTFontAttributeName]; + { + [attributes setObject:CFBridgingRelease(newFont) forKey:(id)kCTFontAttributeName]; + } } } diff --git a/Core/Source/UIFont+DTCoreText.m b/Core/Source/UIFont+DTCoreText.m index 5165131a1..4b2c50e0b 100644 --- a/Core/Source/UIFont+DTCoreText.m +++ b/Core/Source/UIFont+DTCoreText.m @@ -13,8 +13,17 @@ @implementation UIFont (DTCoreText) + (UIFont *)fontWithCTFont:(CTFontRef)ctFont { NSString *fontName = (__bridge_transfer NSString *)CTFontCopyName(ctFont, kCTFontPostScriptNameKey); + CGFloat fontSize = CTFontGetSize(ctFont); - return [UIFont fontWithName:fontName size:fontSize]; + UIFont *font = [UIFont fontWithName:fontName size:fontSize]; + + // fix for missing HelveticaNeue-Italic font in iOS 7.0.x + if (!font && [fontName isEqualToString:@"HelveticaNeue-Italic"]) + { + font = [UIFont fontWithName:@"HelveticaNeue-LightItalic" size:fontSize]; + } + + return font; } @end diff --git a/DTCoreText.podspec b/DTCoreText.podspec index 62a20b561..49d83d7cf 100644 --- a/DTCoreText.podspec +++ b/DTCoreText.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |spec| spec.name = 'DTCoreText' - spec.version = '1.6.13' + spec.version = '1.6.14' spec.platform = :ios, '4.3' spec.license = 'BSD' spec.source = { :git => 'https://github.com/Cocoanetics/DTCoreText.git', :tag => spec.version.to_s } diff --git a/DTCoreText.xcodeproj/project.pbxproj b/DTCoreText.xcodeproj/project.pbxproj index a2df4c0d9..f3363da8c 100644 --- a/DTCoreText.xcodeproj/project.pbxproj +++ b/DTCoreText.xcodeproj/project.pbxproj @@ -144,6 +144,9 @@ A7675E7D172EA24700C548CB /* NSAttributedString+DTDebug.m in Sources */ = {isa = PBXBuildFile; fileRef = A7675E76172EA24700C548CB /* NSAttributedString+DTDebug.m */; }; A7675E7E172EA24700C548CB /* NSAttributedString+DTDebug.m in Sources */ = {isa = PBXBuildFile; fileRef = A7675E76172EA24700C548CB /* NSAttributedString+DTDebug.m */; }; A768BE4717FC547E008834C6 /* NSDictionaryDTCoreText.m in Sources */ = {isa = PBXBuildFile; fileRef = A768BE4617FC547E008834C6 /* NSDictionaryDTCoreText.m */; }; + A76B316019E681200021243F /* libDTAnimatedGIF.a in Frameworks */ = {isa = PBXBuildFile; fileRef = A7F0C43A1965A0D600D7FAFB /* libDTAnimatedGIF.a */; }; + A76B316119E681290021243F /* libDTHTMLParser_iOS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = A781FE9B17FAABE500A1F5E8 /* libDTHTMLParser_iOS.a */; }; + A76B316219E681500021243F /* libDTFoundation.a in Frameworks */ = {isa = PBXBuildFile; fileRef = A781FE9117FAABE500A1F5E8 /* libDTFoundation.a */; }; A76C23D618353EFE00F54F02 /* Oliver.jpg in Resources */ = {isa = PBXBuildFile; fileRef = A788CA2814863EF100E1AFD9 /* Oliver.jpg */; }; A76C23D718353F0A00F54F02 /* Oliver@2x.jpg in Resources */ = {isa = PBXBuildFile; fileRef = A76C23B1183535A300F54F02 /* Oliver@2x.jpg */; }; A76C23FF1835423200F54F02 /* Oliver@2x.jpg in Resources */ = {isa = PBXBuildFile; fileRef = A76C23B1183535A300F54F02 /* Oliver@2x.jpg */; }; @@ -421,6 +424,10 @@ A7DBC1B71689BA20003F1D38 /* DTHTMLAttributedStringBuilderTest.m in Sources */ = {isa = PBXBuildFile; fileRef = A7DBC1B61689BA20003F1D38 /* DTHTMLAttributedStringBuilderTest.m */; }; A7DBE49B12E6E53C00F25897 /* MediaPlayer.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A7DBE49A12E6E53C00F25897 /* MediaPlayer.framework */; }; A7DBE4F812E6E5B000F25897 /* AVFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A7DBE4F712E6E5B000F25897 /* AVFoundation.framework */; }; + A7DDDCA519F1615500EAE9BA /* RetinaDataURL.html in Resources */ = {isa = PBXBuildFile; fileRef = A7DDDCA419F1615500EAE9BA /* RetinaDataURL.html */; }; + A7DDDCA619F1615500EAE9BA /* RetinaDataURL.html in Resources */ = {isa = PBXBuildFile; fileRef = A7DDDCA419F1615500EAE9BA /* RetinaDataURL.html */; }; + A7DDDCBB19F166B700EAE9BA /* NavTag.plist in Resources */ = {isa = PBXBuildFile; fileRef = A7DDDCBA19F166B700EAE9BA /* NavTag.plist */; }; + A7DDDCBD19F166F600EAE9BA /* CSSCascading.plist in Resources */ = {isa = PBXBuildFile; fileRef = A7DDDCBC19F166F600EAE9BA /* CSSCascading.plist */; }; A7DDF87717DDEB630005D62D /* DTColorFunctions.h in Headers */ = {isa = PBXBuildFile; fileRef = A7DDF87617DDEB630005D62D /* DTColorFunctions.h */; settings = {ATTRIBUTES = (Public, ); }; }; A7DDF87817DDEB630005D62D /* DTColorFunctions.h in Headers */ = {isa = PBXBuildFile; fileRef = A7DDF87617DDEB630005D62D /* DTColorFunctions.h */; settings = {ATTRIBUTES = (Public, ); }; }; A7DDF87917DDEB630005D62D /* DTColorFunctions.h in Headers */ = {isa = PBXBuildFile; fileRef = A7DDF87617DDEB630005D62D /* DTColorFunctions.h */; }; @@ -698,6 +705,13 @@ remoteGlobalIDString = A7AC21AE196417830009E1B9; remoteInfo = "DTAnimatedGIF (iOS)"; }; + A76B314B19E680C30021243F /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = A785701C17FAA69D0080AB0A /* DTFoundation.xcodeproj */; + proxyType = 1; + remoteGlobalIDString = A7AC21AE196417830009E1B9; + remoteInfo = "DTAnimatedGIF (iOS)"; + }; A781FE8E17FAABE500A1F5E8 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = A785701C17FAA69D0080AB0A /* DTFoundation.xcodeproj */; @@ -960,6 +974,7 @@ A70ED6CD17F99BD9008A801A /* NSAttributedStringDTCoreTextTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NSAttributedStringDTCoreTextTest.m; sourceTree = ""; }; A70F119B14863198009202BF /* DTCoreText.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = DTCoreText.framework; sourceTree = BUILT_PRODUCTS_DIR; }; A70F11DE148632CD009202BF /* libDTCoreText.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libDTCoreText.a; sourceTree = BUILT_PRODUCTS_DIR; }; + A717BDE319E5A06C0024EF95 /* DTCoreTextMacros.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DTCoreTextMacros.h; sourceTree = ""; }; A71B927014E0165000360C30 /* PreWhitespace.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = PreWhitespace.html; sourceTree = ""; }; A71B927214E016A300360C30 /* PreWhitespace.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = PreWhitespace.plist; sourceTree = ""; }; A72418161678BACE001362C4 /* iOS6.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = iOS6.html; sourceTree = ""; }; @@ -1152,6 +1167,9 @@ A7DBE4F712E6E5B000F25897 /* AVFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AVFoundation.framework; path = System/Library/Frameworks/AVFoundation.framework; sourceTree = SDKROOT; }; A7DC5CED17F81DEE006ADDF5 /* DTCoreTextTestLog.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DTCoreTextTestLog.h; sourceTree = ""; }; A7DC5CEE17F81DEE006ADDF5 /* DTCoreTextTestLog.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DTCoreTextTestLog.m; sourceTree = ""; }; + A7DDDCA419F1615500EAE9BA /* RetinaDataURL.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = RetinaDataURL.html; sourceTree = ""; }; + A7DDDCBA19F166B700EAE9BA /* NavTag.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = NavTag.plist; sourceTree = ""; }; + A7DDDCBC19F166F600EAE9BA /* CSSCascading.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = CSSCascading.plist; sourceTree = ""; }; A7DDF87617DDEB630005D62D /* DTColorFunctions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DTColorFunctions.h; sourceTree = ""; }; A7DDF87B17DDEB780005D62D /* DTColorFunctions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DTColorFunctions.m; sourceTree = ""; }; A7E3346C16837482002EFCBE /* DTCSSStylesheetTest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DTCSSStylesheetTest.h; sourceTree = ""; }; @@ -1215,6 +1233,9 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + A76B316219E681500021243F /* libDTFoundation.a in Frameworks */, + A76B316119E681290021243F /* libDTHTMLParser_iOS.a in Frameworks */, + A76B316019E681200021243F /* libDTAnimatedGIF.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1447,21 +1468,21 @@ A781FE9917FAABE500A1F5E8 /* libDTASN1.a */, A781FE9B17FAABE500A1F5E8 /* libDTHTMLParser_iOS.a */, A781FE9D17FAABE500A1F5E8 /* libDTHTMLParser_Mac.a */, - A781FE9F17FAABE500A1F5E8 /* libDTZipArchive_iOS.a */, - A781FEA117FAABE500A1F5E8 /* libDTZipArchive_Mac.a */, - A781FEA317FAABE500A1F5E8 /* libDTUTI_iOS.a */, - A781FEA517FAABE500A1F5E8 /* libDTUTI_Mac.a */, + A7F0C43C1965A0D600D7FAFB /* libDTProgressHUD_iOS.a */, A781FEA717FAABE500A1F5E8 /* libDTReachability_iOS.a */, A781FEA917FAABE500A1F5E8 /* libDTReachability_Mac.a */, A781FEAB17FAABE500A1F5E8 /* libDTSQLite_iOS.a */, A781FEAD17FAABE500A1F5E8 /* libDTSQLite_Mac.a */, - A7F0C43C1965A0D600D7FAFB /* libDTProgressHUD_iOS.a */, - A781FEAF17FAABE500A1F5E8 /* DTSidePanels Demo.app */, + A781FEA317FAABE500A1F5E8 /* libDTUTI_iOS.a */, + A781FEA517FAABE500A1F5E8 /* libDTUTI_Mac.a */, + A781FE9F17FAABE500A1F5E8 /* libDTZipArchive_iOS.a */, + A781FEA117FAABE500A1F5E8 /* libDTZipArchive_Mac.a */, + A7F0C4401965A0D600D7FAFB /* DTAnimatedGIF Demo.app */, + A7F0C43E1965A0D600D7FAFB /* DTProgressHUD Demo.app */, A781FEB117FAABE500A1F5E8 /* DTReachability Demo.app */, + A781FEAF17FAABE500A1F5E8 /* DTSidePanels Demo.app */, A781FEB317FAABE500A1F5E8 /* DTZipArchive.app */, - A7F0C43E1965A0D600D7FAFB /* DTProgressHUD Demo.app */, A781FE9317FAABE500A1F5E8 /* Unit Tests.xctest */, - A7F0C4401965A0D600D7FAFB /* DTAnimatedGIF Demo.app */, ); name = Products; sourceTree = ""; @@ -1615,6 +1636,7 @@ A7949A4F14CC44D200A8CCDE /* DTCoreTextConstants.m */, A72D975C1684B38B005F8BA5 /* DTCoreTextFunctions.h */, A72D975D1684B38B005F8BA5 /* DTCoreTextFunctions.m */, + A717BDE319E5A06C0024EF95 /* DTCoreTextMacros.h */, A7949A4514CAF58C00A8CCDE /* DTHTMLAttributedStringBuilder.h */, A7949A4614CAF58C00A8CCDE /* DTHTMLAttributedStringBuilder.m */, A788C92614863E8700E1AFD9 /* DTCSSListStyle.h */, @@ -1729,12 +1751,14 @@ A7C7ACEB14DA62BA005A9C69 /* Resources */ = { isa = PBXGroup; children = ( + A7DDDCA419F1615500EAE9BA /* RetinaDataURL.html */, A7C7ACEC14DA62BA005A9C69 /* CustomFont.plist */, A7C7ACED14DA62BA005A9C69 /* Empty_and_Unclosed_Paragraphs.html */, A7C7AD0414DA782D005A9C69 /* ListTest.plist */, A7C7AD0214DA6EB2005A9C69 /* Video.plist */, A7C7ACEE14DA62BA005A9C69 /* WarAndPeace.plist */, A76994F614DBB3DD0047CC8D /* NavTag.html */, + A7DDDCBA19F166B700EAE9BA /* NavTag.plist */, A74C953514DC0C69002B5A45 /* MalformedURL.html */, A74C973D14DC5294002B5A45 /* Emoji.html */, A71B927014E0165000360C30 /* PreWhitespace.html */, @@ -1747,6 +1771,7 @@ A7F34D3F16CFC7C90054A512 /* RTL.html */, A7E8E1D316D22B7E001EDE51 /* EmptyLinesAndFontAttribute.html */, A7343F3217BDF64A00EF9B83 /* CSSCascading.html */, + A7DDDCBC19F166F600EAE9BA /* CSSCascading.plist */, C2CDBADA17CCD245000E4AD7 /* CSSOOMCrash.html */, A783CE6717D11D0100C84C28 /* CSSOOMCrash.plist */, ); @@ -2100,6 +2125,7 @@ A76994FD14DBB7380047CC8D /* PBXBuildRule */, ); dependencies = ( + A76B314C19E680C30021243F /* PBXTargetDependency */, A7C3A93717FAAF8100B3AEE8 /* PBXTargetDependency */, A7C3A93517FAAF6A00B3AEE8 /* PBXTargetDependency */, ); @@ -2475,6 +2501,7 @@ A7DBC1AA1689B846003F1D38 /* ListItemBulletColorAndFont.html in Resources */, A7DBC1B31689B989003F1D38 /* SpaceBetweenUnderlines.html in Resources */, A7EB8543169065F300D686B7 /* WhitespaceFollowingImagePromotedToParagraph.html in Resources */, + A7DDDCA519F1615500EAE9BA /* RetinaDataURL.html in Resources */, A7E3A5C6169360E5007A526B /* KeepMeTogether.html in Resources */, A70E630216C25734009B47BF /* Oliver.jpg in Resources */, A7F34D4016CFC7C90054A512 /* RTL.html in Resources */, @@ -2493,6 +2520,7 @@ files = ( A78D9FA51965B9BD00C80986 /* AppleConverted.html in Resources */, A78D9F9A1965B9BD00C80986 /* Video.plist in Resources */, + A7DDDCBD19F166F600EAE9BA /* CSSCascading.plist in Resources */, A78D9FA01965B9BD00C80986 /* PreWhitespace.plist in Resources */, A78D9FAB1965B9E200C80986 /* Oliver.jpg in Resources */, A78D9FA71965B9BD00C80986 /* EmptyLinesAndFontAttribute.html in Resources */, @@ -2508,9 +2536,11 @@ A78D9FA91965B9BD00C80986 /* CSSOOMCrash.html in Resources */, A78D9FA21965B9BD00C80986 /* SpaceBetweenUnderlines.html in Resources */, A78D9F9D1965B9BD00C80986 /* MalformedURL.html in Resources */, + A7DDDCA619F1615500EAE9BA /* RetinaDataURL.html in Resources */, A78D9FAA1965B9BD00C80986 /* CSSOOMCrash.plist in Resources */, A78D9FA61965B9BD00C80986 /* RTL.html in Resources */, A78D9F991965B9BD00C80986 /* ListTest.plist in Resources */, + A7DDDCBB19F166B700EAE9BA /* NavTag.plist in Resources */, A78D9FA41965B9BD00C80986 /* KeepMeTogether.html in Resources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -2895,6 +2925,11 @@ name = "DTAnimatedGIF (iOS)"; targetProxy = A758EE691965A29F00773D22 /* PBXContainerItemProxy */; }; + A76B314C19E680C30021243F /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = "DTAnimatedGIF (iOS)"; + targetProxy = A76B314B19E680C30021243F /* PBXContainerItemProxy */; + }; A781FEB917FAAD5500A1F5E8 /* PBXTargetDependency */ = { isa = PBXTargetDependency; name = "DTHTMLParser (Mac)"; @@ -2976,6 +3011,10 @@ A70F11A414863198009202BF /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + ARCHS = ( + "$(ARCHS_STANDARD)", + armv7s, + ); CONTENTS_FOLDER_PATH = "$(WRAPPER_NAME)/Versions/$(FRAMEWORK_VERSION)"; COPY_PHASE_STRIP = NO; DEAD_CODE_STRIPPING = NO; @@ -3008,6 +3047,10 @@ A70F11A514863198009202BF /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + ARCHS = ( + "$(ARCHS_STANDARD)", + armv7s, + ); CONTENTS_FOLDER_PATH = "$(WRAPPER_NAME)/Versions/$(FRAMEWORK_VERSION)"; COPY_PHASE_STRIP = YES; DEAD_CODE_STRIPPING = NO; @@ -3038,6 +3081,10 @@ A70F11E7148632CD009202BF /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + ARCHS = ( + "$(ARCHS_STANDARD)", + armv7s, + ); CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_SUSPICIOUS_IMPLICIT_CONVERSION = YES; COPY_PHASE_STRIP = NO; @@ -3060,6 +3107,10 @@ A70F11E8148632CD009202BF /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + ARCHS = ( + "$(ARCHS_STANDARD)", + armv7s, + ); CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_SUSPICIOUS_IMPLICIT_CONVERSION = YES; COPY_PHASE_STRIP = YES; @@ -3316,6 +3367,10 @@ A7DC5CFD17F833F1006ADDF5 /* Coverage */ = { isa = XCBuildConfiguration; buildSettings = { + ARCHS = ( + "$(ARCHS_STANDARD)", + armv7s, + ); CONTENTS_FOLDER_PATH = "$(WRAPPER_NAME)/Versions/$(FRAMEWORK_VERSION)"; COPY_PHASE_STRIP = NO; DEAD_CODE_STRIPPING = NO; @@ -3348,6 +3403,10 @@ A7DC5CFE17F833F1006ADDF5 /* Coverage */ = { isa = XCBuildConfiguration; buildSettings = { + ARCHS = ( + "$(ARCHS_STANDARD)", + armv7s, + ); CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_SUSPICIOUS_IMPLICIT_CONVERSION = YES; COPY_PHASE_STRIP = NO; @@ -3409,6 +3468,10 @@ A7DC5D0217F833F1006ADDF5 /* Coverage */ = { isa = XCBuildConfiguration; buildSettings = { + ARCHS = ( + "$(ARCHS_STANDARD)", + armv7s, + ); COPY_PHASE_STRIP = NO; DEAD_CODE_STRIPPING = NO; DSTROOT = /tmp/DTCoreText.dst; @@ -3464,6 +3527,10 @@ A7F7EFCB1573603100F5A4D0 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + ARCHS = ( + "$(ARCHS_STANDARD)", + armv7s, + ); COPY_PHASE_STRIP = NO; DEAD_CODE_STRIPPING = NO; DSTROOT = /tmp/DTCoreText.dst; @@ -3487,6 +3554,10 @@ A7F7EFCC1573603100F5A4D0 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + ARCHS = ( + "$(ARCHS_STANDARD)", + armv7s, + ); COPY_PHASE_STRIP = NO; DEAD_CODE_STRIPPING = NO; DSTROOT = /tmp/DTCoreText.dst; diff --git a/Demo/Resources/CurrentTest.html b/Demo/Resources/CurrentTest.html index 3843a58a6..a78f1f8d2 100644 --- a/Demo/Resources/CurrentTest.html +++ b/Demo/Resources/CurrentTest.html @@ -1 +1,16 @@ -

BOX1

BOX2

END

+ +

+Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. +

+ +

+Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. +

+ +

+Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. +

+ +

+Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. +

\ No newline at end of file diff --git a/Demo/Source/DemoAboutViewController.xib b/Demo/Source/DemoAboutViewController.xib index 5745c02bb..3dea647a7 100644 --- a/Demo/Source/DemoAboutViewController.xib +++ b/Demo/Source/DemoAboutViewController.xib @@ -1,14 +1,14 @@ - 1552 - 12C3006 - 3084 - 1187.34 - 625.00 + 2048 + 14A388a + 6245 + 1343.14 + 755.00 com.apple.InterfaceBuilder.IBCocoaTouchPlugin - 2083 + 6238 IBProxyObject @@ -31,7 +31,7 @@ IBCocoaTouchFramework - + 274 @@ -39,7 +39,6 @@ 274 {320, 548} - _NS:9 3 @@ -52,8 +51,6 @@ {{0, 20}, {320, 548}} - - 3 @@ -63,6 +60,8 @@ IBUIScreenMetrics + IBCocoaTouchFramework + iPhone 4-inch YES @@ -74,15 +73,13 @@ {568, 320} - IBCocoaTouchFramework - Retina 4 Full Screen 2 IBCocoaTouchFramework - + view @@ -149,55 +146,15 @@ 9 - - - - DTAttributedTextView - UIScrollView - - UIView - id - - - - backgroundView - UIView - - - textDelegate - id - - - - IBProjectSource - ./Classes/DTAttributedTextView.h - - - - DemoAboutViewController - UIViewController - - attributedTextView - DTAttributedTextView - - - attributedTextView - - attributedTextView - DTAttributedTextView - - - - IBProjectSource - ./Classes/DemoAboutViewController.h - - - - + 0 IBCocoaTouchFramework + NO + + com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3 + + YES 3 - 2083 diff --git a/Demo/Source/DemoTextViewController.m b/Demo/Source/DemoTextViewController.m index 0fa4415c7..398ff55be 100644 --- a/Demo/Source/DemoTextViewController.m +++ b/Demo/Source/DemoTextViewController.m @@ -44,6 +44,8 @@ @implementation DemoTextViewController // private NSURL *lastActionLink; NSMutableSet *mediaPlayers; + + BOOL _needsAdjustInsetsOnLayout; } @@ -70,7 +72,10 @@ - (id)init self.navigationItem.titleView = _segmentedControl; [self _updateToolbarForMode]; - + + _needsAdjustInsetsOnLayout = YES; + + self.automaticallyAdjustsScrollViewInsets = YES; } return self; } @@ -257,12 +262,23 @@ - (void)viewWillDisappear:(BOOL)animated; [super viewWillDisappear:animated]; } +- (BOOL)prefersStatusBarHidden +{ + // prevent hiding of status bar in landscape because this messes up the layout guide calc + return NO; +} + +- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration +{ + _needsAdjustInsetsOnLayout = YES; +} + // this is only called on >= iOS 5 - (void)viewDidLayoutSubviews { [super viewDidLayoutSubviews]; - if (![self respondsToSelector:@selector(topLayoutGuide)]) + if (![self respondsToSelector:@selector(topLayoutGuide)] || !_needsAdjustInsetsOnLayout) { return; } @@ -271,6 +287,8 @@ - (void)viewDidLayoutSubviews CGFloat topInset = [[self valueForKeyPath:@"topLayoutGuide.length"] floatValue]; CGFloat bottomInset = [[self valueForKeyPath:@"bottomLayoutGuide.length"] floatValue]; + NSLog(@"%f top", topInset); + UIEdgeInsets outerInsets = UIEdgeInsetsMake(topInset, 0, bottomInset, 0); UIEdgeInsets innerInsets = outerInsets; innerInsets.left += 10; @@ -300,6 +318,8 @@ - (void)viewDidLayoutSubviews _htmlView.contentInset = outerInsets; _htmlView.contentOffset = outerScrollOffset; _htmlView.scrollIndicatorInsets = outerInsets; + + _needsAdjustInsetsOnLayout = NO; } #pragma mark Private Methods diff --git a/Externals/DTFoundation b/Externals/DTFoundation index 3fe513d03..64c58c8e6 160000 --- a/Externals/DTFoundation +++ b/Externals/DTFoundation @@ -1 +1 @@ -Subproject commit 3fe513d03829b27b10b32a0cc740a3f2a0b4ebbd +Subproject commit 64c58c8e664b7242680cc3626beeff2038942589 diff --git a/Test/Resources/CSSCascading.plist b/Test/Resources/CSSCascading.plist new file mode 100644 index 000000000..c1eaa6a1e --- /dev/null +++ b/Test/Resources/CSSCascading.plist @@ -0,0 +1,8 @@ + + + + + SkipUnitTest + + + diff --git a/Test/Resources/NavTag.plist b/Test/Resources/NavTag.plist new file mode 100644 index 000000000..c1eaa6a1e --- /dev/null +++ b/Test/Resources/NavTag.plist @@ -0,0 +1,8 @@ + + + + + SkipUnitTest + + + diff --git a/Test/Resources/RetinaDataURL.html b/Test/Resources/RetinaDataURL.html new file mode 100644 index 000000000..4ebbbb800 --- /dev/null +++ b/Test/Resources/RetinaDataURL.html @@ -0,0 +1,1836 @@ + + +

+ + \ No newline at end of file diff --git a/Test/Source/DTHTMLAttributedStringBuilderTest.m b/Test/Source/DTHTMLAttributedStringBuilderTest.m index 32be58f49..04bd519f3 100644 --- a/Test/Source/DTHTMLAttributedStringBuilderTest.m +++ b/Test/Source/DTHTMLAttributedStringBuilderTest.m @@ -637,6 +637,22 @@ - (void)testHelveticaNeueLight XCTAssertEqualObjects(descriptor.fontName, @"HelveticaNeue-Italic", @"Font face should be 'HelveticaNeue-Italic'"); } +// issue 804: allow custom font name specification +- (void)testOverrideFontName +{ + NSAttributedString *attributedString = [self attributedStringFromHTMLString:@"

Bold

" options:nil]; + + CTFontRef font; + NSRange fontRange = [self _effectiveRangeOfFontAtIndex:0 inAttributedString:attributedString font:&font]; + + NSRange expectedRange = NSMakeRange(0, [attributedString length]); + XCTAssertTrue(NSEqualRanges(fontRange, expectedRange), @"Font should be entire length"); + + DTCoreTextFontDescriptor *descriptor = [DTCoreTextFontDescriptor fontDescriptorForCTFont:font]; + + XCTAssertEqualObjects(descriptor.fontName, @"Arial-BoldMT", @"Font should be 'Arial-BoldMT'"); +} + #pragma mark - Nested Lists - (void)testNestedListWithStyleNone @@ -1143,6 +1159,29 @@ - (void)testDoubleOutputOfAttachmentWithDisplayNone } } +// issue 816: Retina data URL would cause incorrect original size +- (void)testRetinaDataURL +{ + NSAttributedString *attributedString = [self attributedStringFromTestFileName:@"RetinaDataURL"]; + + XCTAssert([attributedString length] == 2, @"RetinaDataURL should be parsed as 2 characters"); + + NSRange effectiveRange; + DTImageTextAttachment *attachment = [attributedString attribute:NSAttachmentAttributeName atIndex:0 effectiveRange:&effectiveRange]; + + XCTAssertNotNil(attachment, @"There should be an attachment"); + XCTAssertTrue(NSEqualRanges(effectiveRange, NSMakeRange(0, 1)), @"Attachment should only be on first character"); + + CGSize targetSize = CGSizeMake(176, 68); + + XCTAssert([attachment isKindOfClass:[DTImageTextAttachment class]], @"Attachment should be image"); + XCTAssert(CGSizeEqualToSize(attachment.image.size, targetSize), @"Attachment has incorrect image size"); + XCTAssert(CGSizeEqualToSize(attachment.originalSize, targetSize), @"Attachment has incorrect original size"); + +#if TARGET_OS_IPHONE + XCTAssert(attachment.image.scale == 2, @"Attachment image should have scale 2"); +#endif +} #pragma mark - Parsing Options