Superscript, Subscript text with Core Text iPhone - iphone

Can anyone explain me, How to draw superscript and subscript alphabets with Core Text?
Thanks.

I noticed that this question is a bit old, I hope you still require assistance in this matter and that this post will help you.
you can use NSAttributedString (or its mutable counterpart NSMutableAttributedString) to assign different attributes (such as font, both name and size) to specific ranges of a single string.
Superscript and subscript are not natively supported by core text and to make them look good you might need to do quite a lot of work. Fortunately there is an open source project developed by Oliver Drobnik from cocoa genetics that allows you to easily convert HTML into NSAttributedString (or NSMutableAttributedString), feed it into a custom textview and show superscripts and subscripts (along with many other HTML and CSS) as they would appear in a UIWebview, but without the need to use a UIWebview. You can download the project from here.
While a lot of effort has been put into this project, there are two caveats:
The computations can be at times very performance intensive.
Not all HTML tags and CSS features are supported yet.

IF NSAttributedString is an acceptable solution you can create a superscript / subscript effect with NSAttributedString rather than Core Text. This is how I did it:
NSMutableAttributedString *str = [[NSMutableAttributedString alloc] initWithString:myString];
// Everything except the first character is rendered with the regular size / position
[str addAttribute:NSFontAttributeName
value:font
range:NSMakeRange(1, [amountString length]-1)]; // Everything except the first character is rendered with the regular size / position
// First character is 5/8 normal size
[str addAttribute:NSFontAttributeName
value:[UIFont fontWithName:initialFont.fontName
size:initialFont.pointSize/8*5]
range:NSMakeRange(0, 1)];
// Set the baseline offset to push the first character into a superscript position
[str addAttribute:#"NSBaselineOffset"
value:[NSNumber numberWithFloat:initialFont.pointSize*1/3]
range:NSMakeRange(0, 1)];
The key lines are the last two, which make the size of the super/sub script text smaller and change it's vertical position. It's worth noting that I'm using a string (#"NSBaselineOffset") instead of a defined attribute name constant (NSBaselineOffsetAttributeName). From what I was able to gather I believe that NSBaselineOffsetAttributeName is defined in the libraries for Mac but not for iOS (which I was developing for when I came up with this). As I result I used the name string itself rather than a constant for the attribute name.

Related

How can I display super script number in text view iphone sdk?

I want to display super script number in a simple text view can any one help me for that?
UITextView can't handle rich text so if you want to have superscripted numbers you have to build up a string using the unicode characters for superscripted numbers, e.g.
NSString *super0 = #"\u2070";
Gives you a superscripted zero. You can find the rest of the numerals here on wikipedia. You'll have to build up the string yourself from the individual digits but that will be a nice programming exercise.
Under the Edit menu in Xcode there is a Special Characters option.
int no=1;
NSString *str=#"xyz";
*yourtextView*.text=[NSString stringWithFormat:#"%#%d",str,no];

Displaying 'special' characters from other encodings in UILabel or similar

I'd like to be able to simulate a terminal on my iPhone to play games like Nethack using the primitive graphics I enjoyed on a real DEC terminal. Nethack allows selection of DECgraphics for vt-compatible terminals or IBMGraphics for codepage 437 support.
I know that these special graphics characters are generated by strings sent to the terminal (vt100.net has a huge amount of information including the terminal manuals and test programs). I can receive and interpret those strings but I need to be able to reproduce and display those characters in a UIView.
It looks like kCFStringEncodingMacVT100 and kCFStringEncodingDOSLatinUS are the keys to the puzzle. Here's a bit of partial code showing what I tried to do to get "special characters" glyphs onto a UILabel:
UInt8 c = some value...
NSStringEncoding stringEncoding = CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingMacVT100);
NSData *charData = [NSData dataWithBytes:&c length:1];
NSString *charString = [[NSString alloc] initWithData:charData encoding:stringEncoding];
label.font = [UIFont fontWithName:#"Courier New" size:20.f];
label.text = charString;
I tried values of c from 0 to 255. I can display characters from space to '~' with all the expected stuff in between using this code but there are no corners or other line characters at all. When there is no character to display, charString is nil.
Now I'm pretty sure the Courier New TTF has these characters - on my Mac I can play Nethack with the terminal font set to Courier New and I can set DECgraphics and the display is OK.
So the questions are:
what's wrong with the code above?
what freely available monospaced truetype fonts are there supporting the DEC special characters and/or codepage 437?
how can you test a TTF once you have it to be sure those glyphs are there?
how can you display these glyphs in a UILabel or similar?
(I don't want to use any of the graphical tilesets available, I don't like them. I know there are at least two Nethacks available for free already but none have the straightforward keyboard interface I want, I find the popup a window for everything approach really slow and frustrating. I know it's not an easy project. And I might want to to Angband one day.)
Most (all?) of the glyphs in CP437 have corresponding code points in the Unicode standard, as detailed on this Wikipedia article.
For example, to display a club, you can do the following. It works with the default UILabel font:
UniChar club = 0x2663;
NSString *clubString = [NSString stringWithCharacters:&club length:1];
[label setText:clubString];

Core text exactly same as UITextView text format?

I'm trying to set up a CTFrame that exactly matches my UITextView's text format in iPad.
First of all, I converted UITextView's text to an attributed string. Then I set up a width and a height of drawing box in which Core Text will draw text.
I succeeded to draw text using Core Text, but UITextView and Core Text show slightly different results even though I used the same font and size.
Specifically, when I used [UIFont systemFontOfSize:21], each space in UITextView has one more pixel than Core Text's result.
It's okay for a short sentence or word, but if UITextView and Core Text have multiple lines, their result become very different. For example, UITextView performs word-wrapping for one word at the end of line, while Core Text keeps that word in the same line. If you see the attached picture, the start positions of the last word "paragraph" are already very different (8 pixel gap due to 8 space characters).
More badly, if I use different fonts such as a custom font added to my project, each character in UITextView has 1 pixel more.
I'm using Core Text to find the pixel-position of the current cursor in UITextView, so both of them should perfectly match each other, containing the same number of characters and words in each line.
Question: Is there a way to make Core Text object that perfectly matches UITextView's text format?
Thank you!
Here's a code how I set up attributed string. (I just followed Core Text Guide.)
CTFontRef font = CTFontCreateWithName((CFStringRef) [UIFont systemFontOfSize:21.0].fontName, 21.0, NULL);
CFMutableAttributedStringRef attrString2 = CFAttributedStringCreateMutable(kCFAllocatorDefault, 0);
CFAttributedStringReplaceString (attrString2, CFRangeMake(0, 0), (CFStringRef) string);
CFAttributedStringSetAttribute(attrString2, CFRangeMake(0, [string length]),kCTFontAttributeName, font);
-
-
Here's a picture.
Your solution might work for a specific font at a specific point size, but you can't rely on it in general.
CoreText is simply not compatible with normal UILabels, UITextView:s or UIStringDrawing, so you can't mix them.
Either you have to use only CT functions for all string handling (including implementing custom input if that is what you need) or not use them at all.
Answer to myself.
I just found very simple solution! Using any font editor, you can just change the width of space character (ascii value 32); an original font for UITextView and a modified font for Core Text or vice versa. I used a freeware font editor FontForge. Though I still have to do some extreme-case tests such as writing Japanese characters and English alphabets in the same line and so on, now it becomes almost possible to find a pixel-position of a cursor/caret in UITextView.

Search or compare within a Grapheme Cluster in Korean

In my current implementation of a UISearchBarController I'm using [NSString compare:] inside the filterContentForSearchText:scope: delegate method to return relevant objects based on their name property to the results UITableView as you start typing.
So far this works great in English and Korean, but what I'd like to be able to do is search within NSString's defined character clusters. This is only applicable for a handfull of languages, of which Korean is one.
In English, compare: returns new results after every letter you enter, but in Korean the results are generated once you complete a recognized grapheme cluster. I would like to be able to search through my Korean objects name property via the individual elements that make up a syllable.
Can anyone shed any light on how to approach this? I'm sure it has something to do with searching through UTF16 characters manually, or by utilising a lower level class.
Cheers!
Here is a specific example that's just not working:
`NSString *string1 = #"이";
`NSString *string2 = #"ㅣ";
NSRange resultRange = [[string1 decomposedStringWithCanonicalMapping] rangeOfString: [string2 decomposedStringWithCanonicalMapping] options:(NSLiteralSearch)];
The result is always NSNotFound, with or without decomposedStringWithCanonicalMapping.
Any ideas?
I'm no expert, but I think you're very unlikely to find a clean solution for what you want. There doesn't seem to be any relationship between a Korean character's Unicode value and the graphemes that it's made up of.
e.g. "이" is \uc774 and "ㅣ" is \u3163. From the perspective of the NSString, they're just two different characters with no specific relationship to each other.
I suspect that you will have to find or create an explicit mapping between characters and their graphemes, and then write your own search function that consults this mapping.
This very long page on Unicode Korean can help you, if it comes to that. It has a table of all the characters which suggests some structured relation between the way characters are numbered and their components.
If you use compare:options with NSLiteralString, it should compare character by character, that is, the Unicode code points, regardless of the grapheme. The default behavior of compare: is to use no options. You could use - decomposedStringWithCanonicalMapping to get the Unicode bytes of the input string, but I'm not sure how that would interact with compare:.

How to detect if a Unicode character maps to the missing-symbol square?

Is there a way to detect whether a Unicode character is present in a font on the iPhone, i.e., to detect whether the character will map to a printable glyph or instead to the square "missing character" symbol?
For example, if I want to generate a random Wingding character with this snippet:
NSString *s = [NSString stringWithFormat:#"%C", (0x2700 + (arc4random() % 0x0100))];
is there a way to tell if the generated string will render as the little square, or a real glyph when I draw it with this:
[s drawAtPoint:x withFont:[UIFont systemFontOfSize:30]];
Thanks!
...R
I was able to accomplish this using Core Text's CTFontGetGlyphsForCharacters:
- (BOOL)isInCharSet:(unichar)character
{
CTFontRef fontRef = CTFontCreateWithName((CFStringRef)#"Arial", 0.0, NULL);
unichar characters[] = {character};
CGGlyph glyphs[] = {};
return (BOOL)CTFontGetGlyphsForCharacters(fontRef, characters, glyphs, 1);
}
NSFont has a property coveredCharacterSet that UIFont does not have. So I would recommend to use your desktop PC to create the coveredCharacterSet information and put it into your iphone app.
A list of fonts that are available on the iphone can be found at: http://daringfireball.net/misc/2007/07/iphone-osx-fonts
I don't know of any method that checks for this specifically, however I imagine it'd be possible to set up an NSDictionary with paired values for each table of characters encoded into Unicode, then run a check to ensure that the generated value falls within the ranges specified by one of the paired values.
Why not generate it on your computer, if you're using the system font it should be Helvetica and there's the character maps in the Font menu option of almost any program.