iPhone CoreText: Find the pixel coordinates of a substring - iphone

Here's a screenshot of the twitter app for reference: http://screencast.com/t/YmFmYmI4M
What I want to do is place a floating pop-over on top of a substring in an NSAttributedString that could span multiple lines. NSAttributedString is a requirement for the project.
In the screenshot supplied, you can see that links are background-highlighted, so it leads me to believe that they're using CoreText and NSAttributedStrings. I also found something called CTRunRef ( http://developer.apple.com/library/ios/#documentation/Carbon/Reference/CTRunRef/Reference/reference.html ) which looks promising, but I'm having trouble fitting it all together conceptually.
In short, if I have a paragraph in core text and when I tap on a word, how do I find the bounding box for that word?

Set some attribute in the attributed string that won't effect display, but will cause it to be laid out as a seperate glyph run, then use CoreText to layout the string
CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString(attrString);
CTFrameRef ctframe = CTFramesetterCreateFrame(framesetter, CFRangeMake(0, 0), path, NULL);
Now you will have to hunt through the frame to find the relevant chunk of text. Get the array of CTLineRefs with CTFrameGetLines().
Iterate through the array, testing if the touch was on that line, by checking it is within the rect returned by CTLineGetImageBounds(). If it is, now look through the glyph runs in the line.
Again, you can get an array of CTRunRefs with CTLineGetGlyphRuns(). Check whether the tap was within the glyph run with CTRunGetImageBounds(), and if it was you can find the the range of indices in the original attributed string that the glyph run corresponds to with CTRunGetStringIndices().

you need to find Y by CTLine and X by CTRun width and height you can get by word and font itself. ill attache my project link, its really simple code but you can reedit in order to meet your needs. hope it helps cheers if you improve general logic please let me know thx.
textViewProject

The link given by George was very helpful and got me what I wanted. But strange thing happened. It was working in iOS SDK 4.0 but in the iOS SDK 5 the position of the link appeared in wrong position on the view.
So I had to tweak the code a little bit. For the x coordinates of the touchable button, I had to use CTRunGetTypographicBounds instead of the CTRunGetImageBounds function.
So over all, in the tweaked code:
The y Coordinate , width and height was calculated using CTRunGetImageBounds.
And x coordinate was calculated using CTRunGetTypographicBounds.

I've been working on a small library that does exactly that. You can find it here: https://github.com/pothibo/CMFramework
However, this library is in its alpha stage, there's optimization needed and some feature are lacking (line height is one of the urgent feature I want to add)
If you decide to use it and find issue, don't hesitate to post issues on github!

Related

Trouble with font and text extrusion

So, I'm doing some odd things with text extrusion and (perhaps not surprisingly) having some odd issues in OpenSCAD.
This is part of a much larger project, but I've been able to simplify the problem down to the following snippet of code.
use<RingbearerMedium-51mgZ.ttf>
Text = "b";
Font = "Ringbearer:style=Medium";
segment_count = 2;
segment_width = 2;
text_height = 5;
text_thickness = 1;
// Iterate over each "segment" of text
for (segment_number = [0: segment_count - 1])
{
// Calculate the x offset of the current "segment" of text
segment_x_offset = segment_number * segment_width;
// Extrude the "segment" of text to the requested thickness
linear_extrude(text_thickness)
// Grab the current "segment" of text
intersection()
{
text(Text, font=Font, size=text_height);
translate([segment_x_offset, 0])
square([segment_width, text_height]);
}
}
All this does is generate a line of text (just "b", in this case), cuts it into "segments", then extrudes each segment in-place. It's not much use in this example, but in the larger one, I'm translating and rotating each segment.
OpenSCAD's F5 preview renders fine. Here's a screenshot:
F5 Preview
However, the F6 preview always drops the left side of the letter "b" and displays the error "ERROR: The given mesh is not closed! Unable to convert to CGAL_Nef_Polyhedron". Here's a screenshot:
F6 Preview
This effects other letters as well, but only seems to be a problem with the "Ringbearer" font I'm trying to use. I don't know if I can upload the font, but it's available for download for free from here: Link to Ringbearer Font. Extruding and rendering the font without breaking it into segments works just fine. It's just when I try to segment this particular font that OpenSCAD fails.
Now, the obvious answer is to use a font that works, which is fine, as far as it goes, but I'm genuinely curious why this is happening. Is it an error with the font or is this a limitation of OpenSCAD? Is this a known issue that I'm just not aware of?
I appreciate any insight I can get.
Within OpenScad, go to help->font list.
I think the font you are using isn't supported.
Yet I had a similar problem with a supported font. I changed the font few times until I found one that works for me well, and look nice as well.
It also depends on the font size. Sometimes same font fails at a smaller size, and works well on a larger size.
Anyway, you can see this on the slicer, before going to the printing. Take a close look at the slicing layers of the text, it will save you some printing time and frustration.

How can I determine the position of a contentcontol in a Word Document

We're developing an Office.js application for creating documents. We want to integrate with a digital signing solution. This solution requires a position (x and y) for the signature in Pixels. But because the content of the document will vary, the position of the signature is not fixed. We use contentcontrols for our other dynamic content, so I'm trying to find a way of reading or calculating the position of a specific contentcontrol.
If there are any other elements we can use to determine the position that would be fine too. I would prefer a Office.JS solution, but OpenXML would also work.
In documentation there seems no support for getting the position. For Ranges there is this compareLocationWith() method, so you can get the position relative to another range, but no coordinates.
I would appreciate any help or suggestions!
Thank you.

FastPDFKit get document size

I might be overlooking this, but how can one get the size of a PDF if you're using FastPDFKit?
I'm trying to create PNG's from a pdf, but without knowing the actual dimensions of the page it's rather hard to get it right.
EDIT:
I searching in the documentation before, but all I found was this method:
- (void)getCropbox:(CGRect *)cropbox andRotation:(int *)rotation forPageNumber:(NSInteger)pageNumber withBuffer:(BOOL)withOrWithout
But I have no idea how to use it, it doesn't return anything.
Not sure how familiar you are with PDF, but each page specifies a number of "boxes" that are various rectangles of interest (crop, media, etc)
Most apps using PDF elect to use the crop box which defines the region of the page that should be displayed. (See section 10.10.1 of the PDF 1.7 specification: http://www.adobe.com/devnet/pdf/pdf_reference_archive.html)
Also of note is that a page can specify a rotation angle of 0, 90, 180, or 270 which you need to apply to the crop box yourself. (see /Rotate in table TABLE 3.27 of the PDF 1.7 spec)
So using the above API you would call it like so:
[somePDFDoc getCropbox:&cropbox andRotation:&rotation forPageNumber:10 withBuffer:NO];
This would give you the cropbox rect and it's rotation.
NOTE: I have never used FastPDFKit
NOTE2: If the value of cropbox is CGRectZero, you want to use one of the other rects. Most viewers use the media box instead.

find the frame or position from the content drawn on the screen [duplicate]

Here's a screenshot of the twitter app for reference: http://screencast.com/t/YmFmYmI4M
What I want to do is place a floating pop-over on top of a substring in an NSAttributedString that could span multiple lines. NSAttributedString is a requirement for the project.
In the screenshot supplied, you can see that links are background-highlighted, so it leads me to believe that they're using CoreText and NSAttributedStrings. I also found something called CTRunRef ( http://developer.apple.com/library/ios/#documentation/Carbon/Reference/CTRunRef/Reference/reference.html ) which looks promising, but I'm having trouble fitting it all together conceptually.
In short, if I have a paragraph in core text and when I tap on a word, how do I find the bounding box for that word?
Set some attribute in the attributed string that won't effect display, but will cause it to be laid out as a seperate glyph run, then use CoreText to layout the string
CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString(attrString);
CTFrameRef ctframe = CTFramesetterCreateFrame(framesetter, CFRangeMake(0, 0), path, NULL);
Now you will have to hunt through the frame to find the relevant chunk of text. Get the array of CTLineRefs with CTFrameGetLines().
Iterate through the array, testing if the touch was on that line, by checking it is within the rect returned by CTLineGetImageBounds(). If it is, now look through the glyph runs in the line.
Again, you can get an array of CTRunRefs with CTLineGetGlyphRuns(). Check whether the tap was within the glyph run with CTRunGetImageBounds(), and if it was you can find the the range of indices in the original attributed string that the glyph run corresponds to with CTRunGetStringIndices().
you need to find Y by CTLine and X by CTRun width and height you can get by word and font itself. ill attache my project link, its really simple code but you can reedit in order to meet your needs. hope it helps cheers if you improve general logic please let me know thx.
textViewProject
The link given by George was very helpful and got me what I wanted. But strange thing happened. It was working in iOS SDK 4.0 but in the iOS SDK 5 the position of the link appeared in wrong position on the view.
So I had to tweak the code a little bit. For the x coordinates of the touchable button, I had to use CTRunGetTypographicBounds instead of the CTRunGetImageBounds function.
So over all, in the tweaked code:
The y Coordinate , width and height was calculated using CTRunGetImageBounds.
And x coordinate was calculated using CTRunGetTypographicBounds.
I've been working on a small library that does exactly that. You can find it here: https://github.com/pothibo/CMFramework
However, this library is in its alpha stage, there's optimization needed and some feature are lacking (line height is one of the urgent feature I want to add)
If you decide to use it and find issue, don't hesitate to post issues on github!

Core Text - select text in iPhone?

I need to render rich text using Core Text in my view (simple formatting, multiple fonts in one line of texts, etc.). I am wondering if text rendered this way can be selected by user using (standard copy / paste function)?
I implemented a text selection in CoreText. It is really a hard work... But it's doable.
Basically you have to save all CTLine rects and origins using CTFrameGetLineOrigins(1), CTLineGetTypographicBounds(2), CTLineGetStringRange(3) and CTLineGetOffsetForStringIndex(4).
The line rect can be calculated using the origin(1), ascent(2), descent(2) and offset(3)(4) as shown bellow.
lineRect = CGRectMake(origin.x + offset,
origin.y - descent,
offset,
ascent + descent);
After doing that, you can test which line has the touched point looping the lines (always remember that CoreText uses inverse Y coordinates).
Knowing the line that has the touched point, you can know the letter that is located at that point (or the nearest letter) using CTLineGetStringIndexForPosition.
Here's one screenshot.
For that loupe, I used the code shown in this post.
Edit:
To draw the blue background selection, you have to paint the rect using CGContextFillRect. Unfortunately, there's no background color in NSAttributedString.