obtaining the glyphs for characters that aren't letters

Discussion in 'Mac Programming' started by Chirone, May 19, 2009.

  1. macrumors 6502

    Joined:
    Mar 2, 2009
    Location:
    NZ
    #1
    so i found out a nice way to get the width of strings, and taht is to obtain a glyph which can then be used to obtain a rectangle which can then be used to obtain the width

    seems pretty silly to have to go through all that, but then there is no getTheWidthOfThisStringInPixels:WithThisFont: method

    so i found out that glyphs can't recognize non letter characters... like 'space', numbers, quotes, and other punctuation

    if i have an entire string how can i loop through all the letters and identify when i've come across a non-letter so i can then get the glyph for it.

    what i have is
    Code:
    if([word length] > 0) {
    		for(unsigned int i = 0; i < [word length]; i++){
    			NSGlyph gly = [aFont glyphWithName: [NSString stringWithFormat: @"%C", [word characterAtIndex: i]]];
    			if(gly) {
    				// do stuff
    			}
    		}
    	}
    
    i saw "+" is coded as "plus" to get the glyph... so what's everything else and how do determine when i have something that isn't a letter?

    i am also working under the assumption that glyphs will help me in this same manner if the language uses a non roman alphabet
     
  2. macrumors 68030

    Catfish_Man

    Joined:
    Sep 13, 2001
    Location:
    Portland, OR
    #2
    It seems like that wouldn't take into account kerning, etc... have you tried making an NSAttributedString with your font and such and getting the width of that?
     
  3. macrumors 6502a

    Joined:
    May 10, 2009
    Location:
    Des Moines, WA
    #3
    Long time C/C++ programmer so excuse my attempt at Objective-C but the following should get the idea across.

    Code:
    -(void)drawString:(NSString*)message withFontname:(NSString*)fontname atSize:(CGFloat)pointSize
    {
    	NSFont*	font = nil;
    	NSMutableString* str = nil;
    	NSMutableAttributedString*	astr = nil;
    	NSTextView* view = nil;
    	NSBezierPath* bezier = nil;
    	NSRect bounds;
    
    
    	font = [NSFont fontWithName:fontname size:pointSize];
    	if ( !font ) return;
    	
    	str = [NSMutableString stringWithCapacity:0];
    	[str appendString:message];
    	
    	astr = [[[NSMutableAttributedString alloc] initWithString:str] autorelease];
    	[astr addAttribute:NSFontAttributeName value:font range:NSMakeRange(0, [astr length])];
    	
    	view = [[[NSTextView alloc] initWithFrame:NSMakeRect(0, 0, 0, 0)] autorelease];
    	if ( view )
    	{
    		[[view textStorage] appendAttributedString:astr];
    		
    		bezier = [NSBezierPath bezierPath];
    		if ( bezier )
    		{
    			[bezier moveToPoint:NSMakePoint( 0, 0 )];
    			
    			for ( unsigned int i = 0; hasGlyph; i++ )
    			{
    				NSGlyph glyph = [[view layoutManager] glyphAtIndex:i isValidIndex:&hasGlyph];
    				if ( hasGlyph == YES )
    				{
    					[bezier appendBezierPathWithGlyph:glyph inFont:font];
    				}
    			}
    			
    			bounds = [bezier bounds];
    
    			/* Your draw code here ...
    			 drawBezier(bezier);
    			 */
    		}
    	}
    }
    
     
  4. thread starter macrumors 6502

    Joined:
    Mar 2, 2009
    Location:
    NZ
    #4
    catfishMan: yeah, i'm not sure how to go about that with attributed string but lloyddean's post looks helpful

    lloyddean, i will try your solution, thanks for all that help :cool:

    edit: thanks lloyddean! the code worked wonders! and i get what you're doing too, which is great!
     
  5. macrumors 68030

    Catfish_Man

    Joined:
    Sep 13, 2001
    Location:
    Portland, OR
    #5
    My suggestion would look something like this:

    Code:
    NSDictionary *attributes = [NSDictionary dictionaryWithObjectsAndKeys:[NSFont fontWithName:fontName size:fontSize], NSFontAttributeName, nil];
    NSAttributedString *attString = [[NSAttributedString alloc] initWithString:message attributes:attributes];
    NSSize drawnFontSize = [attString size];
    
    Rather a lot simpler, and I suspect much faster as well since it uses CoreText for text measurement under the hood instead of doing it manually. NSAttributedString also has simple methods to draw the string in a rect, or at a point.
     
  6. thread starter macrumors 6502

    Joined:
    Mar 2, 2009
    Location:
    NZ
    #6
    ah thanks catfish, that's a heck of a lot more accurate than the other solution (sorry lloyddean)
    it looks so simple to
    :cool:
     
  7. macrumors 6502a

    Joined:
    May 10, 2009
    Location:
    Des Moines, WA
    #7
    No problem - don't be sorry.

    I was doing research into grabbing glyphs as beziers from fonts
    for use in some games I'm working on. The code you presented
    looked like you were interested in something along the same line
    and I presented it in that light.

    I've found a unicode symbol font with some useful glyphs for doing
    board style games (the font has a very liberal license allowing
    for such use) but couldn't use the whole font and had written
    something to pull the glyphs I was interested in to individual
    files for inclusion in my projects.

    The resulting bezier can be manipulated in may interesting ways
    before rendering.

    Keep that in mind and you may yet find the snippet useful!

    Good luck!
     

Share This Page