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
|
|
|
|
|