| 
 
| 
|  Author | Topic: Angled Text  (Read 587 times) |  |  
| 
| 
| KenDown Full Member
 
 
 member is offline
 
  
 
 
 
 
  
 
 Posts: 181
 
 | 
|  | Angled Text « Thread started on: Apr 12th, 2017, 03:14am »
 |  |  I'm not sure where to put this, so if a moderator wants to move it, that's fine.
 
 Someone, somewhere, posted a method of drawing angled text (was it Richard in the Help?) which I have been using for a while, so imagine my horror to discover that it didn't handle non-ASCII text - ie. UTF-8 text. It took me a while to sort it out, but here's the result. (Note, it is a funciton rather than a proc as that fits my program better. It can be easily turned into a proc.)
 
 REM Draws text at the specified angle and colour
 DEFFNangled(font$,height%,weight%,text$,angle,X%,Y%,col%)
 LOCALfont%,oldfont%,L%
 DIMU%LOCAL1024:U%=(U%+1)AND-2
 SYS"CreateFont",height%,0,angle*10,angle*10,weight%,0,0,0,0,0,0,0,0,font$TOfont%
 SYS"SelectObject",@memhdc%,font%TOoldfont%
 SYS"SetTextColor",@memhdc%,&1000000+col%
 SYS"SetBkColor",@memhdc%,&1000000+@vdu%?71
 SYS"SetBkMode",@memhdc%,1
 SYS"MultiByteToWideChar",&FDE9,0,text$,LENtext$,0,0TOL%
 SYS"MultiByteToWideChar",&FDE9,0,text$,LENtext$,U%,L%
 SYS"TextOutW",@memhdc%,X%,Y%,$U%,L%
 SYS"SetBkMode",@memhdc%,2
 SYS"InvalidateRect",@hwnd%,0,0
 SYS"SelectObject",@memhdc%,oldfont%
 SYS"DeleteObject",font%
 =0
 
 Many thanks to whoever posted the original code. I couldn't have done it on my own!
 |  
| 
|  |  Logged |  
 |  |  |  
| 
| 
| hellomike New Member
 
 
 member is offline
 
  
 
 
 
 
  
 Gender:
  Posts: 46
 
 | 
|  | Re: Angled Text « Reply #1 on: Apr 13th, 2017, 07:37am »
 |  |  Hi Ken,
 
 The code indeed crashes. The reason is that you pass $U% to "TextOutW" and not U%.
 This way the SYS looks for the string located at the address that is in the first bytes of U%, not in U% itself.
 
 Hope this helps.
 
 Mike
 |  
| 
|  |  Logged |  
 |  |  |  
| 
| 
| KenDown Full Member
 
 
 member is offline
 
  
 
 
 
 
  
 
 Posts: 181
 
 | 
|  | Re: Angled Text « Reply #2 on: Apr 13th, 2017, 4:21pm »
 |  |  That's an interesting comment, given that it is working perfectly with $U%.
 
 However, following your remarks I removed the $ and somewhat to my surprise it continues to work with U%. Surely, if it wants the address of U% it would require something like ^U%?
 
 
 |  
| 
|  |  Logged |  
 |  |  |  
| 
| 
| hellomike New Member
 
 
 member is offline
 
  
 
 
 
 
  
 Gender:
  Posts: 46
 
 | 
|  | Re: Angled Text « Reply #3 on: Apr 14th, 2017, 09:51am »
 |  |  I was confused because I assumed you started this thread because your code wasn't working.
 And now I'm still confused because the code you posted crashes the interpreter for me, caused by (as far as I can see) using $U% instead of U%.
 
 In the 2nd SYS "MultiByteToWideChar" in your code, you correctly pass the address (stored in U%), pointing to the memory where the wide string is to be placed.
 Following, SYS "TextOutW" needs an address where the wide string can be found in the same manner. So, also U%.
 
 $U% doesn't contain an address. Also note that after the 2nd SYS "MultiByteToWideChar", U% now points to a wide (two bytes per character) string, NOT to a &0D terminated one-byte character string, so $U% will give unpredictable result.
 
 The notation without the '$' in the SYS call is the correct one. See for example the BB4W wiki, article http://bb4w.wikispaces.com/Unicode+filenames.
 
 Using assembly language, I checked what value was passed by using $U% as a SYS parameter. And it is a value in or near the stack, so near the value of HIMEM.
 
 |  
| 
|  |  Logged |  
 |  |  |  
| 
| 
| KenDown Full Member
 
 
 member is offline
 
  
 
 
 
 
  
 
 Posts: 181
 
 | 
|  | Re: Angled Text « Reply #4 on: Apr 14th, 2017, 1:35pm »
 |  |  No, I posted it because a) I was rather pleased with myself for sorting it out without bleating for help, and b) I thought someone else might find it useful.
 
 As it turns out, you have kindly corrected my code, but it is curious that it worked fine for me with $U% but crashes for you. Anyway, I have changed my code to the correct version, so again, thanks.
 |  
| 
|  |  Logged |  
 |  |  |  
| 
| 
| marsFS New Member
 
 
 member is offline
 
  
 
 
 
 
  
 Gender:
  Posts: 6
 
 | 
|  | Re: Angled Text « Reply #5 on: Nov 2nd, 2017, 9:51pm »
 |  |  This is great!
 
 Just thought I'd post the code along with the fix you mentioned and a little demo in case someone needs an example of how to use.
 Code:
 
      MODE 22
      ON ERROR: OSCLI "REFRESH ON":END
      an%=0
      c%=1
      a$="WOW! Rotating text :-)"
      *REFRESH OFF
      REPEAT
  
        an%+=1: IF an%>=360 THEN
          an%=an%-360
          c%+=1: IF c%=16 THEN c%=1
        ENDIF
  
        CLG
        a%=FNangled("Arial",40,2,a$,an%,512,384,c%)
  
        *REFRESH
        WAIT 1
      UNTIL FALSE
      END
      REM Draws text at the specified angle and colour
      DEFFNangled(font$,height%,weight%,text$,angle,X%,Y%,col%)
      LOCALfont%,oldfont%,L%
      DIMU%LOCAL1024:U%=(U%+1)AND-2
      SYS"CreateFont",height%,0,angle*10,angle*10,weight%,0,0,0,0,0,0,0,0,font$TOfont%
      SYS"SelectObject",@memhdc%,font%TOoldfont%
      SYS"SetTextColor",@memhdc%,&1000000+col%
      SYS"SetBkColor",@memhdc%,&1000000+@vdu%?71
      SYS"SetBkMode",@memhdc%,1
      SYS"MultiByteToWideChar",&FDE9,0,text$,LENtext$,0,0TOL%
      SYS"MultiByteToWideChar",&FDE9,0,text$,LENtext$,U%,L%
      SYS"TextOutW",@memhdc%,X%,Y%,U%,L%
      SYS"SetBkMode",@memhdc%,2
      SYS"InvalidateRect",@hwnd%,0,0
      SYS"SelectObject",@memhdc%,oldfont%
      SYS"DeleteObject",font%
      =0
  |  
| 
|  |  Logged |  
 |  |  |  
| 
| 
| KenDown Full Member
 
 
 member is offline
 
  
 
 
 
 
  
 
 Posts: 181
 
 | 
|  | Re: Angled Text « Reply #6 on: Nov 3rd, 2017, 04:35am »
 |  |  Excellent. And it works just as well if you have
 
 a$="Пастор Кендал Даун"
 
 Which of course was the problem all along.
 
 Once again, thanks to all those who helped.
 |  
| 
|  |  Logged |  
 |  |  |  
| 
| 
| KenDown Full Member
 
 
 member is offline
 
  
 
 
 
 
  
 
 Posts: 181
 
 | 
|  | Re: Angled Text « Reply #7 on: Nov 3rd, 2017, 04:39am »
 |  |  All we need now is some clever clogs to come up with a way of rotating around the centre of the line of text and we'll really have something that will knock people's eyes out!
 |  
| 
|  |  Logged |  
 |  |  |  
| 
| 
| KenDown Full Member
 
 
 member is offline
 
  
 
 
 
 
  
 
 Posts: 181
 
 | 
|  | Re: Angled Text « Reply #8 on: Nov 3rd, 2017, 07:28am »
 |  |  The other thing, of course, is that if you want to save a fraction of a second, you can DIM the U% in your intialisation, rather than DIMming it again every time the routine is called. Just leave the LOCAL out of the line and put it elsewhere.
 |  
| 
|  |  Logged |  
 |  |  |  
| 
| 
| DDRM Administrator
 
 
 member is offline
 
  
 
 
 
 
  
 Gender:
  Posts: 321
 
 | 
|  | Re: Angled Text « Reply #9 on: Nov 3rd, 2017, 5:12pm »
 |  |  You mean like this?
 Code:
 
      MODE 22
      ON ERROR: OSCLI "REFRESH ON":END
      an%=0
      c%=1
      a$="WOW! Rotating text :-)"
      w%=FNstringwidth(a$)
      *REFRESH OFF
      REPEAT
  
        an%+=1: IF an%>=360 THEN
          an%=an%-360
          c%+=1: IF c%=16 THEN c%=1
        ENDIF
  
        CLG
        dx%=w%*COSRAD(an%)+@vdu%!220*COSRAD(an%-90)
        dy%=w%*SINRAD(an%)+@vdu%!220*SINRAD(an%-90)
        a%=FNangled("Arial",40,2,a$,an%,512-dx%,384+dy%,c%)
        PLOT 69,1024,768 :REM Centre of rotation, in BB4W graphics units
        *REFRESH
        WAIT 1
      UNTIL FALSE
      END
      REM Draws text at the specified angle and colour
      DEFFNangled(font$,height%,weight%,text$,angle,X%,Y%,col%)
      LOCALfont%,oldfont%,L%
      DIMU%LOCAL1024:U%=(U%+1)AND-2
      SYS"CreateFont",height%,0,angle*10,angle*10,weight%,0,0,0,0,0,0,0,0,font$TOfont%
      SYS"SelectObject",@memhdc%,font%TOoldfont%
      SYS"SetTextColor",@memhdc%,&1000000+col%
      SYS"SetBkColor",@memhdc%,&1000000+@vdu%?71
      SYS"SetBkMode",@memhdc%,1
      SYS"MultiByteToWideChar",&FDE9,0,text$,LENtext$,0,0TOL%
      SYS"MultiByteToWideChar",&FDE9,0,text$,LENtext$,U%,L%
      SYS"TextOutW",@memhdc%,X%,Y%,U%,L%
      SYS"SetBkMode",@memhdc%,2
      SYS"InvalidateRect",@hwnd%,0,0
      SYS"SelectObject",@memhdc%,oldfont%
      SYS"DeleteObject",font%
      =0
      :
      DEF FNstringwidth(a$)
      LOCAL @vdu.m.c&, @vdu.l.x%, @vdu.l.y%, ?444
      VDU 5,23,16,0|30,11,23,16,64|10,10
      PRINT a$;
      @vdu.l.y% = GET(0,0) : REM SDL thread sync.
      = @vdu.l.x%
 The function at the bottom is something of Richard's to find the actual length at which a string will print, in pixels. I've just used it to offset the start point for the string plotting.
 
 It needs an additional small correction to allow for the height of the characters, which is 90 degrees out of phase.
 
 :-)
 
 D
 |  
| 
|  |  Logged |  
 |  |  |  
| 
| 
| KenDown Full Member
 
 
 member is offline
 
  
 
 
 
 
  
 
 Posts: 181
 
 | 
|  | Re: Angled Text « Reply #10 on: Nov 23rd, 2017, 01:25am »
 |  |  Yes, very clever. For some reason it jumps every 90 degrees and I can't work out why. However it is still clever.
 |  
| 
|  |  Logged |  
 |  |  |  
| 
| 
| DDRM Administrator
 
 
 member is offline
 
  
 
 
 
 
  
 Gender:
  Posts: 321
 
 | 
|  | Re: Angled Text « Reply #11 on: Nov 23rd, 2017, 07:56am »
 |  |  Not sure I know why, either. It seems less prominent if you change all the references to an% to an, and then make the start angle 0.1. There's a little bit of wobble going on all the time.
 
 I suspect it's because the possible plot positions are integers, and there is a sudden transition from one to the next which is most noticeable when the line is horizontal or vertical (because the whole line shifts, rather than just some of the pixels making up the characters. I haven't done any maths to test that idea though.
 
 Maybe if you used GDIP (which allows sub-pixel locations) it would be better? Unfortunately, GDIPLib doesn't contain text output functions...
 
 Best wishes,
 
 D
 |  
| 
|  |  Logged |  
 |  |  |  
| 
| 
| KenDown Full Member
 
 
 member is offline
 
  
 
 
 
 
  
 
 Posts: 181
 
 | 
|  | Re: Angled Text « Reply #12 on: Nov 23rd, 2017, 2:00pm »
 |  |  I'm not referring to the slight back-and-forth jiggling which, as you say, is due to the pixel positioning.
 
 Rather the rotating seems to jump every 90 degrees, which it doesn't do (or not that I've noticed) in my routine where the line of text rotated around its start point rather than its middle point. As the two routines use the same mathematics, it's odd.
 |  
| 
|  |  Logged |  
 |  |  |  
| 
| 
| marsFS New Member
 
 
 member is offline
 
  
 
 
 
 
  
 Gender:
  Posts: 6
 
 | 
|  | Re: Angled Text « Reply #13 on: Nov 23rd, 2017, 11:55pm »
 |  |  Seems to be when at 0, 90, 180 and 270 degrees
 
 I added a pixel plot using the same coordinates which doesn't jump around so I can only assume the SYS call is fudging the angle when plotting the angled text.
 
 If it were an issue and knowing that it happens for fixed angles you maybe be able to add an offset to x or y to mask the issue?
 
 
 
 
 
 
 |  
| 
|  |  Logged |  
 |  |  |  
| 
| 
| DDRM Administrator
 
 
 member is offline
 
  
 
 
 
 
  
 Gender:
  Posts: 321
 
 | 
|  | Re: Angled Text « Reply #14 on: Nov 24th, 2017, 5:13pm »
 |  |  I've been playing with this a bit more. It's funny, because at least on my machine it doesn't jump EVERY time, despite all the parameters being integers. I get the impression it gets worse with time, too.
 
 I actually think it might be a rendering conflict. There is a "InvalidateRect" call in the function, AND I've got a *REFRESH which is doing something similar. If I disable the *REFRESH OFF and the *REFRESH it seems to happen less (though the text flickers appallingly).
 
 D
 |  
| 
|  |  Logged |  
 |  |  |  
 |