Author Topic: Large Text News Ticker Scroll Without Using Fonts  (Read 2355 times)

0 Members and 1 Guest are viewing this topic.

Offline SierraKen

  • Forum Resident
  • Posts: 1454
Large Text News Ticker Scroll Without Using Fonts
« on: July 19, 2020, 11:52:52 pm »
Today I learned RotoZoom so I tried it with text and you can do the same thing with text as with graphics. :) So I made a large text news ticker scroll without using any fonts. It  is a bit tricky with RotoZoom in that I had to experiment with X and Y to get it to be on the screen. I think since RotoZoom uses the center point of the picture (text window in this case), you have to deal with that. For example, I can't figure out how to make the window smaller for some reason. RotoZoom puts it out of reach if I make the window any smaller vertically. Anyways, enjoy :).

Code: QB64: [Select]
  1. DIM t$(7)
  2. SCREEN _NEWIMAGE(800, 600, 32)
  3.  
  4. t$(1) = "Hello QB64!"
  5. t$(2) = "Weather..."
  6. t$(3) = "Hot as a frying pan!..."
  7. t$(4) = "Remember this?...."
  8. t$(5) = "10 PRINT 'HELLO WORLD'"
  9. t$(6) = "20 GOTO 10"
  10. t$(7) = "And thus a programmer was born!"
  11. t = 1
  12. start:
  13. IF t > 7 THEN t = 1
  14. _PRINTSTRING (500, 250), t$(t)
  15.  
  16. IF i& <> 0 THEN _FREEIMAGE i&
  17. i& = _COPYIMAGE(0)
  18.  
  19. x = 500
  20.     x = x - 1
  21.     IF x < -2000 THEN x = 500: t = t + 1: GOTO start:
  22.     RotoZoom x, 250, i&, 5, 0 'Angle
  23.     _DISPLAY
  24.     CLS
  25.  
  26.  
  27. SUB RotoZoom (X AS LONG, Y AS LONG, Image AS LONG, Scale AS SINGLE, Rotation AS SINGLE)
  28.     DIM px(3) AS SINGLE: DIM py(3) AS SINGLE
  29.     W& = _WIDTH(Image&): H& = _HEIGHT(Image&)
  30.     px(0) = -W& / 2: py(0) = -H& / 2: px(1) = -W& / 2: py(1) = H& / 2
  31.     px(2) = W& / 2: py(2) = H& / 2: px(3) = W& / 2: py(3) = -H& / 2
  32.     sinr! = SIN(-Rotation / 57.2957795131): cosr! = COS(-Rotation / 57.2957795131)
  33.     FOR i& = 0 TO 3
  34.         x2& = (px(i&) * cosr! + sinr! * py(i&)) * Scale + X: y2& = (py(i&) * cosr! - px(i&) * sinr!) * Scale + Y
  35.         px(i&) = x2&: py(i&) = y2&
  36.     NEXT
  37.     _MAPTRIANGLE (0, 0)-(0, H& - 1)-(W& - 1, H& - 1), Image& TO(px(0), py(0))-(px(1), py(1))-(px(2), py(2))
  38.     _MAPTRIANGLE (0, 0)-(W& - 1, 0)-(W& - 1, H& - 1), Image& TO(px(0), py(0))-(px(3), py(3))-(px(2), py(2))
  39.  
« Last Edit: July 20, 2020, 12:34:25 am by SierraKen »

Offline SierraKen

  • Forum Resident
  • Posts: 1454
Re: Large Text News Ticker Scroll Without Using Fonts
« Reply #1 on: July 19, 2020, 11:58:26 pm »
Note: If you quickly got this code within a minute of me first posting it, please get the updated code above. I added a _FREEIMAGE command on Line 16 to reduce the memory usage. I don't want anyone to get memory problems.

Offline Ashish

  • Forum Resident
  • Posts: 630
  • Never Give Up!
Re: Large Text News Ticker Scroll Without Using Fonts
« Reply #2 on: July 20, 2020, 12:21:12 am »
Nice!
and yes, I think you mean "frying pan" not "fying pan"
if (Me.success) {Me.improve()} else {Me.tryAgain()}


My Projects - https://github.com/AshishKingdom?tab=repositories
OpenGL tutorials - https://ashishkingdom.github.io/OpenGL-Tutorials

Offline johnno56

  • Forum Resident
  • Posts: 1270
  • Live long and prosper.
Re: Large Text News Ticker Scroll Without Using Fonts
« Reply #3 on: July 20, 2020, 12:31:25 am »
Cool... also, it could have been 'flying'...
Logic is the beginning of wisdom.

Offline SierraKen

  • Forum Resident
  • Posts: 1454
Re: Large Text News Ticker Scroll Without Using Fonts
« Reply #4 on: July 20, 2020, 12:35:01 am »
LOL thanks guys. :) My blurry vision tonight missed that one. I just fixed it... FRYING Pan. lol

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
Re: Large Text News Ticker Scroll Without Using Fonts
« Reply #5 on: July 20, 2020, 12:36:39 am »
Code: QB64: [Select]
  1. _TITLE "Scale and rotate (default font) text strings." 'B+ started 2019-03-17
  2.  
  3. ' The following CONSTants or TYPES are for the demo and NOT needed for the 2 main subs
  4.  
  5. CONST xmax = 1200
  6. CONST ymax = 700
  7. CONST x0 = 600
  8. CONST y0 = 350
  9. CONST radius = 240
  10. CONST r2 = 20
  11.  
  12. TYPE vectorType
  13.     x AS SINGLE
  14.     y AS SINGLE
  15.  
  16. SCREEN _NEWIMAGE(xmax, ymax, 32)
  17. _SCREENMOVE 100, 40
  18.  
  19.  
  20. a = 1: dir = 1: dir2 = 1
  21. ca = _PI(2 / 20)
  22. DIM vdigit(0 TO 19) AS vectorType
  23. DIM outer(0 TO 19) AS vectorType
  24. FOR i = 0 TO 19
  25.     vdigit(i).x = x0 + radius * COS(ca * i - 4.5 * ca)
  26.     vdigit(i).y = y0 + radius * SIN(ca * i - 4.5 * ca)
  27. t$ = "Scale and rotate text strings"
  28. WHILE _KEYDOWN(27) = 0
  29.     CLS
  30.  
  31.     'this demos putting double sized numbers around a circle angled so the circle is the bottom of number
  32.     CIRCLE (x0, y0), radius
  33.     FOR i = 0 TO 19
  34.         CIRCLE (vdigit(i).x, vdigit(i).y), 2
  35.         x = x0 + (radius + 18) * COS(ca * i - 4.5 * ca)
  36.         y = y0 + (radius + 18) * SIN(ca * i - 4.5 * ca)
  37.         drwString LTRIM$(STR$(i)), &HFFFFFFFF, x, y, 2, 2, ca * i - 4.5 * ca + _PI(.5)
  38.     NEXT
  39.  
  40.     'this demos stretching and shrinking the xScale while the text string is turned + and - Pi/2 or 90 degrees
  41.     'left side red
  42.     drwString t$, &HFF552200, 300, ymax / 2, 50 * ABS(rot), 3, _PI(-.5)
  43.     'right side green
  44.     drwString t$, &HFF004400, xmax - 300, ymax / 2, 50 * ABS(rot), 3, _PI(.5)
  45.  
  46.     'this demos rotaing a text string about the x axis at 3 times default font scale, rot range -1 to 1
  47.     drwString t$, &HFF0000FF, xmax / 2, 32, 3, 3 * rot, 0
  48.  
  49.     'this demos rotaing a text string about the y axis at 3 times default font scale, rot range -1 to 1
  50.     drwString t$, &HFF00FF00, xmax / 2, ymax - 32, 3 * rot, 3, 0
  51.  
  52.     'this demos rotating a text string from 0 to 2 Pi radians and reverse 0 to -2 Pi
  53.     'and shrinking both the xScale and yScale at same time and amount
  54.     drwString t$, &HFFFF0000, xmax / 2, ymax / 2, ABS(rot) * 4, ABS(rot) * 4, a
  55.  
  56.     rot = rot + .1 * dir
  57.     IF rot > 1 THEN dir = -dir: rot = .9
  58.     IF rot < -1 THEN dir = -dir: rot = -.9
  59.     a = a + _PI(1 / 45) * dir2
  60.     IF a > _PI(2) THEN dir2 = -dir2: a = _PI(2)
  61.     IF a < _PI(-2) THEN dir2 = -dir2: a = _PI(-2)
  62.  
  63.     _DISPLAY
  64.     _LIMIT 10
  65.  
  66. 'drwString needs sub RotoZoom2, intended for graphics screens using the default font.
  67. 'S$ is the string to display
  68. 'c is the color (will have a transparent background)
  69. 'midX and midY is the center of where you want to display the string
  70. 'xScale would multiply 8 pixel width of default font
  71. 'yScale would multiply the 16 pixel height of the default font
  72. 'Rotation is in Radian units, use _D2R to convert Degree units to Radian units
  73. SUB drwString (S$, c AS _UNSIGNED LONG, midX, midY, xScale, yScale, Rotation)
  74.     I& = _NEWIMAGE(8 * LEN(S$), 16, 32)
  75.     _DEST I&
  76.     COLOR c, _RGBA32(0, 0, 0, 0)
  77.     _PRINTSTRING (0, 0), S$
  78.     _DEST 0
  79.     RotoZoom2 midX, midY, I&, xScale, yScale, Rotation
  80.     _FREEIMAGE I&
  81.  
  82. 'This sub gives really nice control over displaying an Image.
  83. SUB RotoZoom2 (centerX AS LONG, centerY AS LONG, Image AS LONG, xScale AS SINGLE, yScale AS SINGLE, Rotation AS SINGLE)
  84.     DIM px(3) AS SINGLE: DIM py(3) AS SINGLE
  85.     W& = _WIDTH(Image&): H& = _HEIGHT(Image&)
  86.     px(0) = -W& / 2: py(0) = -H& / 2: px(1) = -W& / 2: py(1) = H& / 2
  87.     px(2) = W& / 2: py(2) = H& / 2: px(3) = W& / 2: py(3) = -H& / 2
  88.     sinr! = SIN(-Rotation): cosr! = COS(-Rotation)
  89.     FOR i& = 0 TO 3
  90.         x2& = (px(i&) * cosr! + sinr! * py(i&)) * xScale + centerX: y2& = (py(i&) * cosr! - px(i&) * sinr!) * yScale + centerY
  91.         px(i&) = x2&: py(i&) = y2&
  92.     NEXT
  93.     _MAPTRIANGLE (0, 0)-(0, H& - 1)-(W& - 1, H& - 1), Image& TO(px(0), py(0))-(px(1), py(1))-(px(2), py(2))
  94.     _MAPTRIANGLE (0, 0)-(W& - 1, 0)-(W& - 1, H& - 1), Image& TO(px(0), py(0))-(px(3), py(3))-(px(2), py(2))
  95.  
  96.  

Offline Ashish

  • Forum Resident
  • Posts: 630
  • Never Give Up!
Re: Large Text News Ticker Scroll Without Using Fonts
« Reply #6 on: July 20, 2020, 12:38:20 am »
@bplus
amazing as always. :)
if (Me.success) {Me.improve()} else {Me.tryAgain()}


My Projects - https://github.com/AshishKingdom?tab=repositories
OpenGL tutorials - https://ashishkingdom.github.io/OpenGL-Tutorials

Offline SierraKen

  • Forum Resident
  • Posts: 1454
Re: Large Text News Ticker Scroll Without Using Fonts
« Reply #7 on: July 20, 2020, 12:27:20 pm »
That's awesome B+. I didn't know we could use both X and Y Zoom.

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
Re: Large Text News Ticker Scroll Without Using Fonts
« Reply #8 on: July 20, 2020, 12:37:09 pm »
That's awesome B+. I didn't know we could use both X and Y Zoom.

My variation on the Wiki posted in Samples > Graphics
https://www.qb64.org/forum/index.php?topic=2313.msg115354#msg115354

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • Steve’s QB64 Archive Forum
Re: Large Text News Ticker Scroll Without Using Fonts
« Reply #9 on: July 20, 2020, 01:00:52 pm »
I tend to use several little routines, which I keep in my text library, to accomplish these goals.

Code: QB64: [Select]
  1. SCREEN _NEWIMAGE(640, 640, 32)
  2. FOR i = 1 TO 4
  3.     Hello(i) = TextToImage("Hello World", 16, Red, 0, i)
  4. 'Mode 1 is print forwards
  5. 'Mode 2 is print backwards
  6. 'Mode 3 is print from top to bottom
  7. 'Mode 4 is print from bottom up
  8. 'Mode 0 got lost somewhere, but it's OK.  We check to see if our mode is < 1 or > 4 and compensate automatically if it is to make it one (default).
  9.  
  10.  
  11. PRINT "First, a demo of simple positioning and letter manipulation"
  12. FOR i = 1 TO 3
  13.     PRINT ".";
  14.     SLEEP 1
  15.  
  16. DisplayImage Hello(1), 320, 320, 0, 1
  17. DisplayImage Hello(2), 320, 320, 0, 3
  18. DisplayImage Hello(3), 320, 320 + _FONTHEIGHT, 0, 2
  19. DisplayImage Hello(4), 320, 320, 0, 1
  20.  
  21. PRINT "Press <ANY KEY> to continue."
  22.  
  23.  
  24.  
  25.  
  26. _DELAY .25
  27. i = 0.5
  28.     _KEYCLEAR
  29.     CLS
  30.     PRINT "A Demo of how to make text wider."
  31.     i = i + .01: IF i > 5 THEN i = 0.5
  32.     scaled = ScaleImage(Hello(1), i, 1)
  33.     DisplayImage scaled, 320, 320, 0, 0
  34.     _FREEIMAGE scaled
  35.     _LIMIT 100
  36.     _DISPLAY
  37.  
  38. _DELAY .25
  39. i = 0.5
  40.     _KEYCLEAR
  41.     CLS
  42.     PRINT "A Demo of how to make text taller."
  43.     i = i + .01: IF i > 5 THEN i = 0.5
  44.     scaled = ScaleImage(Hello(1), 1, i)
  45.     DisplayImage scaled, 320, 320, 0, 0
  46.     _FREEIMAGE scaled
  47.     _LIMIT 100
  48.     _DISPLAY
  49.  
  50. _DELAY .25
  51. i = 0
  52.     _KEYCLEAR
  53.     CLS
  54.     PRINT "A Demo of how to rotate text."
  55.     i = i + 1: IF i > 359 THEN i = 0
  56.     scaled = ScaleImage(Hello(1), 4, 4)
  57.     DisplayImage scaled, 320, 320, i, 0
  58.     _FREEIMAGE scaled
  59.     _LIMIT 100
  60.     _DISPLAY
  61.  
  62.  
  63.  
  64.  
  65. SUB DisplayImage (Image AS LONG, x AS INTEGER, y AS INTEGER, angle AS SINGLE, mode AS _BYTE)
  66.     'Image is the image handle which we use to reference our image.
  67.     'x,y is the X/Y coordinates where we want the image to be at on the screen.
  68.     'angle is the angle which we wish to rotate the image.
  69.     'mode determines HOW we place the image at point X,Y.
  70.     'Mode 0 we center the image at point X,Y
  71.     'Mode 1 we place the Top Left corner of oour image at point X,Y
  72.     'Mode 2 is Bottom Left
  73.     'Mode 3 is Top Right
  74.     'Mode 4 is Bottom Right
  75.  
  76.  
  77.     DIM px(3) AS INTEGER, py(3) AS INTEGER, w AS INTEGER, h AS INTEGER
  78.     DIM sinr AS SINGLE, cosr AS SINGLE, i AS _BYTE
  79.     w = _WIDTH(Image): h = _HEIGHT(Image)
  80.     SELECT CASE mode
  81.         CASE 0 'center
  82.             px(0) = -w \ 2: py(0) = -h \ 2: px(3) = w \ 2: py(3) = -h \ 2
  83.             px(1) = -w \ 2: py(1) = h \ 2: px(2) = w \ 2: py(2) = h \ 2
  84.         CASE 1 'top left
  85.             px(0) = 0: py(0) = 0: px(3) = w: py(3) = 0
  86.             px(1) = 0: py(1) = h: px(2) = w: py(2) = h
  87.         CASE 2 'bottom left
  88.             px(0) = 0: py(0) = -h: px(3) = w: py(3) = -h
  89.             px(1) = 0: py(1) = 0: px(2) = w: py(2) = 0
  90.         CASE 3 'top right
  91.             px(0) = -w: py(0) = 0: px(3) = 0: py(3) = 0
  92.             px(1) = -w: py(1) = h: px(2) = 0: py(2) = h
  93.         CASE 4 'bottom right
  94.             px(0) = -w: py(0) = -h: px(3) = 0: py(3) = -h
  95.             px(1) = -w: py(1) = 0: px(2) = 0: py(2) = 0
  96.     END SELECT
  97.     sinr = SIN(angle / 57.2957795131): cosr = COS(angle / 57.2957795131)
  98.     FOR i = 0 TO 3
  99.         x2 = (px(i) * cosr + sinr * py(i)) + x: y2 = (py(i) * cosr - px(i) * sinr) + y
  100.         px(i) = x2: py(i) = y2
  101.     NEXT
  102.     _MAPTRIANGLE (0, 0)-(0, h - 1)-(w - 1, h - 1), Image TO(px(0), py(0))-(px(1), py(1))-(px(2), py(2))
  103.     _MAPTRIANGLE (0, 0)-(w - 1, 0)-(w - 1, h - 1), Image TO(px(0), py(0))-(px(3), py(3))-(px(2), py(2))
  104.  
  105. SUB CircleFill (CX AS INTEGER, CY AS INTEGER, R AS INTEGER, C AS _UNSIGNED LONG)
  106.     ' CX = center x coordinate
  107.     ' CY = center y coordinate
  108.     '  R = radius
  109.     '  C = fill color
  110.     DIM Radius AS INTEGER, RadiusError AS INTEGER
  111.     DIM X AS INTEGER, Y AS INTEGER
  112.     Radius = ABS(R)
  113.     RadiusError = -Radius
  114.     X = Radius
  115.     Y = 0
  116.     IF Radius = 0 THEN PSET (CX, CY), C: EXIT SUB
  117.     LINE (CX - X, CY)-(CX + X, CY), C, BF
  118.     WHILE X > Y
  119.         RadiusError = RadiusError + Y * 2 + 1
  120.         IF RadiusError >= 0 THEN
  121.             IF X <> Y + 1 THEN
  122.                 LINE (CX - Y, CY - X)-(CX + Y, CY - X), C, BF
  123.                 LINE (CX - Y, CY + X)-(CX + Y, CY + X), C, BF
  124.             END IF
  125.             X = X - 1
  126.             RadiusError = RadiusError - X * 2
  127.         END IF
  128.         Y = Y + 1
  129.         LINE (CX - X, CY - Y)-(CX + X, CY - Y), C, BF
  130.         LINE (CX - X, CY + Y)-(CX + X, CY + Y), C, BF
  131.     WEND
  132.  
  133. FUNCTION ScaleImage (Image AS LONG, xscale AS SINGLE, yscale AS SINGLE)
  134.     w = _WIDTH(Image): h = _HEIGHT(Image)
  135.     w2 = w * xscale: h2 = h * yscale
  136.     NewImage& = _NEWIMAGE(w2, h2, 32)
  137.     _PUTIMAGE (0, 0)-(w2 - 1, h2 - 1), Image&, NewImage&, (0, 0)-(w - 1, h - 1)
  138.     ScaleImage = NewImage&
  139.  
  140.  
  141. FUNCTION TextToImage& (text$, font&, fc&, bfc&, mode AS _BYTE)
  142.     'text$ is the text that we wish to transform into an image.
  143.     'font& is the handle of the font we want to use.
  144.     'fc& is the color of the font we want to use.
  145.     'bfc& is the background color of the font.
  146.  
  147.     'Mode 1 is print forwards
  148.     'Mode 2 is print backwards
  149.     'Mode 3 is print from top to bottom
  150.     'Mode 4 is print from bottom up
  151.     'Mode 0 got lost somewhere, but it's OK.  We check to see if our mode is < 1 or > 4 and compensate automatically if it is to make it one (default).
  152.  
  153.     IF mode < 1 OR mode > 4 THEN mode = 1
  154.     dc& = _DEFAULTCOLOR: bgc& = _BACKGROUNDCOLOR
  155.     D = _DEST
  156.     F = _FONT
  157.     IF font& <> 0 THEN _FONT font&
  158.     IF mode < 3 THEN
  159.         'print the text lengthwise
  160.         w& = _PRINTWIDTH(text$): h& = _FONTHEIGHT
  161.     ELSE
  162.         'print the text vertically
  163.         FOR i = 1 TO LEN(text$)
  164.             IF w& < _PRINTWIDTH(MID$(text$, i, 1)) THEN w& = _PRINTWIDTH(MID$(text$, i, 1))
  165.         NEXT
  166.         h& = _FONTHEIGHT * (LEN(text$))
  167.     END IF
  168.  
  169.     TextToImage& = _NEWIMAGE(w&, h&, 32)
  170.     _DEST TextToImage&
  171.     IF font& <> 0 THEN _FONT font&
  172.     COLOR fc&, bfc&
  173.  
  174.     SELECT CASE mode
  175.         CASE 1
  176.             'Print text forward
  177.             _PRINTSTRING (0, 0), text$
  178.         CASE 2
  179.             'Print text backwards
  180.             temp$ = ""
  181.             FOR i = 0 TO LEN(text$) - 1
  182.                 temp$ = temp$ + MID$(text$, LEN(text$) - i, 1)
  183.             NEXT
  184.             _PRINTSTRING (0, 0), temp$
  185.         CASE 3
  186.             'Print text upwards
  187.             'first lets reverse the text, so it's easy to place
  188.             temp$ = ""
  189.             FOR i = 0 TO LEN(text$) - 1
  190.                 temp$ = temp$ + MID$(text$, LEN(text$) - i, 1)
  191.             NEXT
  192.             'then put it where it belongs
  193.             FOR i = 1 TO LEN(text$)
  194.                 fx = (w& - _PRINTWIDTH(MID$(temp$, i, 1))) / 2 + .99 'This is to center any non-monospaced letters so they look better
  195.                 _PRINTSTRING (fx, _FONTHEIGHT * (i - 1)), MID$(temp$, i, 1)
  196.             NEXT
  197.         CASE 4
  198.             'Print text downwards
  199.             FOR i = 1 TO LEN(text$)
  200.                 fx = (w& - _PRINTWIDTH(MID$(text$, i, 1))) / 2 + .99 'This is to center any non-monospaced letters so they look better
  201.                 _PRINTSTRING (fx, _FONTHEIGHT * (i - 1)), MID$(text$, i, 1)
  202.             NEXT
  203.     END SELECT
  204.     _DEST D
  205.     COLOR dc&, bgc&
  206.     _FONT F
  207.  

TextToImage transforms your text into an image, so then we can manipulate it however we would an image.  It also contains parameter options to print text forwards, backwards, up-to-down, down-to-up, so you can perfectly mirror your text, if you're looking for that effect.  (Such as reading letters reflected in a mirror.)

ScaleImage simply scales any image for us.  Make it taller.  Wider.  Shorter.  Narrower.  Just scale it as you wish.

Displayimage lets you pop that image down wherever you want it, along with several positioning options.  You can rotate it, print it centered at that spot, or position any given corner at the spot specified.

The demo above showcases the basics of usage.  ;)
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
Re: Large Text News Ticker Scroll Without Using Fonts
« Reply #10 on: July 20, 2020, 01:33:23 pm »
I was just saying to myself last night and this morning. I need a better TextImage with a font because blowing up the default font gets raggity as seen in my drawing of Spinner yesterday.

Maybe use a large font for shrinking and expanding with less distortion and blockiness.

Offline SierraKen

  • Forum Resident
  • Posts: 1454
Re: Large Text News Ticker Scroll Without Using Fonts
« Reply #11 on: July 20, 2020, 03:20:32 pm »
Awesome Steve! Thank you.

Since we are doing text manipulation, here is one I put together last year from someone's code in the 90's. You type a word and it changes the texture of the letters on a gray-scale from light to dark. I used the old bmp save code to be able to save the picture if you want to. The original program from the 90's was a wormhole effect with this text in the middle of it. I took just that code out and made this. It was made by someone named Travis Schultz and he put it on comp.lang.basic.misc newsgroup.

Code: QB64: [Select]
  1. 'Code from an old 1990's Internet Newsgroup post.
  2. begin:
  3. PRINT "                    3D Text Maker"
  4. PRINT "     The 3D code is from a program called 'Wormhole' from the 1990's"
  5. PRINT "     by someone named Travis Schultz, which was posted on a BASIC"
  6. PRINT "     programming newsgroup online."
  7. PRINT "     I have added a way to save the text to a BMP picture."
  8. PRINT "     First type in 1 or 2 words, then it will show it on"
  9. PRINT "     a white background. Then if you want to save it,"
  10. PRINT "     press the S key and it will go to the Saving screen."
  11. PRINT "     Press Esc to quit program when seeing the 3d text."
  12. INPUT "     Press enter to begin.", st$
  13. start:
  14. SCREEN _NEWIMAGE(320, 240, 13)
  15. INPUT "     Type here:", a$
  16. _TITLE "Press S to Save."
  17. LOCATE 1, 32
  18. FOR I = 248 TO 420
  19.     FOR j = 0 TO 10
  20.         IF POINT(I, j) > 0 THEN LINE ((I - 196) * 2, j * 2 + 50)-((I - 196) * 2 + 2, j * 2 + 52), 15, BF
  21.     NEXT j
  22.  
  23. FOR I = 100 TO 420
  24.     FOR j = 49 TO 75
  25.         IF POINT(I, j) = 15 THEN GOTO skip2j
  26.         IF POINT(I + 1, j + 1) = 15 THEN PSET (I, j), 50
  27.         IF POINT(I, j + 1) = 15 OR POINT(I + 1, j) = 15 THEN PSET (I, j), 49
  28.         IF POINT(I - 1, j + 1) = 15 OR POINT(I + 1, j - 1) = 15 THEN PSET (I, j), 48
  29.         IF POINT(I, j - 1) = 15 OR POINT(I - 1, j) = 15 THEN PSET (I, j), 47
  30.         IF POINT(I - 1, j - 1) = 15 THEN PSET (I, j), 46
  31.         skip2j:
  32.     NEXT j
  33. FOR I = 100 TO 420
  34.     FOR j = 49 TO 75
  35.         IF POINT(I, j) = 15 THEN PSET (I, j), 32 - (j - 49)
  36.     NEXT j
  37.  
  38. FOR I = 1 TO 5
  39.     n = I * 12
  40.     c = n * 65536 + n * 256 + n
  41.     PALETTE I + 45, c
  42.  
  43. LINE (0, 0)-(320, 10), 15, BF
  44.  
  45. FOR x = 0 TO 640
  46.     FOR y = 0 TO 480
  47.         IF POINT(x, y) <> 0 THEN GOTO nex:
  48.         PSET (x, y), 15
  49.         nex:
  50.     NEXT y
  51. go:
  52. a$ = INKEY$
  53. IF a$ = "s" OR a$ = "S" THEN GOTO saving:
  54. IF a$ <> "" THEN END
  55. GOTO go:
  56.  
  57. saving:
  58.  
  59. 'Now we call up the SUB to save the image to JPG.
  60. SaveImage 0, "temp.bmp"
  61. _DELAY .25
  62. PRINT "            Saving"
  63. PRINT "Your bmp file will be saved in the"
  64. PRINT "same directory as this program is."
  65. PRINT "It can be used with almost any"
  66. PRINT "other graphics program or website."
  67. PRINT "It is saved using:"
  68. PRINT "width: 640  height: 480 pixels."
  69. PRINT "Type a name to save your picture"
  70. PRINT "and press the Enter key. Do not"
  71. PRINT "add .bmp at the end, the program"
  72. PRINT "will do it automatically."
  73. PRINT "Also do not use the name temp"
  74. PRINT "because the program uses that name"
  75. PRINT "and it would be erased the next time"
  76. PRINT "you save a picture."
  77. PRINT "Example: MyPic"
  78. PRINT "Quit and Enter key ends program."
  79. INPUT "->"; nm$
  80. IF nm$ = "Quit" OR nm$ = "quit" OR nm$ = "QUIT" THEN END
  81. nm$ = nm$ + ".bmp"
  82. 'Checking to see if the file already exists on your computer.
  83. theFileExists = _FILEEXISTS(nm$)
  84. IF theFileExists = -1 THEN
  85.     PRINT "File Already Exists"
  86.     PRINT "Saving will delete your old"
  87.     PRINT "jpg picture."
  88.     PRINT "Would you like to still do it?"
  89.     PRINT "(Y/N). Esc ends program."
  90.     llloop:
  91.     _LIMIT 10
  92.     ag2$ = INKEY$
  93.     IF ag2$ = "" THEN GOTO llloop:
  94.     IF ag2$ = "y" OR ag$ = "Y" THEN GOTO saving2:
  95.     IF ag2$ = CHR$(27) THEN END
  96.     GOTO saving:
  97. saving2:
  98. NAME "temp.bmp" AS nm$
  99.  
  100. nm$ = ""
  101. FOR snd = 100 TO 700 STEP 100
  102.     SOUND snd, 2
  103. NEXT snd
  104. GOTO start:
  105.  
  106.  
  107.  
  108. 'Here is the SUB needed to save the image to BMP.
  109. 'It also can be used for BMP pictures on your own program.
  110. SUB SaveImage (image AS LONG, filename AS STRING)
  111.     bytesperpixel& = _PIXELSIZE(image&)
  112.     IF bytesperpixel& = 0 THEN PRINT "Text modes unsupported!": END
  113.     IF bytesperpixel& = 1 THEN bpp& = 8 ELSE bpp& = 24
  114.     x& = _WIDTH(image&)
  115.     y& = _HEIGHT(image&)
  116.     b$ = "BM????QB64????" + MKL$(40) + MKL$(x&) + MKL$(y&) + MKI$(1) + MKI$(bpp&) + MKL$(0) + "????" + STRING$(16, 0) 'partial BMP header info(???? to be filled later)
  117.     IF bytesperpixel& = 1 THEN
  118.         FOR c& = 0 TO 255 ' read BGR color settings from JPG image + 1 byte spacer(CHR$(0))
  119.             cv& = _PALETTECOLOR(c&, image&) ' color attribute to read.
  120.             b$ = b$ + CHR$(_BLUE32(cv&)) + CHR$(_GREEN32(cv&)) + CHR$(_RED32(cv&)) + CHR$(0) 'spacer byte
  121.         NEXT
  122.     END IF
  123.     MID$(b$, 11, 4) = MKL$(LEN(b$)) ' image pixel data offset(BMP header)
  124.     lastsource& = _SOURCE
  125.     _SOURCE image&
  126.     IF ((x& * 3) MOD 4) THEN padder$ = STRING$(4 - ((x& * 3) MOD 4), 0)
  127.     FOR py& = y& - 1 TO 0 STEP -1 ' read JPG image pixel color data
  128.         r$ = ""
  129.         FOR px& = 0 TO x& - 1
  130.             c& = POINT(px&, py&) 'POINT 32 bit values are large LONG values
  131.             IF bytesperpixel& = 1 THEN r$ = r$ + CHR$(c&) ELSE r$ = r$ + LEFT$(MKL$(c&), 3)
  132.         NEXT px&
  133.         d$ = d$ + r$ + padder$
  134.     NEXT py&
  135.     _SOURCE lastsource&
  136.     MID$(b$, 35, 4) = MKL$(LEN(d$)) ' image size(BMP header)
  137.     b$ = b$ + d$ ' total file data bytes to create file
  138.     MID$(b$, 3, 4) = MKL$(LEN(b$)) ' size of data file(BMP header)
  139.     IF LCASE$(RIGHT$(filename$, 4)) <> ".jpg" THEN ext$ = ".jpg"
  140.     f& = FREEFILE
  141.     OPEN filename$ + ext$ FOR OUTPUT AS #f&: CLOSE #f& ' erases an existing file
  142.     OPEN filename$ + ext$ FOR BINARY AS #f&
  143.     PUT #f&, , b$
  144.     CLOSE #f&
  145.  

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
Re: Large Text News Ticker Scroll Without Using Fonts
« Reply #12 on: July 20, 2020, 03:54:07 pm »
And here is my demo of Scale and Rotate Text updated with nicer looking Font:
Code: QB64: [Select]
  1. _TITLE "Scale rotate font text strings." 'B+ restarted  2020-07-20
  2.  
  3. ' The following CONSTants or TYPES are for the demo and NOT needed for the 2 main subs
  4.  
  5. CONST xmax = 1200
  6. CONST ymax = 700
  7. CONST x0 = 600
  8. CONST y0 = 350
  9. CONST radius = 240
  10. CONST r2 = 20
  11. DIM SHARED fv72& ' testing verdanab.ttf
  12. fv72& = _LOADFONT("verdanab.ttf", 72)
  13.  
  14. SCREEN _NEWIMAGE(xmax, ymax, 32)
  15. _DELAY .25
  16. ''test font load
  17. '_FONT fv72&
  18. 'S$ = "helloworld pdq"
  19. 'PRINT S$, _PRINTWIDTH(S$), _FONTHEIGHT(fv72&)
  20. 'LINE (0, 0)-STEP(_PRINTWIDTH(S$), _FONTHEIGHT(fv72&)), , B
  21. 'END
  22.  
  23. a = 1: dir = 1: dir2 = 1: runner = 0
  24. ca = _PI(2 / 20)
  25. t$ = "Scale and rotate text strings"
  26. WHILE _KEYDOWN(27) = 0
  27.     COLOR , _RGB32(runner MOD 255, runner MOD 255, 128)
  28.     CLS
  29.  
  30.     ''this demos stretching and shrinking the xScale while the text string is turned + and - Pi/2 or 90 degrees
  31.     'left side red
  32.     drwString t$, &HFF992200, 300, ymax / 2, 10 * ABS(rot), .5, _PI(-.5)
  33.     ''right side green
  34.     drwString t$, &HFF008800, xmax - 300, ymax / 2, 10 * ABS(rot), .5, _PI(.5)
  35.  
  36.     ''this demos rotaing a text string about the x axis at 3 times default font scale, rot range -1 to 1
  37.     drwString t$, &HFF0000FF, xmax / 2, 32, 1, 1 * rot, 0
  38.  
  39.     ''this demos rotaing a text string about the y axis at 3 times default font scale, rot range -1 to 1
  40.     drwString t$, &HFF00FF00, xmax / 2, ymax - 32, 1 * rot, 1, 0
  41.  
  42.     ''this demos rotating a text string from 0 to 2 Pi radians and reverse 0 to -2 Pi
  43.     ''and shrinking both the xScale and yScale at same time and amount
  44.     drwString t$, &HFFFF0066, xmax / 2, ymax / 2, ABS(rot) * 2, ABS(rot) * 2, a
  45.  
  46.     'this demos moving .5 sized numbers around a circle angled so the circle is the bottom of number
  47.     CIRCLE (x0, y0), radius
  48.     FOR i = 0 TO 19
  49.         x = x0 + (radius + 18) * COS(ca * i - 4.5 * ca)
  50.         y = y0 + (radius + 18) * SIN(ca * i - 4.5 * ca)
  51.         s = (i + runner) MOD 20
  52.         drwString _TRIM$(STR$(s)), &HFFFFFFFF, x, y, .5, .5, ca * i - 4.5 * ca + _PI(.5)
  53.     NEXT
  54.     PRINT "Hello Default Font."
  55.  
  56.     runner = runner + 1
  57.     rot = rot + .025 * dir
  58.     IF rot > 1 THEN dir = -dir: rot = 1
  59.     IF rot < -1 THEN dir = -dir: rot = -1
  60.     a = a + _PI(1 / 45) * dir2
  61.     IF a > _PI(2) THEN dir2 = -dir2: a = _PI(2)
  62.     IF a < _PI(-2) THEN dir2 = -dir2: a = _PI(-2)
  63.  
  64.     _DISPLAY
  65.     _LIMIT 5
  66.  
  67. 'drwString needs sub RotoZoom2, intended for graphics screens using the default font.
  68. 'S$ is the string to display
  69. 'c is the color (will have a transparent background)
  70. 'midX and midY is the center of where you want to display the string
  71. 'xScale would multiply 8 pixel width of default font
  72. 'yScale would multiply the 16 pixel height of the default font
  73. 'Rotation is in Radian units, use _D2R to convert Degree units to Radian units
  74. SUB drwString (S$, c AS _UNSIGNED LONG, midX, midY, xScale, yScale, Rotation)
  75.     storeFont& = _FONT
  76.     storeDest& = _DEST
  77.     _FONT fv72& ' loadfont at start and share handle
  78.     I& = _NEWIMAGE(_PRINTWIDTH(S$), _FONTHEIGHT(fv72&), 32)
  79.     _DEST I&
  80.     _FONT fv72&
  81.     COLOR c, _RGBA32(0, 0, 0, 0)
  82.     _PRINTSTRING (0, 0), S$
  83.     _DEST storeDest&
  84.     RotoZoom2 midX, midY, I&, xScale, yScale, Rotation
  85.     _FREEIMAGE I&
  86.     _FONT storeFont&
  87.  
  88. 'This sub gives really nice control over displaying an Image.
  89. SUB RotoZoom2 (centerX AS LONG, centerY AS LONG, Image AS LONG, xScale AS SINGLE, yScale AS SINGLE, Rotation AS SINGLE)
  90.     DIM px(3) AS SINGLE: DIM py(3) AS SINGLE
  91.     W& = _WIDTH(Image&): H& = _HEIGHT(Image&)
  92.     px(0) = -W& / 2: py(0) = -H& / 2: px(1) = -W& / 2: py(1) = H& / 2
  93.     px(2) = W& / 2: py(2) = H& / 2: px(3) = W& / 2: py(3) = -H& / 2
  94.     sinr! = SIN(-Rotation): cosr! = COS(-Rotation)
  95.     FOR i& = 0 TO 3
  96.         x2& = (px(i&) * cosr! + sinr! * py(i&)) * xScale + centerX: y2& = (py(i&) * cosr! - px(i&) * sinr!) * yScale + centerY
  97.         px(i&) = x2&: py(i&) = y2&
  98.     NEXT
  99.     _MAPTRIANGLE (0, 0)-(0, H& - 1)-(W& - 1, H& - 1), Image& TO(px(0), py(0))-(px(1), py(1))-(px(2), py(2))
  100.     _MAPTRIANGLE (0, 0)-(W& - 1, 0)-(W& - 1, H& - 1), Image& TO(px(0), py(0))-(px(3), py(3))-(px(2), py(2))
  101.  

(zipped with font for your convenience)
* Scale and Rotate Text Demo wFont.zip (Filesize: 129.25 KB, Downloads: 86)
« Last Edit: July 20, 2020, 04:10:36 pm by bplus »

Offline SierraKen

  • Forum Resident
  • Posts: 1454
Re: Large Text News Ticker Scroll Without Using Fonts
« Reply #13 on: July 20, 2020, 04:15:12 pm »
Very nice B+. Much smoother look now.