Note that there are some explanatory texts on larger screens.

plurals
  1. POCore Text With Asymmetric Shape on iOS
    primarykey
    data
    text
    <p>I want to write text in a path that can take up any shape. Right now I can draw flipped text in it:</p> <pre><code>NSArray *coordinates = ...; CGMutablePathRef pathRef = [self objectPathGivenCoordinates:coordinates]; ... // Draw the shapes // Now draw the text CGContextSetTextMatrix(context, CGAffineTransformIdentity); NSAttributedString* attString = [[NSAttributedString alloc] initWithString:@"0,1,2..."]; CTFramesetterRef frameSetter = CTFramesetterCreateWithAttributedString((__bridge CFAttributedStringRef)attString); CTFrameRef frame = CTFramesetterCreateFrame(frameSetter, CFRangeMake(0, [attString length]), pathRef, NULL); CTFrameDraw(frame, context); </code></pre> <p>That produces this:</p> <p><img src="https://i.stack.imgur.com/ny3SK.png" alt="Flipped text in Asymmetric Shape"></p> <p>I understand that iOS has a flipped coordinate system. Most solutions add these two lines before drawing:</p> <pre><code>CGContextTranslateCTM(context, 0, rect.size.height); CGContextScaleCTM(context, 1.0, -1.0); </code></pre> <p>But that produces this:</p> <p><img src="https://i.stack.imgur.com/up7UW.png" alt="Text is now written left-right right-side-up but out of path bounds"></p> <p>So why doesn't this technique work? In every example I've seen, this technique is used when text is rendered in something symmetric, or with clipping, or on OS X. If we're drawing text in a symmetric shape, our calls to <code>CGContextTranslateCTM()</code> and <code>CGContextScaleCTM()</code> make sense. A call to <code>CGContextTranslateCTM(context, 0, rect.size.height)</code>, moves the origin of the first letter to the top. A call to <code>CGContextScaleCTM(context, 1, -1)</code> reverses the direction of Y. If we reverse the direction of Y on a symmetric shape, it doesn't change. Sadly, my shapes aren't symmetric.</p> <p>Here is what I've considered but abandoned</p> <ul> <li>Draw shapes and numbers on the same scale (both upside-down), then flip the <code>UIImageView</code> behind it somehow (1)</li> <li>Don't make calls to change the scale or translate the CTM. Flip the text matrix with <code>CGContextSetTextMatrix()</code> so that text is drawn from left to right, bottom up, and is right side up. Determine how many extra characters are left in the shape after a string for the shape is determined. Reverse the words (now it will draw top to bottom, right to left, right side up). Add spaces for every extra character. Now for each <code>CTLine</code>, somehow reverse the words again (now it will draw top to bottom, left to right, right side up) (2)</li> </ul> <p>Why I abandoned them</p> <p>(1) I can't flip my images. They always need to be right side up</p> <p>(2) This may be overkill for a simple solution someone else knows</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload