DrawString Error????

  s="WWWWW"+chr(13)+"a23 b56 c89 d12 e45 f78 g01 g34 i67"
 g.DrawString s,x,y,w,true

This draws “WWWW…” instead of

a23 b56 c8…

which is what I expected.

The width provided is 400, and WWWWW is only 339.7852… So why did it stop?

Because you set Condense to true? Try setting it to false

Condense should have no effect on the first line since it “fits” in the width specified.
and actually the 2nd line should be “a23 b56 c89” since it too is LESS than 400 pixels wide

If I remove a “W”… then it gives the effect I expected.

I am trying to duplicate the “correct” behaviour in my PDF class. and both the native Graphics and my PDF class say this string is 339.7842 pixels wide…

Based on other tests there are 3 behavouirs I have observed (the documentation is not real helpful here)

’ Mode 0 - (wrap=0) Split on EOL, CLIP ALL lines
’ Mode 1 - (wrap>0,True) Split on EOL, Stop after 1st line that is too long
’ Mode 2 - (wrap>0,false) Split on EOL, Wrap Lines - Break on Whitespace

The problem is that XOJO seems to think a line is “too long” based on a percentage of the actual width… not 100% of it

its one long line as far as drawstring is concerned as chr(13) is NOT the right end of line on OS X
Try (I put this in the paint event of a canvas on a window just for quick testing)

dim x as integer=20 dim y as integer =100 dim w as integer =400 dim s as string ="WWWWW"+EndOfLine+"a23 b56 c89 d12 e45 f78 g01 g34 i67" g.textfont="Times" g.TextSize=72 g.DrawString s,x,y,w,false
condense needs to be set to false otherwise you get the ellipsis

Seems it “measures” the string, truncates it at/around the maximum width… the displays whatever is there (honoring linefeeds)

WELLL… I thought that made sense… until I tried this


It displays

Total string width (excluding EOL) is 900

So that DID not measure the who line and NO line exceeded 400…

Chr(13) is NOT the right EOL character on OS X so I think that impacts how it behaves
When you do use the right endofline for the platform it works like you expect :slight_smile:

Actually no it doesn’t… using 0x0A or 0x0D gives same… result.

The code I posted which uses endofline wraps right at the endofline & behaves as I expect
Using chrb(10) or curb(13) makes your string have a NIL encoding and that causes the failure
Using Encodings.UTF8.chr(10) or Encodings.UTF8.chr(13) seems to works just fine

At the risk of repeating myself…

WHY does this not work… And yes Norman I have read your posts… and I still do not have an explanation.

dim x as integer=20
  dim y as integer =100
  dim w as integer =400
  dim s as string ="WWWWW"+EndOfLine+"a23 b56 c89 d12 e45 f78 g01 g34 i67"
  g.DrawString s,x,y,w,TRUE

Why should my expectation of seeing

be wrong?

If I put “aaaaa”+endofline+“WWWWW”
i see

Could you provide what the “RULES” here are supposed to be?

Your compressed setting is true - mine false
The docs are particularly relevant
The Text will wrap if WrapWidth is provided and Condense is False (The default is False). If WrapWidth is omitted, then Text will print on one line, even if the window or RectControl is too narrow to contain the text. If the optional Condense property is True, DrawString truncates the string to fit into the space specified by WrapWidth and uses an ellipsis ("…") to indicate that there is additional text that is not shown. The default values of WrapWidth and Condense are zero and False, respectively. The default behavior is to print the string on one line.

Yes Norman… I have read the documentation… which is what prompted my question in the first place.

So let me ask ONE MORE time. Why does “WWWWW” show with an ellipsis when it is SHORTER than 400 pixels.

Therefore from my point of view… the DOCUMENTATION and observed behaviour do not correspond.

(for the record… I am NOT stupid… I have tried hundreds of test cases, before posting here … and cannot find a common denominator, that indicates at what precise point it will truncate a string, and/or show the ellipsis… And I am taking for only cases where CONDENSE is TRUE)

String width is calculated irrespective of newlines. When you pass condense as True, it condenses the string as if it were one line (I’m not sure what the width of a newline is) and then prints. Embedded newlines will cause the output to “wrap”, but the actual string does not wrap at that point.

In other words, Condense ignores newlines. Each line does NOT start fresh, it’s the cumulative length that condenses.

I understand that is what is supposed to be the case… but as stated before… Observation DOES NOT support that to to be the case

The string “aaaaa” is 159.7852 pixels wide
The string “WWWWW” is 339.7852 pixels wide
leaving out the EOL the sum is 499 …

According to the documentation, and everything everyone has been stating in this thread

This code should

 dim x as integer=20
  dim y as integer =100
  dim w as integer =400
  g.DrawString s,x,y,w,TRUE

Should display

Because the total width of the exceeds 400

but it shows

which kind of makes sense… as the length has exceeded 400 by the time it got to the next EOL… but why didn’t it truncate one of the "W"s and place the ellipis there?

Remove a “W” from the first section

and it displays this

where according to “the rules” should have truncated at 400 pixels

is 430 pixels… why didn’t it stop there? Instead it used 1005 pixels

So somehow the algorithm for CONDENSE is hardly “truncate at string length closest to specified width”

At this point why not just wrap the string yourself? That is what I do.

which seems to be impossible… since the built-in graphics objects don’t follow any rules that can be quantified.

It appears to ignore the end online and treats the string as one long line
What I’m unsure of is if this is a bug or as designed - but it certainly doest seem to be documented as such

I’d actually file a bug report about this
In the mean time wrapping yourself isn’t so hard as you can split on endofline’s and move down by the font height and then draw each section
We do that in a couple spots in the IDE (like the code editor) - it’s one giant text input canvas subclass that draws using drawstring

I have no problem implementing word wrapping… what I do have is a problem determining WHERE so that it emulates what the GRAPHICS object does.

I need to have the output of my class visually match what a graphics object would show given the same code.

Is this a Cocoa thing? Windows seems pretty consistent with the documentation.

Good Question… I will try under Carbon and see if it is different