(Feedback) Underlining of links look a bit big on retina #351

holgersindbaek opened this Issue Mar 17, 2013 · 20 comments

2 participants


Think you mentioned it earlier, so just wanted to give a screenshot:


IMO, it's a bit too thick for an underlining. It almost makes the serifs on the font disappear.


It wasn't so much the width I was talking about, as it was the thickness of the line. Maybe that was what you meant :-).


Please leave issues that are still under investigation open. You find the code for drawing the underline in the new drawDecorationInContext inside DTCoreTextGlyphRun.

@odrobnik odrobnik reopened this Mar 17, 2013

@holgersindbaek Are you working on this?


@holgersindbaek So you don't think we should round it to be an exact number of Retina pixels?


The visual thickness probable comes from the width being not an even multiple of 0.5. Those increments are full Retina pixels. Now if it is 0.7 then this would fill one pixel plus "half of another" which causes antialiasing of a shade of gray and visually makes it almost twice as bit.

The previous implementation was shifting the underline origin to be a half pixel, so that a line of 1 px width would also only touch a single row of pixels. For Retina that would mean that we have to shift it to an even multiple of 0.25.

Similar things are true all throughout DTCoreText. In many places I am rounding, truncating or ceiling to full integer values.

When I have some time I'll look at this... unless you beat me to it.

@odrobnik odrobnik added a commit that referenced this issue Mar 20, 2013
@odrobnik odrobnik Improved underline and strike-out drawing.
Modified to avoid anti-aliasing by rounding pixels taking the context scale into account.

related to #351

@holgersindbaek Please inspect the latest update I made.

I tried to get as close as possible to the CoreText output. For this purpose I used Pixelmator and painted the text with the same font and size over it. The underline width now always matches, in rare cases the underline is off by 1 Retina pixel. I suspect that this is because Pixelmator rounds differently than I do. But I think that this is good enough.


Underlining seems more strict now (no half pixels), but it seems like it's drawing it twice (including the text), which it didn't do before:


I'm using the drawing code from the example:

- (UIView *)attributedTextContentView:(DTAttributedTextContentView *)attributedTextContentView viewForAttributedString:(NSAttributedString *)string frame:(CGRect)frame{
    // 1. Get links attributes
    NSDictionary *attributes = [string attributesAtIndex:0 effectiveRange:NULL];

    // 2. Get the url and identifier from the attributes
    NSURL *URL = [attributes objectForKey:DTLinkAttribute];
    NSString *identifier = [attributes objectForKey:DTGUIDAttribute];

    // 3. Create the button
    DTLinkButton *button = [[DTLinkButton alloc] initWithFrame:frame];
    button.URL = URL;
    button.minimumHitSize = CGSizeMake(25, 25); // adjusts it's bounds so that button is always large enough
    button.GUID = identifier;
    button.attributedString = string;

    // 4. Make a version with different text color
    NSMutableAttributedString *highlightedString = [string mutableCopy];
    NSRange range = NSMakeRange(0, highlightedString.length);
    NSDictionary *highlightedAttributes = [NSDictionary dictionaryWithObjectsAndKeys: (__bridge id)global.activeLinkColor.CGColor, (id)kCTForegroundColorAttributeName, nil];
    [highlightedString addAttributes:highlightedAttributes range:range];

    // 5. Set the highlighted state of the button to the new string attribute
    button.highlightedAttributedString = highlightedString;

    // 6. Call method on press of button
    [button addTarget:self action:@selector(linkPushed:) forControlEvents:UIControlEventTouchUpInside];

    // 7. Return button
    return button;

Is that wrong?


In that case, the underlining looks very pixel precise (checking on retina). Beautiful.

The underlining is starting in a funny place though (see attachment).



Which drawing is that now? Check the inline drawing, that should be fine. The extra drawing in links I'll fix tomorrow


Damn... looking good. Looking forward to the link update.

Keep on the good work :-).


@holgersindbaek I just pushed my revamping work from today.

Now links are drawn by the same code that draws the inline text. Please note that there is a breaking change on DTLinkButton. See the DemoTextViewController for the new implementation for showing different color normal and highlighted link text (via UIImages)

I'm now going to work on implementing a method to also set the highlight color via CSS.

If you find this to be working, please close the issue.

@odrobnik odrobnik was assigned Mar 21, 2013

I'm assuming that this is resolved by the link re-implementation.

@odrobnik odrobnik closed this Mar 23, 2013

@Cocoanetics I can't seem to compile, because I'm using this undeclared identifier in the drawing code:


I've imported DTCoreTextLayoutFrame.h, but it doesn't seem to be the right one. Which one should I import?


@Cocoanetics I didn't pull the pod correctly. Everything is working and looking beautiful. Job well done!

@yifan yifan added a commit to yifan/DTCoreText that referenced this issue Mar 25, 2013
@odrobnik odrobnik Improved underline and strike-out drawing.
Modified to avoid anti-aliasing by rounding pixels taking the context scale into account.

related to #351
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment