Log In  

Here I present a method for stroking text and sprites.

In looking through solutions for stroked/filled text, I usually see print()on the string called 9 times; i.e. once at each cardinal location with a 1px offset. I realized if pixels were represented by "fat pixels" outlines of various thicknesses could be simulated.

For example, if a pixel is at (x,y),

rectfill(x-thickness, y-thickness, x+thickness, y+thickness,color)

with a normal pixel draw on top would look like an outlined pixel. I further realized that anything with transparent pixels could be outlined in this same manner, and so applied it to sprites.

This method works in the following:

  1. Video space is "borrowed" for less than a frame (?) to render the text and capture it's pixel data to user data space. (the specific address space used for this caching can be set to wherever you like; sprites are read as-is from sprite memory space)
  2. The bytes are walked and used to draw fat pixels (via rectfill()).
  3. The string is then rendered "as normal" at the location requested. (print()is only called twice: once to grab the pixel data cache, once to draw the string on top of the effects)
  4. Seems to be at 300 tokens currently.

This method has the following benefits:

  1. Visual effects are defined as a table (list) of inner tables, where each inner table defines:
{fill_color, stroke_color, line_thickness, effect_x_offset, effect_y_offset}
  1. Effects in a list are applied in the "painter method" from [1]..[#effect] where each subsequent effect is drawn on top of the previous. This allows for complex stackings of routines.
  2. Effects are just tables, and so can be pre-defined and re-used on other elements, including sprites.
  3. Effects are animatable, by simply swapping colors and offset values.
  4. Uses no sprites, only Pico-8 native text (though it could be pretty easily adapted to work with mini-font libraries that use custom sprites, I think)

Optimization possibilities
Unlike the "draw a string 9 times" methods, this methodology presents an opportunity for optimization. I'm still very new to Pico-8 and Lua, so this really only represents a starting point toward a better algorithm.

For example, I'm sure there are ways to make it more efficient.

  1. I believe the call to peek() could be switched to a peek4()?
  2. I believe the call to rectfill() could be swapped for direct writes to the bytes?
  3. I'm certain there are ways to reduce the token count from the current 300, but for the purpose of this post I tried to consolidate redundant code without sacrificing (too much) legibility.

(P.S. - I don't see how a name can be attached to a cart? @clip didn't use the file name? I see no tools here for setting title, license, etc.)

Cart #56189 | 2018-09-04 | Code ▽ | Embed ▽ | No License

P#56191 2018-09-04 20:03 ( Edited 2018-09-05 11:04)

:: dw817

Pretty neat ! I wrote a fairly comprehensive library for TEXT years ago, unfortunately, it's spaghetti coded. Could stand to be rewritten with modern methods.


P#56206 2018-09-04 23:12 ( Edited 2018-09-05 03:12)

Names are attached to carts very easily. Put this comment on the top of your code:

--cartridge title
--by your name
P#56215 2018-09-05 03:44 ( Edited 2018-09-05 07:44)

Cool, thanks for the heads up on that.

P#56220 2018-09-05 07:04 ( Edited 2018-09-05 11:04)

[Please log in to post a comment]

Follow Lexaloffle:        
Generated 2022-08-14 09:30:21 | 0.046s | Q:19