CTFrameGetLineOrigins return frong Y coordinates

All x coordinates are correct, but all y coordinates are incorrect - always 3.40282e+38 . How to get correct y for each CTLine ?

CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString((CFAttributedStringRef)self.attString);

CGMutablePathRef path = CGPathCreateMutable();
CGPathAddRect(path, NULL, CGRectMake(0, 0, self.frameSize.width, CGFLOAT_MAX));
CTFrameRef frame = CTFramesetterCreateFrame(framesetter, CFRangeMake(0, self.attString.length), path, NULL);
CFArrayRef lines = CTFrameGetLines(frame);
size_t numOfLines = CFArrayGetCount(lines);
CGPoint lineOrigins[numOfLines];
CTFrameGetLineOrigins(frame, CFRangeMake(0, numOfLines), lineOrigins);

NSLog(@"Lines count %ld", numOfLines);
for (CFIndex i = 0; i < numOfLines; i++)
{
    CTLineRef line = CFArrayGetValueAtIndex(lines, i);
    [self draw:frame line:line];

    NSLog(@"%@", NSStringFromCGPoint(lineOrigins[i]));
}

Output:

2014-04-11 10:45:27.095 Backgammon HD Narde[2221:707] {0, 3.40282e+38}
2014-04-11 10:45:27.099 Backgammon HD Narde[2221:707] {0, 3.40282e+38}
2014-04-11 10:45:27.105 Backgammon HD Narde[2221:707] {84.997, 3.40282e+38}
2014-04-11 10:45:27.111 Backgammon HD Narde[2221:707] {0, 3.40282e+38}
2014-04-11 10:45:27.117 Backgammon HD Narde[2221:707] {0, 3.40282e+38}
2014-04-11 10:45:27.121 Backgammon HD Narde[2221:707] {0, 3.40282e+38}
2014-04-11 10:45:27.124 Backgammon HD Narde[2221:707] {0, 3.40282e+38}
2014-04-11 10:45:27.126 Backgammon HD Narde[2221:707] {0, 3.40282e+38}
2014-04-11 10:45:27.128 Backgammon HD Narde[2221:707] {136.804, 3.40282e+38}
2014-04-11 10:45:27.132 Backgammon HD Narde[2221:707] {0, 3.40282e+38}

You get correct coordinates, but CoreText origin is "bottom-left" and as you use a huge heigh by using CGFLOAT_MAX you don't see them. A sample code (based on your code) that's use a smaller height (1e7), and show base and flipped lines coordinates.

 NSAttributedString *attString = [[NSAttributedString alloc] initWithString:@"Lorem ipsum dolor sit amet, ..."];

CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString((CFAttributedStringRef)attString);

CGMutablePathRef path = CGPathCreateMutable();
// used a smaller height
CGPathAddRect(path, NULL, CGRectMake(0, 0, self.view.frame.size.width, 1e7));
CTFrameRef frame = CTFramesetterCreateFrame(framesetter, CFRangeMake(0, 0), path, NULL);
CFArrayRef lines = CTFrameGetLines(frame);
size_t numOfLines = CFArrayGetCount(lines);
CGPoint lineOrigins[numOfLines];
CTFrameGetLineOrigins(frame, CFRangeMake(0, 0), lineOrigins);

// transform to flip coordinate
CGAffineTransform transform = CGAffineTransformMakeTranslation(0, 1e7);
transform = CGAffineTransformScale(transform, 1, -1);

NSLog(@"Lines count %ld", numOfLines);
for (CFIndex i = 0; i < numOfLines; i++)
{
    CGPoint flipped; // flipped line location
    flipped = CGPointApplyAffineTransform(lineOrigins[i], transform);

    NSLog(@"origin=%@ flipped=%@", NSStringFromCGPoint(lineOrigins[i]), NSStringFromCGPoint(flipped));
}

log output :

Lines count 8
origin={0, 9.99999e+06} flipped={0, 12}
origin={0, 9.99997e+06} flipped={0, 27}
origin={0, 9.99996e+06} flipped={0, 42}
origin={0, 9.99994e+06} flipped={0, 57}
origin={0, 9.99993e+06} flipped={0, 72}
origin={0, 9.99991e+06} flipped={0, 87}
origin={0, 9.9999e+06} flipped={0, 102}
origin={0, 9.99988e+06} flipped={0, 117}

Correct way:

Get the frame of text with CTFramesetterCreateWithAttributedString. Use height from returned value.

CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString((CFAttributedStringRef)self.attString);
CGSize suggestedSize = CTFramesetterSuggestFrameSizeWithConstraints(framesetter,
                                                                    CFRangeMake(0, self.attString.length),
                                                                    NULL,
                                                                    CGSizeMake(self.width, CGFLOAT_MAX),
                                                                    NULL);
suggestedSize.width = self.width;
suggestedSize.height = ceilf(suggestedSize.height);
[self setContentSize:suggestedSize];


CGMutablePathRef path = CGPathCreateMutable();
CGPathAddRect(path, NULL, CGRectMake(0, 0, suggestedSize.width, suggestedSize.height));
CTFrameRef frame = CTFramesetterCreateFrame(framesetter, CFRangeMake(0, self.attString.length), path, NULL);
CFArrayRef lines = CTFrameGetLines(frame);
size_t numOfLines = CFArrayGetCount(lines);
CGPoint lineOrigins[numOfLines];
CTFrameGetLineOrigins(frame, CFRangeMake(0, numOfLines), lineOrigins);

for (CFIndex i = 0; i < numOfLines; i++)
{
    CTLineRef line = CFArrayGetValueAtIndex(lines, i);
    CCSprite *sprite = [self draw:frame line:line];
    NSLog(@"%@", NSStringFromCGPoint(lineOrigins[i]));
    sprite.position = lineOrigins[i];
}
链接地址: http://www.djcxy.com/p/81946.html

上一篇: UILabel突出显示颜色属性字符串(Apple bug?)

下一篇: CTFrameGetLineOrigins返回长Y坐标