Re: CTFramesetterSuggestFrameSizeWithConstraints cuts off text

2013-05-17 Thread Graham Cox

On 17/05/2013, at 11:38 PM, Koen van der Drift  
wrote:

> // calculate the size it occupies
> 
>CTFramesetterRef framesetter = 
> CTFramesetterCreateWithAttributedString(attrString);
> []


> // draw the string:
> 
> []

>CTFramesetterRef framesetter = 
> CTFramesetterCreateWithAttributedString((CFAttributedStringRef) attrString);


Don't create the framesetter object twice. I'm not sure it has a bearing on 
your issue, but it would make sense that the framesetter used to calculate the 
frame should be the exact same one that draws the frame. It might be that 
creating it and calculating the size performs some caching that speeds up the 
second use. In any case it will use less memory if you only use one.

--Graham


___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: CTFramesetterSuggestFrameSizeWithConstraints cuts off text

2013-05-17 Thread Robert Vojta
Yep, I saw it as well. But IIRC it was in rare occasions. Rare in my point of 
view, because we do use "normal" alphabet. the problem was in special 
characters, emoji, symbols, ... In these times I tried every possible 
combination/available method/property/calculation/... without success. Also 
tried 3rd party labels, later I tried DTCoreText from Cocoanetics with the same 
output - wrong height. I also asked Apple engineers and then I gave up. Not 
sure, but I did suspect them that they use private API or dunno what, because 
their apps didn't have problems.

I'm pretty happy with attributed string and auto layout for now. It's enough 
for almost all needs and I'm glad that I'm not forced to dive into this "mess" 
again. 


On Friday, 17. May 2013 at 23:42, Quincey Morris wrote:

> On May 17, 2013, at 11:20 , Robert Vojta  (mailto:rob...@tapmates.com)> wrote:
> 
> > Height was wrong even if returned width <= constrained width.
> Once I took proper account of the returned width, I got no more "wrong" 
> heights.
> 
> However, IIRC, there was a separate issue that fractional line heights didn't 
> work correctly. Maybe you ran into that problem as well.
> 

___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: CTFramesetterSuggestFrameSizeWithConstraints cuts off text

2013-05-17 Thread Koen van der Drift
Thanks all for the insightful responses. In my case I am using a monospaced
font, and everything looks pretty square.  The thing I did wrong as it
turned out was that I had a little padding on the top, making my CTView to
slightly shift down, and therefore making the final string disappear.

My code looks like this now:

CGSize frameSize = CTFramesetterSuggestFrameSizeWithConstraints(framesetter,


CFRangeMake(0, 0),

NULL,


CGSizeMake(self.bounds.size.width,
CGFLOAT_MAX), &fitRange);




self.frame = CGRectMake(self.frame.origin.x,

self.frame.origin.y,

self.frame.size.width,

frameSize.height + PADDING_TOP);  <<===
correction for padding



Cheers,


- Koen.



On Fri, May 17, 2013 at 5:42 PM, Quincey Morris <
quinceymor...@rivergatesoftware.com> wrote:

> On May 17, 2013, at 11:20 , Robert Vojta  wrote:
>
> Height was wrong even if returned width <= constrained width.
>
>
> Once I took proper account of the returned width, I got no more "wrong"
> heights.
>
> However, IIRC, there was a separate issue that fractional line heights
> didn't work correctly. Maybe you ran into that problem as well.
>
>
___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: CTFramesetterSuggestFrameSizeWithConstraints cuts off text

2013-05-17 Thread Quincey Morris
On May 17, 2013, at 11:20 , Robert Vojta  wrote:

> Height was wrong even if returned width <= constrained width.

Once I took proper account of the returned width, I got no more "wrong" heights.

However, IIRC, there was a separate issue that fractional line heights didn't 
work correctly. Maybe you ran into that problem as well.

___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: CTFramesetterSuggestFrameSizeWithConstraints cuts off text

2013-05-17 Thread Robert Vojta
I ran into this few years ago and didn't find correct solution. Correct means 
nice & clean. Ended with adding 1/2 of line height, which causes another issues 
like wrong vertical alignment of elements. It was pre NSAttributedString era on 
iOS. Height was wrong even if returned width <= constrained width.

Did spend on this couple of weeks and finally gave up.  


On Friday, 17. May 2013 at 19:25, Quincey Morris wrote:

> On May 17, 2013, at 06:38 , Koen van der Drift  
> wrote:
>  
> > CGSize frameSize = 
> > CTFramesetterSuggestFrameSizeWithConstraints(framesetter, CFRangeMake(0, 
> > stringLength), NULL, CGSizeMake(self.bounds.size.width, CGFLOAT_MAX), 
> > &fitRange);
> > self.frame = CGRectMake(0, 0, self.frame.size.width, frameSize.height); // 
> >  frameSize.height is too small
> >  
>  
>  
> I ran into this problem a while back, and after a lot of anguish I think I 
> worked out what was going wrong. From an admittedly imperfect memory…
>  
> 'CTFramesetterSuggestFrameSizeWithConstraints' sometimes returns a width 
> that's *larger* than the width in the 'constraints' parameter -- wider than 
> the view width in your case. So, with your existing code, when the string is 
> eventually typeset and displayed, your view isn't wide enough for the text to 
> line-wrap with exactly the same line breaks as it when you got the suggested 
> frame size, and the text wraps with (generally) one extra line.
>  
> The extra width in the returned value comes from "hanging spaces" -- spaces 
> at the end of a line that don't count in the line's wrap width. For example, 
> if you specify a constraint width of 350 points, and the width metric for a 
> space is 5 points (in the font size being used), then the longest possible 
> typeset line is actually 355 points. There may also be other typesetting 
> situations, such as hanging punctuation, which produce similar results.
>  
> This is correct behavior, because the non-space characters in the line are 
> allowed to use all 350 points of the width. (Hanging punctuation may 
> partially occupy some of the 350-point width, and partially extend past the 
> end of the width.)
>  
> Note that the larger width isn't *always* returned -- it depends how close 
> the non-hanging characters of the longest line come to the constraint width 
> -- so the problem appears to be intermittent.
>  
> It's disputable, I guess, but I convinced myself it's correct to return a 
> width >350, because the character that "oversets" the line may have a 
> non-blank glyph -- even a space, when displaying text with a "show 
> invisibles" option -- and so needs to be given a place to display.
>  
> Therefore, you need to use the *returned* width for your CTFrame, instead of 
> your view width. This will mean that the CTFrame may overhang the view on the 
> right. In most cases this won't matter, since in most cases the overhanging 
> glyph will be a blank space.
>  
> Alternatively, you can pass a smaller width to 
> 'CTFramesetterSuggestFrameSizeWithConstraints' -- for example: 
> self.frame.size.width - (width of a space) -- to ensure that hanging 
> characters have a place to display. But this is an awkward solution if you 
> have a mix of fonts and point sizes in your attributed string.
>  
>  
> ___
>  
> Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)
>  
> 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:
> https://lists.apple.com/mailman/options/cocoa-dev/robert%40tapmates.com
>  
> This email sent to rob...@tapmates.com  

___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Re: CTFramesetterSuggestFrameSizeWithConstraints cuts off text

2013-05-17 Thread Quincey Morris
On May 17, 2013, at 06:38 , Koen van der Drift  
wrote:

>CGSize frameSize = 
> CTFramesetterSuggestFrameSizeWithConstraints(framesetter, CFRangeMake(0, 
> stringLength), NULL, CGSizeMake(self.bounds.size.width, CGFLOAT_MAX), 
> &fitRange);
>self.frame = CGRectMake(0, 0, self.frame.size.width, frameSize.height);   
> //    frameSize.height is too small

I ran into this problem a while back, and after a lot of anguish I think I 
worked out what was going wrong. From an admittedly imperfect memory…

'CTFramesetterSuggestFrameSizeWithConstraints' sometimes returns a width that's 
*larger* than the width in the 'constraints' parameter -- wider than the view 
width in your case. So, with your existing code, when the string is eventually 
typeset and displayed, your view isn't wide enough for the text to line-wrap 
with exactly the same line breaks as it when you got the suggested frame size, 
and the text wraps with (generally) one extra line.

The extra width in the returned value comes from "hanging spaces" -- spaces at 
the end of a line that don't count in the line's wrap width. For example, if 
you specify a constraint width of 350 points, and the width metric for a space 
is 5 points (in the font size being used), then the longest possible typeset 
line is actually 355 points. There may also be other typesetting situations, 
such as hanging punctuation, which produce similar results.

This is correct behavior, because the non-space characters in the line are 
allowed to use all 350 points of the width. (Hanging punctuation may partially 
occupy some of the 350-point width, and partially extend past the end of the 
width.)

Note that the larger width isn't *always* returned -- it depends how close the 
non-hanging characters of the longest line come to the constraint width -- so 
the problem appears to be intermittent.

It's disputable, I guess, but I convinced myself it's correct to return a width 
>350, because the character that "oversets" the line may have a non-blank glyph 
-- even a space, when displaying text with a "show invisibles" option -- and so 
needs to be given a place to display.

Therefore, you need to use the *returned* width for your CTFrame, instead of 
your view width. This will mean that the CTFrame may overhang the view on the 
right. In most cases this won't matter, since in most cases the overhanging 
glyph will be a blank space.

Alternatively, you can pass a smaller width to 
'CTFramesetterSuggestFrameSizeWithConstraints' -- for example: 
self.frame.size.width - (width of a space) -- to ensure that hanging characters 
have a place to display. But this is an awkward solution if you have a mix of 
fonts and point sizes in your attributed string.


___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Re: CTFramesetterSuggestFrameSizeWithConstraints cuts off text

2013-05-17 Thread Koen van der Drift
Thanks Fritz,

After trying out various values, this worked for me:

CGSize frameSize = 
CTFramesetterSuggestFrameSizeWithConstraints(framesetter, 

CFRangeMake(0, 0), 

NULL, 

CGSizeMake(self.bounds.size.width, CGFLOAT_MAX), 

&fitRange);

CGFloat lineHeight = CTFontGetSize( ctFont ) * 2.0;
frameSize.height += lineHeight;


I'm using CGFLOAT_MAX, since the text can be longer than the bounds of the view.


- Koen.



On May 17, 2013, at 10:37 AM, Fritz Anderson  wrote:

> Also, I had another app that didn't need the kludge. I don't have time to 
> experiment, but I think the operative line was:
> 
>// boundingRect.size was {columwidth, CGFLOAT_MAX}
>suggestion = CTFramesetterSuggestFrameSizeWithConstraints(setter,
>  CFRangeMake(0, 
> 0),
>  NULL,
>  
> boundingRect.size,
>  &actualRange);
> 
> Note the range of {0,0}, which allows the framesetter to run until it runs 
> out of space or string. That app worked properly.
> 
>   — F
> 
> 
> -- 
> Fritz Anderson
> Xcode 4 Unleashed: 4.5 supplement for free!
> http://www.informit.com/store/xcode-4-unleashed-9780672333279
> 


___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Re: CTFramesetterSuggestFrameSizeWithConstraints cuts off text

2013-05-17 Thread Fritz Anderson
Also, I had another app that didn't need the kludge. I don't have time to 
experiment, but I think the operative line was:

// boundingRect.size was {columwidth, CGFLOAT_MAX}
suggestion = CTFramesetterSuggestFrameSizeWithConstraints(setter,
  CFRangeMake(0, 0),
  NULL,
  boundingRect.size,
  &actualRange);

Note the range of {0,0}, which allows the framesetter to run until it runs out 
of space or string. That app worked properly.

— F


-- 
Fritz Anderson
Xcode 4 Unleashed: 4.5 supplement for free!
http://www.informit.com/store/xcode-4-unleashed-9780672333279


___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Re: CTFramesetterSuggestFrameSizeWithConstraints cuts off text

2013-05-17 Thread Fritz Anderson
On 17 May 2013, at 8:38 AM, Koen van der Drift  
wrote:

> CTFramesetterSuggestFrameSizeWithConstraints

I ran into this problem and had to resort to an ad-hoc kludge (though I guess 
all kludges are ad-hoc:

lineHeight = CTFontGetSize(self.ctDefaultFont)*1.2;
...
frameSize = CTFramesetterSuggestFrameSizeWithConstraints(ctFramesetter...
...
//  I wish I had a principled reason why this is necessary, or the best 
solution.
//  It looks good from a cursory examination, but surely this fails in some 
cases,
//  or with some combination of styles.
frameSize.height += lineHeight / 2.0;

— F

-- 
Fritz Anderson
Xcode 4 Unleashed: 4.5 supplement for free!
http://www.informit.com/store/xcode-4-unleashed-9780672333279


___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

CTFramesetterSuggestFrameSizeWithConstraints cuts off text

2013-05-17 Thread Koen van der Drift
I'm using Core Text to layout text in an UIView but am having troubles with 
getting the correct size that the text needs, so I can set the contentSize of 
the UIScrollView that it is embedded in.  I know it is the wrong size, because 
the last line is not showing.

I've done some spitting around, and it seems that 
CTFramesetterSuggestFrameSizeWithConstraints may not always work properly.   
However I haven't found a solution that works for me.  


I've pasted my code below, maybe I am overlooking something?


Thanks,

- Koen.

==




// create the string:

NSString *testString = @"This is a not so very long but at least long 
enough test string to cover more than one line.";

CFMutableAttributedStringRef attrString = 
CFAttributedStringCreateMutable(kCFAllocatorDefault, 0);
CFAttributedStringReplaceString (attrString, CFRangeMake(0, 0), 
(CFStringRef) testString );
CFIndex stringLength = CFStringGetLength((CFStringRef) attrString);

// give it a font

UIFont* uiFont = [UIFont fontWithName: @"Courier" size: 22.0];
CTFontRef ctFont = CTFontCreateWithName((__bridge CFStringRef) 
uiFont.fontName, uiFont.pointSize, NULL);
CFAttributedStringSetAttribute(attrString, CFRangeMake(0, stringLength), 
kCTFontAttributeName, ctFont);

// calculate the size it occupies

CTFramesetterRef framesetter = 
CTFramesetterCreateWithAttributedString(attrString);
CFRange fitRange;
CGSize frameSize = 
CTFramesetterSuggestFrameSizeWithConstraints(framesetter, CFRangeMake(0, 
stringLength), NULL, CGSizeMake(self.bounds.size.width, CGFLOAT_MAX), 
&fitRange);
self.frame = CGRectMake(0, 0, self.frame.size.width, frameSize.height);   
//    frameSize.height is too small


// draw the string:

CGContextRef context = UIGraphicsGetCurrentContext();

CGContextSetTextMatrix(context, CGAffineTransformIdentity);
CGContextTranslateCTM(context, 0, self.bounds.size.height);
CGContextScaleCTM(context, 1.0, -1.0);

CGMutablePathRef path = CGPathCreateMutable();
CGPathAddRect(path, NULL, self.frame);

CTFramesetterRef framesetter = 
CTFramesetterCreateWithAttributedString((CFAttributedStringRef) attrString);
CTFrameRef frameRef = CTFramesetterCreateFrame(framesetter, CFRangeMake(0, 
stringLength), path, NULL);

CTFrameDraw(frameRef, context);
___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com