iosunicodensstringwkinterfacelabel

NSString sizing does not account for Greek breathing marks


I've got an app that displays Greek text. I use the Cardo font for good display. In working on an AppleWatch extension and app, it was pointed out to me that some of the special characters are being cut off. This is how some example text should look (screenshot from an iPhone simulator):

Good Greek display on phone

Here is the same text on the Watch simulator:

Bad Greek display on watch

Note that the fancy accent character (to be specific, a breathing mark with a circumflex accent) on the second character of the first word is cut off. I tried setting the label's frame on the phone using some NSString measuring code like this:

UILabel *label = [[UILabel alloc]init];
label.font = [UIFont fontWithName:@"Cardo" size:16];
[self.view addSubview:label];
label.text = @"οὗτος ἦλθεν εἰς μαρτυρίαν ἵνα μαρτυρήσῃ περὶ τοῦ φωτός, ἵνα πάντες πιστεύσωσιν δι᾽ αὐτοῦ.";
label.numberOfLines = 0;
label.lineBreakMode = NSLineBreakByWordWrapping;
NSMutableParagraphStyle *style = [[NSMutableParagraphStyle alloc]init];
style.lineBreakMode = NSLineBreakByWordWrapping;

CGRect rect = [label.text boundingRectWithSize:self.view.bounds.size
  options:NSStringDrawingUsesLineFragmentOrigin
  attributes:@{NSFontAttributeName: label.font,
     NSParagraphStyleAttributeName: style} context:nil];
label.frame = CGRectMake(5, 100, ceilf(rect.size.width), ceilf(rect.size.height));
label.layer.borderWidth = 1; //for clarity
label.layer.borderColor = [UIColor blackColor].CGColor;

The result looks like this (the border is drawn for clarity's sake):

Bad Greek display on phone

Interestingly, if I use the system font instead of Cardo, the extra symbols display correctly:

Greek in Helvetica works, but is ugly

So, my question: What causes the NSString sizing to cut off the extra marks? Is there some option I can pass to the sizing method to correct this? Or better yet, is there some option I can set on the WKInterfaceLabel in the Watch app to get it to render correctly?


Solution

  • I suspect the problem is in the font itself, with the ascenders being set too tightly for proper display.

    I would first try setting the UILabel's text inset by making a subclass of UILabel and overriding drawTextInRect:

    - (void)drawTextInRect:(CGRect)rect {
    UIEdgeInsets insets = {5, 0, 0, 0};
    [super drawTextInRect:UIEdgeInsetsInsetRect(rect, insets)];
    }
    

    If you have tried increasing the text inset to accommodate the font and it has not worked, take a look at Custom installed font not displayed correctly in UILabel