Author Topic: PPRINT - Prints larger font size using _PUTIMAGE  (Read 1722 times)

0 Members and 1 Guest are viewing this topic.

Offline Dav

  • Forum Resident
  • Posts: 792
PPRINT - Prints larger font size using _PUTIMAGE
« on: January 06, 2021, 11:39:04 am »
I needed a way to make larger screen text than the default one (without using font files) and came up with this method.  Or is there already an easier way to do this?  I don't know.  Also, I need to learn to use _DEST more so I was playing around with it.

It would be more efficient and faster to just do one print and _PUTIMAGE than step through each letter - I will update to that later.

- Dav

Edit: Changed this to output to current output screen instead of DEST 0. 

Code: QB64: [Select]
  1. '==========
  2. 'PPRINT.BAS
  3. '==========
  4. 'Prints larger screen text using _PUTIMAGE.
  5. 'Works in 8-bit and 32-bit screen modes.
  6. 'Coded by Dav, JAN/2021
  7.  
  8.  
  9. '=== Set screen mode, and color
  10. SCREEN _NEWIMAGE(600, 600, 32)
  11.  
  12. CLS , _RGB(32, 32, 32)
  13.  
  14. '=== draw stuff
  15. FOR x = 1 TO 600 STEP 3
  16.     FOR y = 1 TO 600 STEP 3
  17.         PSET (x, y), _RGB(RND * 255, RND * 255, RND * 255)
  18.     NEXT
  19.  
  20. '=== Sample usage
  21. FOR t = 20 TO 500 STEP 30
  22.     t$ = STR$(RND * 1000) 'make some random text
  23.     PPRINT 22, t + 2, 30, _RGB(1, 1, 1), 0, t$ 'give it a shadow
  24.     PPRINT 20, t, 30, _RGB(200, 200, 200), 0, t$
  25.  
  26.  
  27.  
  28. SUB PPRINT (x, y, size, clr&, trans&, text$)
  29.     'This sub outputs to the current _DEST set
  30.     'It makes trans& the transparent color
  31.  
  32.     'x/y is where to print text
  33.     'size is the font size to use
  34.     'clr& is the color of your text
  35.     'trans& is the background transparent color
  36.     'text$ is the string to print
  37.  
  38.     '=== get users current write screen
  39.     orig& = _DEST
  40.  
  41.     '=== if you are using an 8 or 32 bit screen
  42.     bit = 32: IF _PIXELSIZE(0) = 1 THEN bit = 256
  43.  
  44.     '=== step through your text
  45.     FOR t = 0 TO LEN(text$) - 1
  46.         '=== make a temp screen to use
  47.         pprintimg& = _NEWIMAGE(16, 16, bit)
  48.         _DEST pprintimg&
  49.         '=== set colors and print text
  50.         CLS , trans&: COLOR clr&
  51.         PRINT MID$(text$, t + 1, 1);
  52.         '== make background color the transprent one
  53.         _CLEARCOLOR _RGB(0, 0, 0), pprintimg&
  54.         '=== go back to original screen  to output
  55.         _DEST orig&
  56.         '=== set it and forget it
  57.         x1 = x + (t * size): x2 = x1 + size
  58.         y1 = y: y2 = y + size
  59.         _PUTIMAGE (x1 - (size / 2)), y1)-(x2, y2 + (size / 3)), pprintimg&
  60.         _FREEIMAGE pprintimg&
  61.     NEXT
  62.  

 
pprint.jpg
« Last Edit: January 06, 2021, 02:14:55 pm by Dav »

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • Steve’s QB64 Archive Forum
Re: PPRINT - Prints larger font size using _PUTIMAGE
« Reply #1 on: January 06, 2021, 12:13:30 pm »
TextToImage is what I use for these type needs.

Code: QB64: [Select]
  1.  FUNCTION TextToImage& (text$, font&, fc&, bfc&, mode AS _BYTE)
  2.     'text$ is the text that we wish to transform into an image.
  3.     'font& is the handle of the font we want to use.
  4.     'fc& is the color of the font we want to use.
  5.     'bfc& is the background color of the font.
  6.  
  7.     'Mode 1 is print forwards
  8.     'Mode 2 is print backwards
  9.     'Mode 3 is print from top to bottom
  10.     'Mode 4 is print from bottom up
  11.     '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).
  12.  
  13.     IF mode < 1 OR mode > 4 THEN mode = 1
  14.     dc& = _DEFAULTCOLOR: bgc& = _BACKGROUNDCOLOR
  15.     D = _DEST
  16.     F = _FONT
  17.     IF font& <> 0 THEN _FONT font&
  18.     IF mode < 3 THEN
  19.         'print the text lengthwise
  20.         w& = _PRINTWIDTH(text$): h& = _FONTHEIGHT
  21.     ELSE
  22.         'print the text vertically
  23.         FOR i = 1 TO LEN(text$)
  24.             IF w& < _PRINTWIDTH(MID$(text$, i, 1)) THEN w& = _PRINTWIDTH(MID$(text$, i, 1))
  25.         NEXT
  26.         h& = _FONTHEIGHT * (LEN(text$))
  27.     END IF
  28.  
  29.     TextToImage& = _NEWIMAGE(w&, h&, 32)
  30.     _DEST TextToImage&
  31.     IF font& <> 0 THEN _FONT font&
  32.     COLOR fc&, bfc&
  33.  
  34.     SELECT CASE mode
  35.         CASE 1
  36.             'Print text forward
  37.             _PRINTSTRING (0, 0), text$
  38.         CASE 2
  39.             'Print text backwards
  40.             temp$ = ""
  41.             FOR i = 0 TO LEN(text$) - 1
  42.                 temp$ = temp$ + MID$(text$, LEN(text$) - i, 1)
  43.             NEXT
  44.             _PRINTSTRING (0, 0), temp$
  45.         CASE 3
  46.             'Print text upwards
  47.             'first lets reverse the text, so it's easy to place
  48.             temp$ = ""
  49.             FOR i = 0 TO LEN(text$) - 1
  50.                 temp$ = temp$ + MID$(text$, LEN(text$) - i, 1)
  51.             NEXT
  52.             'then put it where it belongs
  53.             FOR i = 1 TO LEN(text$)
  54.                 fx = (w& - _PRINTWIDTH(MID$(temp$, i, 1))) / 2 + .99 'This is to center any non-monospaced letters so they look better
  55.                 _PRINTSTRING (fx, _FONTHEIGHT * (i - 1)), MID$(temp$, i, 1)
  56.             NEXT
  57.         CASE 4
  58.             'Print text downwards
  59.             FOR i = 1 TO LEN(text$)
  60.                 fx = (w& - _PRINTWIDTH(MID$(text$, i, 1))) / 2 + .99 'This is to center any non-monospaced letters so they look better
  61.                 _PRINTSTRING (fx, _FONTHEIGHT * (i - 1)), MID$(text$, i, 1)
  62.             NEXT
  63.     END SELECT
  64.     _DEST D
  65.     COLOR dc&, bgc&
  66.     _FONT F
  67.  

Send it some text and basic information, get back an image handle that you can then manipulate however you want.  Often, I use this in conjuction with ScaleImage and DisplayImage, to generate all sorts of effects.  (Rotating text, tall text, wide text, centered text, mirrored text, ect...)

Do a search for any of them, and you’ll find a ton of programs here on the forums which make use of the three routines in one form or another.  :)

(For default font, just use 16 as your font handle, or 8 if you’re using 8x8 fonts.)
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline Dav

  • Forum Resident
  • Posts: 792
Re: PPRINT - Prints larger font size using _PUTIMAGE
« Reply #2 on: January 06, 2021, 12:44:21 pm »
That's pretty slick, Steve!  Sure blows mine away.  I'll be using it...

- Dav


Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • Steve’s QB64 Archive Forum
Re: PPRINT - Prints larger font size using _PUTIMAGE
« Reply #3 on: January 06, 2021, 01:29:17 pm »
A quick demo of the 3 routines working together to produce various effects for us:

Code: QB64: [Select]
  1. DIM TI(4) AS LONG
  2.  
  3. SCREEN _NEWIMAGE(800, 600, 32)
  4. FOR i = 1 TO 4
  5.     TI(i) = TextToImage("Here's some text for you.", 16, &HFFFF0000, 0, i)
  6.     'print forward, backward, up to down, down to up
  7. DisplayImage TI(1), 100, 100, 0, 1
  8. DisplayImage TI(2), 100, 510, 0, 1
  9. DisplayImage TI(3), 100, 110, 0, 1
  10. DisplayImage TI(4), 300, 110, 0, 1
  11.  
  12. a$ = INPUT$(1)
  13.  
  14. 'And now to scale these fonts
  15.  
  16. Scaled1 = ScaleImage(TI(1), 2, 2) 'double width, double height
  17. DisplayImage Scaled1, 100, 100, 0, 1
  18. Scaled2 = ScaleImage(TI(1), 2, 1) 'double width, normal height
  19. DisplayImage Scaled2, 100, 150, 0, 1
  20. Scaled3 = ScaleImage(TI(1), 1, 2) 'normal width, double height
  21. DisplayImage Scaled3, 100, 200, 0, 1
  22. Scaled4 = ScaleImage(TI(1), 1.5, 1.5) '1.5 times as  wide, 1.5 times as high
  23. DisplayImage Scaled4, 100, 250, -45, 1 'rotated at -45 degrees
  24.  
  25. a$ = INPUT$(1)
  26.     _LIMIT 60
  27.     CLS
  28.     DisplayImage Scaled4, 400, 300, angle, 0 'and just to show how we can rotate with the displayimage routine
  29.     angle = angle - 3
  30.     _DISPLAY
  31.  
  32.  
  33.  
  34.  
  35.  
  36. SUB DisplayImage (Image AS LONG, x AS INTEGER, y AS INTEGER, angle AS SINGLE, mode AS _BYTE)
  37.     'Image is the image handle which we use to reference our image.
  38.     'x,y is the X/Y coordinates where we want the image to be at on the screen.
  39.     'angle is the angle which we wish to rotate the image.
  40.     'mode determines HOW we place the image at point X,Y.
  41.     'Mode 0 we center the image at point X,Y
  42.     'Mode 1 we place the Top Left corner of oour image at point X,Y
  43.     'Mode 2 is Bottom Left
  44.     'Mode 3 is Top Right
  45.     'Mode 4 is Bottom Right
  46.  
  47.  
  48.     DIM px(3) AS INTEGER, py(3) AS INTEGER, w AS INTEGER, h AS INTEGER
  49.     DIM sinr AS SINGLE, cosr AS SINGLE, i AS _BYTE
  50.     w = _WIDTH(Image): h = _HEIGHT(Image)
  51.     SELECT CASE mode
  52.         CASE 0 'center
  53.             px(0) = -w \ 2: py(0) = -h \ 2: px(3) = w \ 2: py(3) = -h \ 2
  54.             px(1) = -w \ 2: py(1) = h \ 2: px(2) = w \ 2: py(2) = h \ 2
  55.         CASE 1 'top left
  56.             px(0) = 0: py(0) = 0: px(3) = w: py(3) = 0
  57.             px(1) = 0: py(1) = h: px(2) = w: py(2) = h
  58.         CASE 2 'bottom left
  59.             px(0) = 0: py(0) = -h: px(3) = w: py(3) = -h
  60.             px(1) = 0: py(1) = 0: px(2) = w: py(2) = 0
  61.         CASE 3 'top right
  62.             px(0) = -w: py(0) = 0: px(3) = 0: py(3) = 0
  63.             px(1) = -w: py(1) = h: px(2) = 0: py(2) = h
  64.         CASE 4 'bottom right
  65.             px(0) = -w: py(0) = -h: px(3) = 0: py(3) = -h
  66.             px(1) = -w: py(1) = 0: px(2) = 0: py(2) = 0
  67.     END SELECT
  68.     sinr = SIN(angle / 57.2957795131): cosr = COS(angle / 57.2957795131)
  69.     FOR i = 0 TO 3
  70.         x2 = (px(i) * cosr + sinr * py(i)) + x: y2 = (py(i) * cosr - px(i) * sinr) + y
  71.         px(i) = x2: py(i) = y2
  72.     NEXT
  73.     _MAPTRIANGLE (0, 0)-(0, h - 1)-(w - 1, h - 1), Image TO(px(0), py(0))-(px(1), py(1))-(px(2), py(2))
  74.     _MAPTRIANGLE (0, 0)-(w - 1, 0)-(w - 1, h - 1), Image TO(px(0), py(0))-(px(3), py(3))-(px(2), py(2))
  75.  
  76. FUNCTION TextToImage& (text$, font&, fc&, bfc&, mode AS _BYTE)
  77.     'text$ is the text that we wish to transform into an image.
  78.     'font& is the handle of the font we want to use.
  79.     'fc& is the color of the font we want to use.
  80.     'bfc& is the background color of the font.
  81.  
  82.     'Mode 1 is print forwards
  83.     'Mode 2 is print backwards
  84.     'Mode 3 is print from top to bottom
  85.     'Mode 4 is print from bottom up
  86.     '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).
  87.  
  88.     IF mode < 1 OR mode > 4 THEN mode = 1
  89.     dc& = _DEFAULTCOLOR: bgc& = _BACKGROUNDCOLOR
  90.     D = _DEST
  91.     F = _FONT
  92.     IF font& <> 0 THEN _FONT font&
  93.     IF mode < 3 THEN
  94.         'print the text lengthwise
  95.         w& = _PRINTWIDTH(text$): h& = _FONTHEIGHT
  96.     ELSE
  97.         'print the text vertically
  98.         FOR i = 1 TO LEN(text$)
  99.             IF w& < _PRINTWIDTH(MID$(text$, i, 1)) THEN w& = _PRINTWIDTH(MID$(text$, i, 1))
  100.         NEXT
  101.         h& = _FONTHEIGHT * (LEN(text$))
  102.     END IF
  103.  
  104.     TextToImage& = _NEWIMAGE(w&, h&, 32)
  105.     _DEST TextToImage&
  106.     IF font& <> 0 THEN _FONT font&
  107.     COLOR fc&, bfc&
  108.  
  109.     SELECT CASE mode
  110.         CASE 1
  111.             'Print text forward
  112.             _PRINTSTRING (0, 0), text$
  113.         CASE 2
  114.             'Print text backwards
  115.             temp$ = ""
  116.             FOR i = 0 TO LEN(text$) - 1
  117.                 temp$ = temp$ + MID$(text$, LEN(text$) - i, 1)
  118.             NEXT
  119.             _PRINTSTRING (0, 0), temp$
  120.         CASE 3
  121.             'Print text upwards
  122.             'first lets reverse the text, so it's easy to place
  123.             temp$ = ""
  124.             FOR i = 0 TO LEN(text$) - 1
  125.                 temp$ = temp$ + MID$(text$, LEN(text$) - i, 1)
  126.             NEXT
  127.             'then put it where it belongs
  128.             FOR i = 1 TO LEN(text$)
  129.                 fx = (w& - _PRINTWIDTH(MID$(temp$, i, 1))) / 2 + .99 'This is to center any non-monospaced letters so they look better
  130.                 _PRINTSTRING (fx, _FONTHEIGHT * (i - 1)), MID$(temp$, i, 1)
  131.             NEXT
  132.         CASE 4
  133.             'Print text downwards
  134.             FOR i = 1 TO LEN(text$)
  135.                 fx = (w& - _PRINTWIDTH(MID$(text$, i, 1))) / 2 + .99 'This is to center any non-monospaced letters so they look better
  136.                 _PRINTSTRING (fx, _FONTHEIGHT * (i - 1)), MID$(text$, i, 1)
  137.             NEXT
  138.     END SELECT
  139.     _DEST D
  140.     COLOR dc&, bgc&
  141.     _FONT F
  142.  
  143. FUNCTION TextArrayToImage& (text() AS STRING, font&, fc&, bfc&, mode AS _BYTE)
  144.     'text is the text array that we wish to transform into an image.
  145.     'text(0) tells us how many lines of text we wish to use.
  146.     'font& is the handle of the font we want to use.
  147.     'fc& is the color of the font we want to use.
  148.     'bfc& is the background color of the font.
  149.  
  150.     'Mode 1 is print forwards
  151.     'Mode 2 is print backwards
  152.     'Mode 3 is print from top to bottom
  153.     'Mode 4 is print from bottom up
  154.     '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).
  155.  
  156.     NumberOfLines = VAL(text(0))
  157.  
  158.     IF mode < 1 OR mode > 4 THEN mode = 1
  159.     dc& = _DEFAULTCOLOR: bgc& = _BACKGROUNDCOLOR
  160.     D = _DEST
  161.     F = _FONT
  162.     IF font& <> 0 THEN _FONT font&
  163.     IF mode < 3 THEN
  164.         'print the text lengthwise
  165.         FOR i = 1 TO NumberOfLines
  166.             IF _PRINTWIDTH(text(i)) > w& THEN w& = _PRINTWIDTH(text(i))
  167.         NEXT
  168.         h& = _FONTHEIGHT
  169.         TextArrayToImage& = _NEWIMAGE(w&, h& * NumberOfLines, 32)
  170.     ELSE
  171.         'print the text vertically
  172.         FOR j = 1 TO NumberOfLines
  173.             IF LEN(text(j)) > longestline THEN longestline = LEN(text(j))
  174.             FOR i = 1 TO LEN(text(j))
  175.                 IF w& < _PRINTWIDTH(MID$(text(j), i, 1)) THEN w& = _PRINTWIDTH(MID$(text(j), i, 1))
  176.             NEXT
  177.         NEXT
  178.         h& = _FONTHEIGHT
  179.         TextArrayToImage& = _NEWIMAGE(w& * NumberOfLines, h& * longestline, 32)
  180.     END IF
  181.  
  182.     _DEST TextArrayToImage&
  183.     IF font& <> 0 THEN _FONT font&
  184.     COLOR fc&, bfc&
  185.  
  186.  
  187.     FOR i = 0 TO NumberOfLines - 1
  188.         SELECT CASE mode
  189.             CASE 1
  190.                 'Print text forward
  191.                 _PRINTSTRING (0, i * h&), text(i + 1)
  192.             CASE 2
  193.                 'Print text backwards
  194.                 temp$ = ""
  195.                 FOR j = 0 TO LEN(text(i + 1)) - 1
  196.                     temp$ = temp$ + MID$(text(i + 1), LEN(text(i + 1)) - j, 1)
  197.                 NEXT
  198.                 _PRINTSTRING (0, i * h&), temp$
  199.             CASE 3
  200.                 'Print text upwards
  201.                 'first lets reverse the text, so it's easy to place
  202.                 temp$ = ""
  203.                 FOR j = 0 TO LEN(text(i + 1)) - 1
  204.                     temp$ = temp$ + MID$(text(i + 1), LEN(text(i + 1)) - j, 1)
  205.                 NEXT
  206.                 'then put it where it belongs
  207.                 FOR j = 1 TO LEN(text(i + 1))
  208.                     fx = (w& - _PRINTWIDTH(MID$(temp$, j, 1))) / 2 + .99 'This is to center any non-monospaced letters so they look better
  209.                     _PRINTSTRING (fx + w& * i, _FONTHEIGHT * (j - 1)), MID$(temp$, j, 1)
  210.                 NEXT
  211.             CASE 4
  212.                 'Print text downwards
  213.                 FOR j = 1 TO LEN(text(i + 1))
  214.                     fx = (w& - _PRINTWIDTH(MID$(text(i + 1), j, 1))) / 2 + .99 'This is to center any non-monospaced letters so they look better
  215.                     _PRINTSTRING (fx + w& * i, _FONTHEIGHT * (j - 1)), MID$(text(i + 1), j, 1)
  216.                 NEXT
  217.         END SELECT
  218.     NEXT
  219.     _DEST D
  220.     COLOR dc&, bgc&
  221.     _FONT F
  222.  
  223. FUNCTION ScaleImage& (Image AS LONG, xscale AS SINGLE, yscale AS SINGLE)
  224.     w = _WIDTH(Image): h = _HEIGHT(Image)
  225.     w2 = w * xscale: h2 = h * yscale
  226.     NewImage& = _NEWIMAGE(w2, h2, 32)
  227.     _PUTIMAGE , Image&, NewImage&
  228.     ScaleImage& = NewImage&

Just don't forget to _FREEIMAGE the handles once you're finished with them.  I don't do so in the demo above, but with a single run-and-shut program like this, that's not going to become a concern like having a program run them in a loop would be. 
« Last Edit: January 06, 2021, 01:31:42 pm by SMcNeill »
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline Dav

  • Forum Resident
  • Posts: 792
Re: PPRINT - Prints larger font size using _PUTIMAGE
« Reply #4 on: January 06, 2021, 01:39:26 pm »
Really cool.  I don't know how I missed this snippet!

- Dav