I am breaking my head over something which works fine under Mac OS X, but not on iOS.
My goal is to do text folding. That means hiding a bunch of characters and showing a image instead. That can be done with an NSTextAttachment and with custom glyph mapping. On iOS I can only hide the characters but not show the text attachment. I am happy to entertain and try out all your suggestions on showing the attachment.
Attachements can be added to a regular string by:
The NSAttachmentCharacter has a glyph index of 65535 (according to logging).
My goal is to do text folding. That means hiding a bunch of characters and showing a image instead. That can be done with an NSTextAttachment and with custom glyph mapping. On iOS I can only hide the characters but not show the text attachment. I am happy to entertain and try out all your suggestions on showing the attachment.
Attachements can be added to a regular string by:
Code:
[NSString stringWithFormat:@"attachment: _%C_",(unichar)NSAttachmentCharacter]
Code:
-(NSUInteger)layoutManager:(NSLayoutManager *)layoutManager
shouldGenerateGlyphs:(const CGGlyph *)glyphs
properties:(const NSGlyphProperty *)props
characterIndexes:(const NSUInteger *)charIndexes
font:(UIFont *)aFont
forGlyphRange:(NSRange)glyphRange
{
//buffers
NSInteger size = glyphRange.length;
CGGlyph nullGlyph = kCGFontIndexInvalid;
CGGlyph *buffer = malloc(sizeof(CGGlyph) * size);
memset_pattern4(buffer, &nullGlyph, size);
NSGlyphProperty nullGlyphProperty = NSGlyphPropertyNull;
NSGlyphProperty *propBuffer = malloc(sizeof(NSGlyphProperty) * size);
memset_pattern4(propBuffer, &nullGlyphProperty, size);
NSUInteger index = 0;
while (index < glyphRange.length)
{
id attribute = [[layoutManager textStorage] attribute:@"FoldText"
atIndex:charIndexes[index]
longestEffectiveRange:&effectiveRange
inRange:NSMakeRange(0, [[layoutManager textStorage] length])];
if (attribute && [attribute boolValue])
{
UTF16Char ellipsis = NSAttachmentCharacter;
CGGlyph attachmentGlyph;
CTFontGetGlyphsForCharacters((CTFontRef) aFont, &ellipsis, &attachmentGlyph, 1);
if (effectiveRange.location == charIndexes[index])
{
NSLog(@"found: %hu | %d ||%d | %d | %d || %d",
glyphs[index],
props[index],
NSAttachmentCharacter,
attachmentGlyph,
NSGlyphPropertyControlCharacter,
kCGGlyphMax);
buffer[index] = 65535; //magic number for the glyph corresponding with NSAttachmentCharacter?
propBuffer[index] = NSGlyphPropertyControlCharacter;
[layoutManager setAttachmentSize:CGSizeMake(100, 100)
forGlyphRange:NSMakeRange(glyphRange.location+index, 1)];
}
// else//not necessary => see buffer alloc
// {
// propBuffer[index] = NSGlyphPropertyNull;
// }
}
else
{
buffer[index] = glyphs[index];
propBuffer[index] = props[index];
}
index++;
}
[layoutManager setGlyphs:buffer
properties:propBuffer
characterIndexes:charIndexes
font:aFont
forGlyphRange:glyphRange];
//fixme: leak
// free(propBuffer);
// free(buffer);
return glyphRange.length;