Permalink
Browse files

Merge branch 'release-1.6.9'

  • Loading branch information...
odrobnik committed Nov 15, 2013
2 parents 0886d14 + 9f4fd69 commit eae013eb15d01ee7253ddd21d69666d920b7027f
Showing with 744 additions and 177 deletions.
  1. +10 −10 Core/Source/DTAttributedTextContentView.m
  2. +1 −2 Core/Source/DTCSSStylesheet.h
  3. +20 −16 Core/Source/DTCSSStylesheet.m
  4. +13 −2 Core/Source/DTCompatibility.h
  5. +14 −0 Core/Source/DTCoreTextConstants.h
  6. +8 −1 Core/Source/DTCoreTextConstants.m
  7. +33 −5 Core/Source/DTCoreTextFontDescriptor.m
  8. +3 −3 Core/Source/DTCoreTextFunctions.m
  9. +1 −1 Core/Source/DTCoreTextGlyphRun.m
  10. +4 −7 Core/Source/DTCoreTextLayoutFrame.h
  11. +38 −16 Core/Source/DTCoreTextLayoutFrame.m
  12. +2 −2 Core/Source/DTCoreTextLayoutLine.m
  13. +1 −1 Core/Source/DTCoreTextLayouter.m
  14. +5 −5 Core/Source/DTCoreTextParagraphStyle.m
  15. +1 −0 Core/Source/DTHTMLAttributedStringBuilder.h
  16. +8 −2 Core/Source/DTHTMLAttributedStringBuilder.m
  17. +9 −9 Core/Source/DTHTMLElement.m
  18. +2 −2 Core/Source/DTHTMLParserNode.m
  19. +1 −1 Core/Source/DTHTMLParserTextNode.m
  20. +5 −5 Core/Source/DTHTMLWriter.m
  21. +1 −1 Core/Source/DTImageTextAttachment.m
  22. +2 −2 Core/Source/DTLazyImageView.m
  23. +1 −1 Core/Source/DTLinkButton.m
  24. +2 −2 Core/Source/DTTextAttachment.h
  25. +4 −4 Core/Source/DTTextAttachment.m
  26. +1 −1 Core/Source/DTTextHTMLElement.m
  27. +2 −2 Core/Source/NSAttributedString+DTCoreText.h
  28. +2 −2 Core/Source/NSAttributedString+DTCoreText.m
  29. +2 −2 Core/Source/NSMutableAttributedString+HTML.m
  30. +13 −13 Core/Source/NSScanner+HTML.m
  31. +2 −2 Core/Source/NSString+CSS.m
  32. +5 −4 Core/Source/NSString+HTML.m
  33. +1 −1 Core/Source/NSString+Paragraphs.m
  34. +4 −4 DTCoreText.podspec
  35. +256 −6 DTCoreText.xcodeproj/project.pbxproj
  36. BIN Default-568h@2x.png
  37. BIN Demo/Resources/Oliver.jpg
  38. BIN Demo/Resources/Oliver@2x.jpg
  39. +1 −1 Demo/Source/DemoSnippetsViewController.m
  40. +3 −3 Demo/Source/DemoTextViewController.m
  41. +22 −0 Documentation/Programming Guide-template.markdown
  42. +1 −1 Externals/DTFoundation
  43. +38 −0 Test/BundleLoaderDummy/BundleLoaderDummy-Info.plist
  44. +18 −0 Test/BundleLoaderDummy/main.m
  45. +2 −2 Test/Source/DTCSSStylesheetTest.m
  46. +64 −0 Test/Source/DTCoreTextFontDescriptorTest.m
  47. +51 −0 Test/Source/DTCoreTextLayoutFrameTest.m
  48. +44 −6 Test/Source/DTHTMLAttributedStringBuilderTest.m
  49. +1 −1 Test/Source/NSAttributedStringHTMLTest.m
  50. +22 −26 Test/Source/NSDictionaryDTCoreText.m
@@ -277,10 +277,10 @@ - (void)layoutSubviewsInRect:(CGRect)rect
}
// round frame
- frameForSubview.origin.x = floorf(frameForSubview.origin.x);
- frameForSubview.origin.y = ceilf(frameForSubview.origin.y);
- frameForSubview.size.width = roundf(frameForSubview.size.width);
- frameForSubview.size.height = roundf(frameForSubview.size.height);
+ frameForSubview.origin.x = floor(frameForSubview.origin.x);
+ frameForSubview.origin.y = ceil(frameForSubview.origin.y);
+ frameForSubview.size.width = round(frameForSubview.size.width);
+ frameForSubview.size.height = round(frameForSubview.size.height);
if (CGRectGetMinY(frameForSubview)> CGRectGetMaxY(rect) || CGRectGetMaxY(frameForSubview) < CGRectGetMinY(rect))
{
@@ -350,8 +350,8 @@ - (void)layoutSubviewsInRect:(CGRect)rect
// make sure that the frame height is no less than the line height for hyperlinks
if (frameForSubview.size.height < oneLine.frame.size.height)
{
- frameForSubview.origin.y = truncf(oneLine.frame.origin.y);
- frameForSubview.size.height = ceilf(oneLine.frame.size.height);
+ frameForSubview.origin.y = trunc(oneLine.frame.origin.y);
+ frameForSubview.size.height = ceil(oneLine.frame.size.height);
}
if (existingLinkView)
@@ -366,8 +366,8 @@ - (void)layoutSubviewsInRect:(CGRect)rect
// make sure that the frame height is no less than the line height for hyperlinks
if (frameForSubview.size.height < oneLine.frame.size.height)
{
- frameForSubview.origin.y = truncf(oneLine.frame.origin.y);
- frameForSubview.size.height = ceilf(oneLine.frame.size.height);
+ frameForSubview.origin.y = trunc(oneLine.frame.origin.y);
+ frameForSubview.size.height = ceil(oneLine.frame.size.height);
}
if (_delegateFlags.delegateSupportsCustomViewsForLinks)
@@ -603,7 +603,7 @@ - (CGRect)_frameForLayoutFrameConstraintedToWidth:(CGFloat)constrainWidth
}
else
{
- rect.size.height = CGFLOAT_OPEN_HEIGHT; // necessary height set as soon as we know it.
+ rect.size.height = CGFLOAT_HEIGHT_UNKNOWN; // necessary height set as soon as we know it.
}
return rect;
@@ -813,7 +813,7 @@ - (DTCoreTextLayoutFrame *)layoutFrame
}
else
{
- rect.size.height = CGFLOAT_OPEN_HEIGHT; // necessary height set as soon as we know it.
+ rect.size.height = CGFLOAT_HEIGHT_UNKNOWN; // necessary height set as soon as we know it.
}
_layoutFrame = [theLayouter layoutFrameWithRect:rect range:NSMakeRange(0, 0)];
@@ -70,8 +70,7 @@
@param matchedSelectors The CSS selectors that caused a match
@returns The merged style dictionary containing only styles which selector matches the element
*/
-- (NSDictionary *)mergedStyleDictionaryForElement:(DTHTMLElement *)element matchedSelectors:(NSSet **)matchedSelectors;
-
+- (NSDictionary *)mergedStyleDictionaryForElement:(DTHTMLElement *)element matchedSelectors:(NSSet **)matchedSelectors ignoreInlineStyle:(BOOL)ignoreInlineStyle;
/**
Returns a dictionary of the styles of the receiver
@@ -442,7 +442,7 @@ - (void)_addStyleRule:(NSString *)rule withSelector:(NSString*)selectors
{
NSMutableArray *newVal;
- for (NSUInteger i = 0; i < [value count]; ++i)
+ for (NSUInteger i = 0; i < [(NSArray*)value count]; ++i)
{
NSString *s = [value objectAtIndex:i];
@@ -464,7 +464,8 @@ - (void)_addStyleRule:(NSString *)rule withSelector:(NSString*)selectors
}
}
- newVal[i] = s;
+ // replace the value that had !important with a version without it
+ [newVal replaceObjectAtIndex:i withObject:s];
}
}
@@ -653,13 +654,13 @@ - (void)_addStyles:(NSDictionary *)styles withSelector:(NSString *)selector {
if (![_orderedSelectors containsObject:selector])
{
[_orderedSelectors addObject:selector];
- _orderedSelectorWeights[selector] = @([self _weightForSelector:selector]);
+ [_orderedSelectorWeights setObject:@([self _weightForSelector:selector]) forKey:selector];
}
}
#pragma mark Accessing Style Information
-- (NSDictionary *)mergedStyleDictionaryForElement:(DTHTMLElement *)element matchedSelectors:(NSSet **)matchedSelectors
+- (NSDictionary *)mergedStyleDictionaryForElement:(DTHTMLElement *)element matchedSelectors:(NSSet **)matchedSelectors ignoreInlineStyle:(BOOL)ignoreInlineStyle
{
// We are going to combine all the relevant styles for this tag.
// (Note that when styles are applied, the later styles take precedence,
@@ -683,8 +684,8 @@ - (NSDictionary *)mergedStyleDictionaryForElement:(DTHTMLElement *)element match
NSMutableArray *matchingCascadingSelectors = [self matchingComplexCascadingSelectorsForElement:element];
[matchingCascadingSelectors sortUsingComparator:^NSComparisonResult(NSString *selector1, NSString *selector2)
{
- NSInteger weightForSelector1 = [_orderedSelectorWeights[selector1] integerValue];
- NSInteger weightForSelector2 = [_orderedSelectorWeights[selector2] integerValue];
+ NSInteger weightForSelector1 = [[_orderedSelectorWeights objectForKey:selector1] integerValue];
+ NSInteger weightForSelector2 = [[_orderedSelectorWeights objectForKey:selector2] integerValue];
if (weightForSelector1 == weightForSelector2)
{
@@ -752,17 +753,20 @@ - (NSDictionary *)mergedStyleDictionaryForElement:(DTHTMLElement *)element match
[tmpMatchedSelectors addObject:idRule];
}
- // Get tag's local style attribute
- NSString *styleString = [element.attributes objectForKey:@"style"];
-
- if ([styleString length])
+ if (!ignoreInlineStyle)
{
- NSMutableDictionary *localStyles = [[styleString dictionaryOfCSSStyles] mutableCopy];
-
- // need to uncompress because otherwise we might get shorthands and non-shorthands together
- [self _uncompressShorthands:localStyles];
+ // Get tag's local style attribute
+ NSString *styleString = [element.attributes objectForKey:@"style"];
- [tmpDict addEntriesFromDictionary:localStyles];
+ if ([styleString length])
+ {
+ NSMutableDictionary *localStyles = [[styleString dictionaryOfCSSStyles] mutableCopy];
+
+ // need to uncompress because otherwise we might get shorthands and non-shorthands together
+ [self _uncompressShorthands:localStyles];
+
+ [tmpDict addEntriesFromDictionary:localStyles];
+ }
}
if ([tmpDict count])
@@ -811,7 +815,7 @@ - (NSMutableArray *)matchingComplexCascadingSelectorsForElement:(DTHTMLElement *
// Aside: Manual for loop here is faster than for in with reverseObjectEnumerator
for (NSUInteger j = selectorParts.count; j-- > 0;)
{
- NSString *selectorPart = selectorParts[j];
+ NSString *selectorPart = [selectorParts objectAtIndex:j];
BOOL matched = NO;
if (selectorPart.length)
@@ -40,7 +40,7 @@
#endif
// constant for checking for iOS 6
- #define DTNSFoundationVersionNumber_iOS_6_0 993.00
+ #define DTNSFoundationVersionNumber_iOS_6_0 992.00
// constant for checking for iOS 7
#define DTNSFoundationVersionNumber_iOS_7_0 1047.20
@@ -58,6 +58,12 @@
return NO;
}
+#if TARGET_CPU_ARM64
+ #define DTNSNumberFromCGFloat(x) [NSNumber numberWithDouble:x]
+#else
+ #define DTNSNumberFromCGFloat(x) [NSNumber numberWithFloat:x]
+#endif
+
#endif
@@ -108,4 +114,9 @@
{
return YES;
}
-#endif
+
+ #define DTNSNumberFromCGFloat(x) [NSNumber numberWithDouble:x]
+#endif
+
+// this enables generic ceil, floor, abs, round functions that work for 64 and 32 bit
+#include <tgmath.h>
@@ -53,6 +53,8 @@ extern NSString * const DTDefaultStyleSheet;
extern NSString * const DTUseiOS6Attributes;
extern NSString * const DTWillFlushBlockCallBack;
extern NSString * const DTProcessCustomHTMLAttributes;
+extern NSString * const DTIgnoreInlineStylesOption;
+
// attributed string attribute constants
@@ -79,6 +81,9 @@ extern NSString * const DTListPrefixField;
// iOS 6 compatibility
extern BOOL ___useiOS6Attributes;
+// exceptions
+extern NSString * const DTCoreTextFontDescriptorException;
+
// macros
#define IS_WHITESPACE(_c) (_c == ' ' || _c == '\t' || _c == 0xA || _c == 0xB || _c == 0xC || _c == 0xD || _c == 0x85)
@@ -175,3 +180,12 @@ typedef NS_ENUM(NSUInteger, DTCoreTextLayoutFrameLinePositioningOptions)
*/
DTCoreTextLayoutFrameLinePositioningOptionAlgorithmLegacy = 2
};
+
+// layouting
+
+// the value to use if the width is unknown
+#define CGFLOAT_WIDTH_UNKNOWN 16777215.0f
+
+// the value to use if the height is unknown
+#define CGFLOAT_HEIGHT_UNKNOWN 16777215.0f
+
@@ -26,6 +26,7 @@
NSString * const DTUseiOS6Attributes = @"DTUseiOS6Attributes";
NSString * const DTWillFlushBlockCallBack = @"DTWillFlushBlockCallBack";
NSString * const DTProcessCustomHTMLAttributes = @"DTProcessCustomHTMLAttributes";
+NSString * const DTIgnoreInlineStylesOption = @"DTIgnoreInlineStyles";
// attributed string attribute constants
@@ -50,4 +51,10 @@
// iOS 6 compatibility
-BOOL ___useiOS6Attributes = NO; // this gets set globally by DTHTMLAttributedStringBuilder
+BOOL ___useiOS6Attributes = NO; // this gets set globally by DTHTMLAttributedStringBuilder
+
+
+// exceptions
+
+NSString * const DTCoreTextFontDescriptorException = @"DTCoreTextFontDescriptorException";
+
@@ -9,6 +9,7 @@
#import "DTCoreTextFontDescriptor.h"
#import "DTCoreTextFontCollection.h"
#import "DTCompatibility.h"
+#import "DTCoreTextConstants.h"
static NSCache *_fontCache = nil;
static NSMutableDictionary *_fontOverrides = nil;
@@ -54,7 +55,7 @@ + (void)initialize
_fontOverrides = [[NSMutableDictionary alloc] init];
// then - if it exists - we override from the plist
- NSString *path = [[NSBundle mainBundle] pathForResource:@"DTCoreTextFontOverrides" ofType:@"plist"];
+ NSString *path = [[NSBundle bundleForClass:self] pathForResource:@"DTCoreTextFontOverrides" ofType:@"plist"];
NSArray *fileArray = [NSArray arrayWithContentsOfFile:path];
for (NSDictionary *oneOverride in fileArray)
@@ -152,8 +153,36 @@ + (void)_createDictionaryOfAllAvailableFontOverrideNamesWithCompletion:(void(^)(
+ (void)setFallbackFontFamily:(NSString *)fontFamily
{
- NSParameterAssert(fontFamily);
+ if (!fontFamily)
+ {
+ [NSException raise:DTCoreTextFontDescriptorException format:@"Fallback Font Family cannot be nil"];
+ }
+
+ // make sure that only valid font families can be registered
+ NSDictionary *attributes = [NSDictionary dictionaryWithObject:fontFamily forKey:(id)kCTFontFamilyNameAttribute];
+ CTFontDescriptorRef fontDesc = CTFontDescriptorCreateWithAttributes((__bridge CFDictionaryRef)(attributes));
+ CTFontRef font = CTFontCreateWithFontDescriptor(fontDesc, 12, NULL);
+
+ BOOL isValid = NO;
+ if (font)
+ {
+ NSString *usedFontFamily = CFBridgingRelease(CTFontCopyFamilyName(font));
+
+ if ([usedFontFamily isEqualToString:fontFamily])
+ {
+ isValid = YES;
+ }
+
+ CFRelease(fontDesc);
+ CFRelease(font);
+ }
+
+ if (!isValid)
+ {
+ [NSException raise:DTCoreTextFontDescriptorException format:@"Fallback Font Family '%@' not registered on the system", fontFamily];
+ }
+
_fallbackFontFamily = [fontFamily copy];
}
@@ -386,8 +415,7 @@ - (NSDictionary *)fontAttributes
}
// we need size because that's what makes a font unique, for searching it's ignored anyway
- [tmpDict setObject:[NSNumber numberWithFloat:_pointSize] forKey:(id)kCTFontSizeAttribute];
-
+ [tmpDict setObject:DTNSNumberFromCGFloat(_pointSize) forKey:(id)kCTFontSizeAttribute];
if (_smallCapsFeature)
{
@@ -964,7 +992,7 @@ - (BOOL)UIoptimizedTrait
- (void)setPointSize:(CGFloat)pointSize
{
- _pointSize = roundf(pointSize);
+ _pointSize = round(pointSize);
}
@synthesize fontFamily = _fontFamily;
@@ -47,17 +47,17 @@ CTLineTruncationType DTCTLineTruncationTypeFromNSLineBreakMode(NSLineBreakMode l
CGFloat DTRoundWithContentScale(CGFloat value, CGFloat contentScale)
{
- return roundf(value*contentScale)/contentScale;
+ return round(value*contentScale)/contentScale;
}
CGFloat DTCeilWithContentScale(CGFloat value, CGFloat contentScale)
{
- return ceilf(value*contentScale)/contentScale;
+ return ceil(value*contentScale)/contentScale;
}
CGFloat DTFloorWithContentScale(CGFloat value, CGFloat contentScale)
{
- return floorf(value*contentScale)/contentScale;
+ return floor(value*contentScale)/contentScale;
}
#pragma mark - Alignment Functions
@@ -86,7 +86,7 @@ - (void)dealloc
- (NSString *)description
{
- return [NSString stringWithFormat:@"<%@ glyphs=%d %@>", [self class], [self numberOfGlyphs], NSStringFromCGRect(_frame)];
+ return [NSString stringWithFormat:@"<%@ glyphs=%ld %@>", [self class], (long)[self numberOfGlyphs], NSStringFromCGRect(_frame)];
}
#endif
@@ -19,10 +19,7 @@
@class DTTextBlock;
-// the value to use if the height is unknown
-#define CGFLOAT_OPEN_HEIGHT 16777215.0f
-
-typedef void (^DTCoreTextLayoutFrameTextBlockHandler)(DTTextBlock *textBlock, CGRect frame, CGContextRef context, BOOL *shouldDrawDefaultBackground);
+typedef void (^DTCoreTextLayoutFrameTextBlockHandler)(DTTextBlock *textBlock, CGRect frame, CGContextRef context, BOOL *shouldDrawDefaultBackground);
/**
The drawing options for DTCoreTextLayoutFrame
@@ -56,7 +53,7 @@ typedef NS_ENUM(NSUInteger, DTCoreTextLayoutFrameDrawingOptions)
/**
This class represents a single frame of text and basically wraps CTFrame. It provides an array of text lines that fit in the given rectangle.
- Both styles of layouting are supported: open ended (suitable for scroll views) and limited to a given rectangle. To use the open-ended style specify `CGFLOAT_OPEN_HEIGHT` for the <frame> height when creating a layout frame.
+ Both styles of layouting are supported: open ended (suitable for scroll views) and limited to a given rectangle. To use the open-ended style specify `CGFLOAT_HEIGHT_UNKNOWN` for the <frame> height when creating a layout frame.
The array of lines is built lazily the first time it is accessed or - for open-ended frames - when the frame property is being queried.
*/
@@ -80,7 +77,7 @@ typedef NS_ENUM(NSUInteger, DTCoreTextLayoutFrameDrawingOptions)
/**
Creates a Layout Frame with the given frame using the attributed string loaded into the layouter.
- @param frame The rectangle specifying origin and size of available for text. Specify `CGFLOAT_OPEN_HEIGHT` to not limit the height.
+ @param frame The rectangle specifying origin and size of available for text. Specify `CGFLOAT_WIDTH_UNKNOWN` to not limit the width. Specify `CGFLOAT_HEIGHT_UNKNOWN` to not limit the height.
@param layouter A reference to the layouter for this text box.
*/
- (id)initWithFrame:(CGRect)frame layouter:(DTCoreTextLayouter *)layouter;
@@ -89,7 +86,7 @@ typedef NS_ENUM(NSUInteger, DTCoreTextLayoutFrameDrawingOptions)
/**
Creates a Layout Frame with the given frame using the attributed string loaded into the layouter.
- @param frame The rectangle specifying origin and size of available for text. Specify `CGFLOAT_OPEN_HEIGHT` to not limit the height.
+ @param frame The rectangle specifying origin and size of available for text. Specify `CGFLOAT_WIDTH_UNKNOWN` to not limit the width. Specify `CGFLOAT_HEIGHT_UNKNOWN` to not limit the height.
@param layouter A reference to the layouter for the receiver. Note: The layouter owns the attributed string.
@param range The range within the attributed string to layout into the receiver.
*/
Oops, something went wrong.

0 comments on commit eae013e

Please sign in to comment.