How to control the border of text characters

Suppose I have a clock application, and I want to mark the clock with characters that may be in an arbitrary character set / font. I would like to create a character in the frame and fill it as much as possible. How can i do this? If I use UILabel , the space will be inserted around the glyph. Here are examples showing two labels, both with the same font, but with different characters. Jewish numbers seem shorter than Arabic numbers. Is there a way to determine the size of the glyphs or somehow display the glyphs according to the box?

enter image description here enter image description here

As you can see, the Hebrew figure is shorter, although it is added to the higher UILabel.

Edit: after posting, I made the first pass using the main text to find out if this could solve my problem. This does not seem to happen. See These illustrations comparing the Hebrew symbol with the Arabic numeral symbol. They are yellow - these are the borders of the labels. Green is the rectangle of the glyph indicated by the body text. I was hoping to get a rectangle on a glyph, but it seems like Hebrew glyphs include a space above and next to what I expected to be a glyph. Is there anything else I should check? Hebrew digit Arabic numeral

0
ios fonts uilabel glyph
source share
1 answer

I don't know if you are using Obj-C or Swift, but you can paste this into the Swift Playground page to see the result:

Minor changes

 import UIKit import CoreText import PlaygroundSupport class PathView: UIView { var myPath: UIBezierPath? override func draw(_ rect: CGRect) { if let pth = myPath { UIColor.red.setStroke() // glyph path is inverted, so flip vertically let flipY = CGAffineTransform(scaleX: 1, y: -1.0) // glyph path may be offset on the x coord, and by the height (because it flipped) let translate = CGAffineTransform(translationX: -pth.bounds.origin.x, y: pth.bounds.size.height + pth.bounds.origin.y) // apply the transforms pth.apply(flipY) pth.apply(translate) // stroke the path pth.stroke() // print the modified path for debug / reference print(pth) } } } class TestViewController : UIViewController { override func viewDidLoad() { super.viewDidLoad() // blue background so we can see framing view.backgroundColor = UIColor(red: 0.25, green: 0.5, blue: 01.0, alpha: 1.0) // use a large font so we can see it easily let font = UIFont(name: "Times", size: 160)! // Hebrew character for 8 var unichars = [UniChar]("ח".utf16) unichars = [UniChar]("י".utf16) // init glyphs array var glyphs = [CGGlyph](repeatElement(0, count: unichars.count)) let gotGlyphs = CTFontGetGlyphsForCharacters(font, &unichars, &glyphs, unichars.count) if gotGlyphs { // get the cgPath for the character let cgpath = CTFontCreatePathForGlyph(font, glyphs[0], nil)! // convert it to a UIBezierPath let path = UIBezierPath(cgPath: cgpath) var r = path.bounds // let show it at 40,40 r = r.offsetBy(dx: 40.0, dy: 40.0) let pView = PathView(frame: r) pView.backgroundColor = .white pView.myPath = path view.addSubview(pView) // print bounds and path data for debug / reference print("bounds of path:", path.bounds) print() print(path) print() } } } let vc = TestViewController() PlaygroundPage.current.liveView = vc 

It takes a lot of error checking / handling, but this can be a good start to finding and using the boundaries of the actual glyphs of characters (instead of label frames).

Result:

enter image description here enter image description here

+1
source share

All Articles