Re: Pixel-perfect migration from ATSUI to Core Text
Re: Pixel-perfect migration from ATSUI to Core Text
- Subject: Re: Pixel-perfect migration from ATSUI to Core Text
- From: Andreas Falkenhahn <email@hidden>
- Date: Wed, 31 Aug 2016 16:52:33 +0200
On 31.08.2016 at 04:01 Ken Thomases wrote:
> On Aug 30, 2016, at 8:47 AM, Andreas Falkenhahn <email@hidden> wrote:
>>> That said, when drawing strings, there are the functions
>>> CGContextSetShouldSubpixelPositionFonts() and
>>> CGContextSetAllowsFontSubpixelPositioning(). Those can be used to
>>> turn off sub-pixel positioning of glyphs. It may be that ATSUI
>>> wasn't capable of that and so turning it off gets you the same positioning as ATSUI.
>>> There doesn't seem to be a direct way to ask Core Text for the
>>> measurements corresponding to that drawing mode. So, you may need
>>> to ask your CTLine for its CTRuns and then ask the CTRun for the
>>> individual glyph advances.
>> Hmm, I don't understand. The only CTRun APIs that take a CGContextRef are CTRunGetImageBounds()
>> and CTRunDraw(). I'd have to use CTRunGetAdvances(), though, but this function doesn't accept
>> a CGContextRef so I don't see how I should implement your suggestions...
> I mentioned CGContext only to illustrate the point that there are
> two text-rendering modes, one that allows for sub-pixel glyph
> position (and thus advances) and one which doesn't. The other part
> of what I said has nothing to do with CGContext.
> I would have hoped there would be APIs built into Core Text that
> would measure the text as it would be rendered when sub-pixel glyph
> positioning isn't allowed, but there don't seem to be. So, I
> suggested a way to compute it manually.
But I still don't understand how computing glyph positioning manually
should work around the fact that there are no APIs that measure the text
like ATSUI. I mean, internally, CTLineGetOffsetForStringIndex() probably
does exactly that, it returns the positioning obtained from CTRunGetAdvances().
Anyway, I've tried your suggestion and used CTRunGetAdvances() to see
if it returns anything different than CTLineGetOffsetForStringIndex() but
apparently it doesn't. Here's my code:
CTFontRef font = CTFontCreateWithName(CFSTR("Arial"), 39, NULL);
CFStringRef keys[] = {kCTFontAttributeName};
CFTypeRef values[] = {font};
CFDictionaryRef attr = CFDictionaryCreate(NULL, (const void **) &keys, (const void **) &values, 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
CFAttributedStringRef attrString = CFAttributedStringCreate(NULL, CFSTR("W"), attr);
CTLineRef line = CTLineCreateWithAttributedString(attrString);
CGFloat cursor_advance = CTLineGetOffsetForStringIndex(line, 1, NULL);
CFArrayRef runs = CTLineGetGlyphRuns(line);
CTRunRef run = (CTRunRef) CFArrayGetValueAtIndex(runs, 0);
CGSize buffer[16];
CTRunGetAdvances(run, CFRangeMake(0, 0), buffer);
printf("CORE TEXT: %.14g --- %.14g\n", cursor_advance, buffer[0].width);
CFRelease(line);
CFRelease(attrString);
CFRelease(attr);
CFRelease(font);
What I get is this:
CORE TEXT: 36.81005859375 --- 36.81005859375
i.e. it's both exactly the same. But ATSUI returns 38! So even using ceil() or round()
doesn't help here because it would still be 1 pixel off from what ATSUI returned...
Any other ideas or should I better ask on the Core Text mailing list?
--
Best regards,
Andreas Falkenhahn mailto:email@hidden
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden