I am trying to create my custom spell checker for the UITextView.
To show that a word is misspelled, I need to add the "red dotted line" under the misspelled word.
To do that, here is what I thought would work -
I create a dictionary which contains the values for the key NSUnderlineStyleAttributeName.
However, what this does is, it does underline the characters but it does not have a dotted pattern.
Also, setting the strokeColorAttribute also does not seem to have any effect.
Here is my code -
NSMutableDictionary *misspelledAttributes = [NSMutableDictionary dictionary];
[misspelledAttributes setObject:[NSNumber numberWithInt:kCTUnderlineStyleThick|kCTUnderlinePatternDot] forKey:NSUnderlineStyleAttributeName];
[misspelledAttributes setObject:[UIColor redColor] forKey:NSStrokeColorAttributeName];
To set the attributes to a attributed string for a particular range -
NSMutableAttributedString *attrString = [self.textView.attributedText mutableCopy];
[attrString addAttributes:misspelledAttributes range:wordRange];
It would be great if someone could help me with this and point out what I am missing/doing wrong.
I think you are going to have to find an approach other than NSAttributedString.
As far as I can tell, your only value choices in iOS for NSUnderlineStyleAttributeName are NSUnderlineStyleNone or NSUnderlineStyleSingle, which represent numbers.
NSUnderlineColorAttributeName support iOS 7.0+.
Related
I own a content-management system which uses Cake's inflector to output entries with pluralization if I detect there's more than one available.
if ($amt >= 2)
$object_name = Inflector::pluralize($object_name);
This works well for any object so long as it isn't in the Inflector's "irregular" list.
http://inflector.cakephp.org/The%20Purple%20Cow returns "The Purple Tows"
http://inflector.cakephp.org/Purple%20Cow returns "Purple Pows"
http://inflector.cakephp.org/The%20Purple%20Goose returns "The Purple Teese"
http://inflector.cakephp.org/Purple%20How returns "Purple Hows" as expected
For some reason it's substituting the last word's first letter with the first word's first letter, then adding an S as expected.
UPDATE: CakePHP bug, documented here. Will be fixed in 2.6.5. Question has been modified to avoid confusion.
Seems to be a bug specific to the word Cow in the last position. "The Purple Hen" and "Purple Hen" work fine. "Cow Fence" works fine. But "Big Cow" or "The Big Cow" reproduce the bug.
I would recommend looking into opening a ticket using their guidelines here.
You'll need to search existing tickets related to the inflector to see if it has already been reported. There are several other inflector issues, but I didn't find anything when searching for the term cow.
I am using CategoryPointerAnnotation to draw an arrow and show label. Right now the label seems to be too wide. Is it possible to add a line break so that that $ amount shows up on the next line?
CategoryPointerAnnotation ann5 = new CategoryPointerAnnotation("You are here $" +
NumberFormat.getIntegerInstance().format(
num.intValue()), cat, num.intValue(), -2.35619449);
No, line-breaks are not supported. Neither in title, subtitles, labels, tooltips, etc. You can search the JFreeChart forum for "linebreak" or "newline" to find related posts. There have been featuers-requests and according to the forum there were even patches available to fix this, but none has made it into JFreeChart yet (as of 1.0.19).
Have you tried adding in System.getProperty("line.separator")?
I am currently writing a simple bitmap font generator using CoreGraphics and CoreText. I am retrieving the kerning table of a font with:
CFDataRef kernTable = CTFontCopyTable(m_ctFontRef, kCTFontTableKern, kCTFontTableOptionNoOptions);
and then parse it which works fine. The kerning pairs give me the glyph indices (i.e. CGGlyph) for the kerning pairs, and I need to translate them to unicode (i.e. UniChar), which unfortunately does not seem super easy. The closest I got was using:
CGFontCopyGlyphNameForGlyph
to retrieve the glyph name of the CGGlyph, but I don't know how to convert the name to unicode, as they are really just strings such as quoteleft. Another thing I though about was parsing the kCTFontTableCmap myself to manually do the mapping from the glyph to the unicode id, but that seems to be a ton of extra work for the task. Is there any simple way of doing this?
Thanks!
I don't know a direct method to get the Unicode for a given glyph, but you could
build a mapping in the following way:
Get all characters of the font with CTFontCopyCharacterSet().
Map all these Unicode characters to their glyph with CTFontGetGlyphsForCharacters().
For each Unicode character and its glyph, store the mapping glyph -> Unicode
in a dictionary.
The glass docs made it look so easy!
I can get my map drawn with start and end points, but the polyline to connect the two isn't getting rendered.
Here's a simple one:
glass://map?w=240&h=360&marker=0;28.036352,-82.422457&marker=1;28.044039,-82.421721&polyline=28.036352,-82.422457,28.044039,-82.421721
After a night and a day of throwing everything at it, still no joy. I must be Doing it Wrong(tm) ... I hope someone sees a problem hidden in plain sight (at least to me).
You're missing a semicolon right after polyline=. Here's the corrected URL:
glass://map?w=240&h=360&marker=0;28.036352,-82.422457&marker=1;28.044039,-82.421721&polyline=;28.036352,-82.422457,28.044039,-82.421721
The documentation says
Each polyline consists of a width and color followed by the vertices in the polyline. For example: polyline=8,ffff0000;47.6,-122.34,47.62,-122.40 specifies an 8-pixel wide red line between (47.6,-122.34) and (47.62,-122.40).
The proper format for a 2-point polyline is therefore:
polyline=WIDTH_IN_PIXELS, COLOR_IN_HEX; START_POINT_LAT, START_POINT_LONG, END_POINT_LAT, END_POINT_LONG,
You need to specify the semicolon to denote the end of the width, color tuple.
I'm currently writing an eBook reader for Windows Phone Seven, and I'm trying to style it like the Kindle reader. In order to do so, I need to split my books up into pages, and this is going to get a lot more complex when variable font sizes are added.
To do this at the moment, I just add a word at a time into the textblock until it becomes higher than its container. As you can imagine though, with a document of over 120,000 words, this takes an unacceptable period of time.
Is there a way I can find out when the text would exceed the bounds (logically dividing it into pages), without having to actually render it? That way I'd be able to run it in a background thread so the user can keep reading in the meantime.
So far, the only idea that has occurred to me is to find out how the textblock decides its bounds (in the measure call?), but I have no idea how to find that code, because reflector didn't show anything.
Thanks in advance!
From what I can see the Kindle app appears to use a similar algorithm to the one you suggest. Note that:
it generally shows the % position through the book - it doesn't show total number of pages.
if you change the font size, then the first word on the page remains the same (so that's where the % comes from) - so the Kindle app just does one page worth of repagination assuming the first word of the page stays the same.
if you change the font size and then scroll back to the first page, then actually there is a discontinuity - they pull content forwards again in order to fill the first page.
Based on this, I would suggest you do not index the whole book. Instead just concentrate on the current page based on a "position" of some kind (e.g. character count - displayed as a percentage). If you have to do something on a background thread, then just look at the next page (and maybe the prev page) in order that scrolling can be more responsive.
Further to optimise your experience, there are a couple of changes you could make to your current algorithm that you could try:
try a different starting point and search increment for your algorithm - no need to start at one word and to then only add one word at a time.
assuming most of your books are ASCII, try caching the width of the common characters, and then work out the width of textblocks yourself.
Beyond that, I'd also quite like to try using <Run> blocks within your TextBlock - it may be possible to get the relative position of each Run within the TextBlock - although I've not managed to do this yet.
I do something similar to adjust font size for individual textboxes (to ensure they all fit). Basically, I create a TextBlock in code, set all my properties and check the ActualWidth and ActualHeight properties. Here is some pseudo code to help with your problem:
public static String PageText(TextBlock txtPage, String BookText)
{
TextBlock t = new TextBlock();
t.FontFamily = txtPage.FontFamily;
t.FontStyle = txtPage.FontStyle;
t.FontWeight = txtPage.FontWeight;
t.FontSize = txtPage.FontSize;
t.Text = BookText;
Size Actual = new Size();
Actual.Width = t.ActualWidth;
Actual.Height = t.ActualHeight;
if(Actual.Height <= txtPage.ActualHeight)
return BookText;
Double hRatio = txtPage.ActualHeight / Actual.Height;
return s.Substring((int)((s.Length - 1) * hRatio));
}
The above is untested code, but hopefully can get you started. Basically it sees if the text can fit in the box, if so you're good to go. If not, it finds out what percentage of the text can fit and returns it. This does not take word breaks into account, and may not be a perfect match, but should get you close.
You could alter this code to return the length rather than the actual substring and use that as your page size. Creating the textblock in code (with no display) actually performs pretty well (I do it in some table views with no noticeable lag). I wouldn't send all 120,000 words to this function, but a reasonable subset of some sort.
Once you have the ideal length you can use a RegEx to split the book into pages. There are examples on this site of RegEx that break on word boundaries after a specific length.
Another option, is to calculate page size ahead of time for each potential fontsize (and hardcode it with a switch statement). This could easily get crazy if you are allowing any font and any size combinations, and would be awful if you allowed mixed fonts/sizes, but would perform very well. Most likely you have a particular range of readable sizes, and just a few fonts. Creating a test app to calculate the text length of a page for each of these combinations wouldn't be that hard and would probably make your life easier - even if it doesn't "feel" right as a programmer :)
I didn't find any reference to this example from Microsoft called: "Principles of Pagination".
It has some interesting sample code running in Windows Phone.
http://msdn.microsoft.com/en-us/magazine/hh205757.aspx
You can also look this article about Page Transitions in Windows Phone and this other about the final touches in the E-Book project.
The code is downloadable: http://archive.msdn.microsoft.com/mag201111UIFrontiers/Release/ProjectReleases.aspx?ReleaseId=5776
You can query the FormattedText class that is used AFAIK inside textBlock. since this is the class being used to format text in preparation for Rendering, this is the most lower-level class available, and should be fast.