Graphics.StringHeight and Graphics.StringWidth

Is there a special reason why Graphics.StringHeight accepts WrapWidth but Graphics.StringWidth doesnt?

It just seems a bit weird to me if you wanted to use both to calculate the bounding box of a text block that is about to be drawn using Graphics.DrawString

It also seems weird that StringWidth is

Graphics.StringWidth ( Text as String ) As Double

and not at least

Graphics.StringWidth ( Text as String [,WrapWidth as Integer ] ) As Double

or even better

Graphics.StringWidth ( Text as String [,WrapWidth as Integer ] [,Condense as Boolean ] ) As Double

I can use Graphics.StringHeight to get the bounding box height of a wrapped string, but what can I use to get the width. how can I know the internals of DrawString with a width set?

Graphics.StringWidth just returns the total width of the string as if new lines dont exist.

Anyone know why or am I being dim again?

(trying hard not to reinvent the wheel here)

I really can’t see your problem. You are able to do all that with some line of code…

Yeah of course, you can do anything with a few lines of code but if a framework exists to do XYZ and its doing XYZ behind the scenes why can we only see XY?

I’m just asking if there’s something that I’m missing here.

If I have enough time, I could send you tons of postings with things that I would like to have it.
But there is one fact: It is not there
So you don’t want some help with that? You just want to tell someone that you don’t like it… ok…

<Deletes what I wanted to write because I’m better than that>

No Marius, I’m just asking if I’ve overlooked something, after all, people on here have far more experience with Xojo than me.

Because they dont :stuck_out_tongue:
Never have and I’m not sure if there is, or was, a technical reason they didn’t

I think there may be a feature request to make it so they can but dont know the # off the top of my head

EDIT : As well we’d need to alter the return value to be an array as well in the case it DOES wrap OR return “the maximum” of them all or something since wrapping would make measuring and returning a single width problematic
A change like this would probably break a lot of existing code

In practice, you can measure the height of several lines because they wrapped, but several lines that wrap result in lines of different width. So it would become impossible to return a single result.

Thanks Norman

Uhhh, it would simply be the width of the widest row?

[quote=310876:@JulianS]
Uhhh, it would simply be the width of the widest row?[/quote]
Possible but thats not what it does
Of note there is also no way to know “where did this wrap when you told me the height” (or width in the case is returned the widest)

There’s LOTS of “typesetting” like functionality that would be nice
But graphics is a VERY low level API

Thanks for the insight Norman, I keep forgetting you have to consider x-platform when doing the framework :slight_smile:

Wouldn’t that be simply the width that you specified to StringHeight? I don’t understand your question. StringWidth assumes no wrapping. StringHeight wraps at whatever width you specify. How would it return something else?

There is indeed a TextBlockSize in iOSGraphics that measures the bounds of a wrapped Text block. Unfortunately, that part of the new framework did not make it to desktop or web.

Nevertheless, wrapping is fairly elementary, so it is possible to emulate it.

It seems to cut at the first encountered white space from the right. Or if no space, it cuts when text encounters the wrap.

Then it becomes possible to select a line to obtain its stringwidth.

[quote=310874:@Norman Palardy]EDIT : As well we’d need to alter the return value to be an array as well in the case it DOES wrap OR return “the maximum” of them all or something since wrapping would make measuring and returning a single width problematic
A change like this would probably break a lot of existing code[/quote]

Erm, I dont think so, you just need to return the wrapped width if a wrap width was set, the condensed width if that was set or the total width if no wrap was specified? If you made the new WrapWidth and Condense params optional I cant see why it would break any code. I cant see why you need to return multiple numbers, you can get the height with StringHeight. Dont worry about it though, you’d need to put an alignment option in there also as just returning a left justified graphics object wouldnt be that flexible.

I don’t want it to return something else I wanted StringWidth to return the widest point of the string if it were wrapped.

The problem is thus:

If you have a button what is 100 pixels wide, you specify a WrapWdith of 100 in DrawString and have two words in the string

aaaaaa bbbbbb

Lets say that the 100 is just short of the end of the b’s

______ ____|_ aaaaaa bbbbbb

This would then wrap the text like this

______ ____|_ aaaaaa bbbbbb

Now you’re thinking that you have a nice font that will be 100 wide, so you work out your offsets to put that text in the center of your button, oh dear, its all shifted to the left because there’s massive white space on the right of that 100 wide button where the wrap took place. :frowning:

| ____________________ | | ______ ____|__ | | aaaaaa | | bbbbbb | | ____________________ |

Now you have no way to work out the “actual” width that the text takes up (the bounding box of the text) because you have no feedback from the that what is happening inside of DrawString.

As I said above, its no biggie, I really just asked because I might have been missing something. I’ll get around to sorting this out with my own routine, I just keep getting sidetracked by other stuff at the moment.

Thanks for the input everyone I’ll mark this as answered as to not waste more of peoples time :slight_smile:

I see. It should be fairly straightforward to get the TextHeight at the maximum width and then reduce the width until the height changes. The previous width is the point at which a) you have the maximum, and b) you have the most pleasing wrap, where the lines are mostly filled.

Now is the time for all good
men.

  • vs -

Now is the time
for all good men.

Hehe yeah, but there’s always an edge case where it blows up and looks naff :slight_smile:

Blah blah blah blah blah

would need to be

Blah blah blah blah blah

If you use MBS Plugin on Mac you can use the boundingRectWithSize method:

[code] dim g as NSGraphicsMBS = NSGraphicsMBS.graphicsContext

	// wrap width included here
	dim size as new NSSizeMBS(100, 200)
	
	dim a as new NSAttributedStringMBS
	call a.initWithString("Hello World, this is just a test.")
	
	// calc bounding rectangle
	dim options as integer = g.NSStringDrawingUsesLineFragmentOrigin
	dim bounds as NSRectMBS = g.boundingRectWithSize(a, size, options)
	
	Break[/code]