Reputation: 11749
After spending quite a bit of time to display "Thai Phonetic YK" fonts in an iPhone app. I finally got things sorted out and working.
Though it is functionning there is still a complaint (warning) from the compiler about one line of code in the (void)drawRect: method of my class performing the display.
CGContextShowGlyphsAtPoint(context, 20, 50, textToPrint, textLength);
The compiler tells me that this code is DEPRECATED. My question is “How am I supposed to change it?”. Even though I searched the net for an answer, I didn’t find any thing clear. The documentation says something like “Use Core Text instead” which is far too vague to be considered as an answer.
Upvotes: 3
Views: 952
Reputation: 31745
Core Graphics:
void CGContextShowGlyphsAtPoint (
CGContextRef context,
CGFloat x,
CGFloat y,
const CGGlyph glyphs[],
size_t count
);
Core Text:
void CTFontDrawGlyphs (
CTFontRef font,
const CGGlyph glyphs[],
const CGPoint positions[],
size_t count,
CGContextRef context
);
The Core Text version requires a CTFontRef (in the Core Graphics version, the font is expected to be set in the context).
You can obtain a CTFontRef from a UIFont:
CTFontRef ctFont = CTFontCreateWithName( (__bridge CFStringRef)uiFont.fontName, uiFont.pointSize, NULL);
The CT version also requires an array of points, one for each glyph. Assuming you were drawing a single glyph with the CG code, you could create the array like this:
CGPoint point = CGPointMake(x, y);
const CGPoint* positions = &point;
This change does mean you will need a point position for each glyph. In my case the extra work was minimal: I was advancing the typesetter one character at a time (for curved text) so I had to do this calculation anyway.
You may be able to typeset one text run at a time with CTRun:
void CTRunDraw (
CTRunRef run,
CGContextRef context,
CFRange range );
That could save you the trouble of iterating over each glyph. You could use it something like this...
CGContextSetTextMatrix(context, CGAffineTransformIdentity);
CTLineRef line = CTLineCreateWithAttributedString(
(__bridge CFTypeRef)self.attributedString);
CFArrayRef runs = CTLineGetGlyphRuns(line);
CFIndex runCount = CFArrayGetCount(runs);
for (CFIndex runIndex = 0; runIndex < runCount; ++runIndex) {
CTRunRef run = CFArrayGetValueAtIndex(runs, runIndex);
[self adjustContextForRun:run];
CTRunDraw (run, context, 0)
}
(thats just a sketch, implementation will depend on your needs, and i haven't tested the code)
adjustContextForRun
would be responsible for setting things like font and initial draw position for the run.
Each CTRun represents a subrange of an attributed string where all of the attributes are the same. IF you don't vary attributes over a line, you can abstract this further:
CTLineDraw(line, context);
I don't know if that level of abstraction would work in your case (i am only used to working with Latin fonts), but its worth knowing it's there, saves a lot of lower-level trouble.
You can set the initial drawing position for the text with this:
void CGContextSetTextPosition (
CGContextRef c,
CGFloat x,
CGFloat y );
Upvotes: 3