Only print ol.style.Text to polygon if text label fits inside its geometry - openlayers-3

In OpenLayers I use ol.style.Text to add a text label to federal states polygons. The states have names of different length and also polygons of different sizes. It looks like this:
Is it possible to only print the text marker if it fits inside its polygon (e.g. after zooming in)? For instance, in the above example Hessen, Thüringen, Sachsen and Bayern would be printed, but Rheinland-Pfalz, Saarland and Baden-Württemberg would be omitted because the text goes beyond its feature's geometry...
I know I can set the font property of an ol.style.Text to a particular size based on the resolution but this does not help here as text would still overlap the borders sometimes...

This is currently not possible with help from the library. But you can use CanvasRenderingContext2D#measureText() in your vector layer's stlyeFunction to get the width of the label, and compare that with the extent's width of the polygon at a certain resolution, and decide based on that whether to render or not. You can also get smarter than using the extent's width, but it is probably a good enough approximation for many cases.

Related

Set numeric UILabel for Auto Layout to correctly compute the intrinsic content size

I have a UILabel with a font of size 50 and text 1. At runtime, its text is changed to other numbers.
If I, say, center it in its superview, the automatically detected (intrinsic content size) height is a lot bigger than the actual text, and this is because it tries not to crop other lower characters like g.
The thing is that I know I won't use other characters than digits. I also don't want to set a fixed height constraint for it.
UIFont metrics include ascender, descender, cap height, x height, etc... all of which determines how the characters fit into a container. There is a good explanation and diagram here: http://cocoanetics.com/2010/02/understanding-uifont
If you really want to get the height (and/or width) of the individual character "glyphs" you'll need to use Core Text. This will include calling CTFontGetGlyphsForCharacters() and CTFontCreatePathForGlyph() to get the "glyph path" (a CGPath object), at which point you can get the "bounding box" to determine the exact size.
Lots of discussions and example code out there... A good starting point is simply searching for CTFontCreatePathForGlyph

iOS: Modify a font height, width, and spacing independently when creating PDF

In an iOS app I need to use a specific font but each character needs to be taller, thinner, and the spacing closed up to fit correctly. Is it possible to stretch/squish a font programmatically?
When you're adding text to a PDF file there are multiple ways to influence how the text is going to appear. The most generic way (and the way that might actually be sufficient for you) is to scale the text matrix:
void CGContextSetTextMatrix ( CGContextRef c, CGAffineTransform t );
As mentioned in the comment by #mkl, you can provide a matrix that will scale up in the Y direction while scaling down in the X direction. The effect will be that the letters are stretched out vertically and squished horizontally.
Normally I would expect you don't have to touch the spacing in that case, as spacing will be "squished" together just as the other characters.
Just in case that isn't sufficient, PDF actually does provide a way to change the spacing between characters too:
void CGContextSetCharacterSpacing ( CGContextRef context, CGFloat spacing );
While Apple's description talks about "additional space" to add between characters, the PDF specification and I suspect Apple's implementation as a result allows the spacing value to be both positive and negative. A negative value would have the effect of moving the characters closer together.
Seems like the best option would be to create your own custom font.
You are able to change the kerning of your font (the space between the letters) and the thickness/thinness of the font, however you probably aren't able to edit the height of the font, unless you edit the bounding box the font is inside of to scale the letters differently.
You might also want to consider using a different font...or if you're REALLY hardcore you can edit the font yourself using photoshop/illustrator.

Karaoke-like progress highlight for iOS

I would like to implement karaoke-like progress highlight for iOS.
I know I could use NSAttributedString and highlight the text character by character. However, I would like the highlight to progress pixel by pixel, not character by character.
Any ideas?
P.S. No need for sample code, just point me to the right direction.
Here is an example:
I can't think of any automatic way to do that. There would be several problems to solve. It would be pretty hard, I think.
The hardest would probably be figuring out the pixel position of each word so you can pace the coloring to match the timing within the music. With text and attributed layout, you could probably get the text engine to give you the boundaries of each word and then apply the color attribute to each word as it's spoken/sung. You'd have to have data about the time offset for the beginning and end of each word's being sung.
You might have to use Core Text to get layout information about the bounding rectangles of each word.
Once you get that you could build a path (UIBezierPath or CGPath; they're pretty interchangeable) that follows the flow of the text, and then install that path in to a shape layer. You could then make the text transparent, make the shape layer a colored background that shows through, and animate the shape layer's strokeStart and/or strokeEnd properties to make it fill the text. You might need to do it word by word with a short animation that interpolates between one word and the next to get the timing right.
You probably want to have a look at Core Text, which is the lower level framework used for laying out text, using this you can obtain necessary paths that you need to render said effect (I suggest starting from answers similar to this)
There are plenty of answers for alternative, perhaps simpler answers, for example character by character or word-by-word, which may be easier to implement.

MINIMUM bounding rect width for NSAttributedString

I have an NSAttributedString which I draw into a rectangle (no text views here.) I allow the user to resize that rectangle thus forcing the text to wrap onto multiple lines. All is good and I'm using NSTextContainer etc to figure out the text bounding height for a given width.
The challenge I have is knowing what the MINIMUM width can be - so that I don't allow the user to resize the rectangle to be narrower than the widest character/glyph in the string.
I have a working solution which involves getting the bounding rect for each glyph (boundingRectForGlyphRange) and keeping track of the largest - but this is a real performance killer on larger strings.
Anyone know of a better way?
Thanks
When you choose your font and display language, you could compile a lookup of all possible glyph widths. Order it descending with the largest glyphs first, then use rangeOfString: != NSNotFound; breaking after you find one (this is your maximum glyph width).
Hard to say what the performance difference is like, but it is probably faster than fetching the width of all your glyphs every time since it's just a string comparison instead of a font measurement.

Converting LogFont height to Font size in points

I have a LOGFONT structure. Now all i'd like to do is get the associated font size in points from the LOGFONT height.
When the mapping mode is mm_Text (which it usually is), and when the lfHeight field is positive, it already gives the height in points. When it's negative, the units are pixels. MSDN for LogFont gives you the formula to convert between them:
lfHeight = -MulDiv(PointSize, GetDeviceCaps(hDC, LOGPIXELSY), 72);
There are 72 points per inch. GetDeviceCaps tells you the number of pixels per inch on a given device. Invert the formula to get pixels from points:
PointSize := MulDiv(-lfHeight, 72, GetDeviceCaps(hDC, LogPixelsY);
The important thing to realize here is that you need a device context. Font sizes don't exist independently of the media they appear on. The pixel height of a font on the screen will be different from the pixel height of a font on a printer. Use the Handle property of whatever canvas you're planning on drawing to.
I find this a bit confusing, as well.
Here are a few things that I háve learned. ;)
Examine the two low-order bits of lfPitchAndFamily to determine the font type.
For fixed-pitch fonts, use GetTextMetrics and the TEXTMETRIC structure.
For variable-pitch fonts (true-type, etc), use GetOutlineTextMetrics and the OUTLINETEXTMETRIC structure. Be sure you have the structure aligned properly. Also, the structure is variable-sized. Call the function once to get the size, allocate space, then call the function again to fill the structure.
From there, you can find proper ascent, descent, and other size-related information.
Keep in mind that they are recommended values and not all display routines will use them properly. For example, I am in the process of figuring out a correct method of determining the required height of a dialog box static control for a given string of text.
It does not appear that Microsoft has followed their own documentation. ;)
Not that the documentation is all that clear or complete, to begin with.

Resources