Add som drawing functions #3

Closed
opened 2019-08-31 14:14:51 +02:00 by Kirafi · 3 comments

I just write notes. We will add missing prototypes latter.

Usefull

  • Rotate & invert sprite
  • Rotate text
  • Stroke rectangle with 1px border (border color is configurable)
  • Dashed line (pattern configurable)
  • Text placement : vertical/horizontal center/align etc...

Probably useless but "classicals"

  • Horizontal & Vertical lines, bewteen 2 points & between screen border
  • Square, fill & stroke (simplified rectangle)
  • Draw tile directly from tileset wich tiles are separated by 1px and are the same size (shortcut for dsubimage)
I just write notes. We will add missing prototypes latter. # Usefull - Rotate & invert sprite - Rotate text - Stroke rectangle with 1px border (border color is configurable) - Dashed line (pattern configurable) - Text placement : vertical/horizontal center/align etc... # Probably useless but "classicals" - Horizontal & Vertical lines, bewteen 2 points & between screen border - Square, fill & stroke (simplified rectangle) - Draw tile directly from tileset wich tiles are separated by 1px and are the same size (shortcut for `dsubimage`)
Kirafi reopened this issue 2019-08-31 15:17:03 +02:00
Owner

I think most of these functions would deserve a full, independent graphing library, much like MonochromeLib. The problem here is that most of the time there's an enormous amount of parameters, which can be specified in multiple ways :

  • By having a very long list of parameters for each function (very painful)
  • By having non-trivial objects such as "pen" and "fill"
  • By having a global state that implicitly sets some parameters

Currently gint only uses parameter-based specifications and so the only solution for now would be the painful one, which... is not a good idea.

I'm considering a way of implementing non-trivial "pen" and "fill" objects. This would allow me to have gint drawing functions with many parameters, and allow you to call them without specifying everything. Please give me some time to plan this change.

In any case, let's start with feasibility and API concerns :

  • Rotation and inversion in general is impossible under bopti on the fx-9860G as the optimization that takes place clearly assumes pixel ordering. More precisely :
    • Vertical mirror is easy
    • Horizontal mirror and 180° rotation would be a bit hard, and less efficient
    • 90° and 270° rotation are just plain impossible in the current setup

This would be possible to a certain extent on fx-CG 50, but ultimately I think the best way to do this is just to generate the sprites you need at compile-time. This preserves performance which is much needed on fx-CG 50.

  • Same for text, if really needed I can implement a vertical-string mode and then you could use a manually-rotated font.

  • Rectangle with border is no problem. The border size could probably be configured as well.

  • A dashed line with configurable patterns feels too fancy to be in the gint core. Also, there's an awful lot of parameters here, including line endings, pattern speification, dots vs line, line width, etc.

  • Text placement is possible, I'll consider a way of specifying in dtext() that parameters x and y represent the position of another corner than the top-left one.

  • We already talked about horizontal and vertical lines, so I implemented dhline() and dvline() that do the same as the Basic commands Horizontal and Vertical in an optimized way (commit ef0e5e3).

  • Is a square really needed? You only save one parameter out of 4 plus the color specification. x_x

  • Tile drawing would have much more parameters than that, starting with the distance which may not be 1px depending on the user. For instance on fx-CG 50, 1px is definitely too short.

I think most of these functions would deserve a full, independent graphing library, much like MonochromeLib. The problem here is that most of the time there's an enormous amount of parameters, which can be specified in multiple ways : * By having a very long list of parameters for each function (very painful) * By having non-trivial objects such as "pen" and "fill" * By having a global state that implicitly sets some parameters Currently gint only uses parameter-based specifications and so the only solution for now would be the painful one, which... is not a good idea. I'm considering a way of implementing non-trivial "pen" and "fill" objects. This would allow me to have gint drawing functions with many parameters, and allow you to call them without specifying everything. Please give me some time to plan this change. In any case, let's start with feasibility and API concerns : * Rotation and inversion in general is impossible under bopti on the fx-9860G as the optimization that takes place clearly assumes pixel ordering. More precisely : * Vertical mirror is easy * Horizontal mirror and 180° rotation would be a bit hard, and less efficient * 90° and 270° rotation are just plain impossible in the current setup This would be possible to a certain extent on fx-CG 50, but ultimately I think the best way to do this is just to generate the sprites you need at compile-time. This preserves performance which is much needed on fx-CG 50. * Same for text, if really needed I can implement a vertical-string mode and then you could use a manually-rotated font. * Rectangle with border is no problem. The border size could probably be configured as well. * A dashed line with configurable patterns feels too fancy to be in the gint core. Also, there's an awful lot of parameters here, including line endings, pattern speification, dots vs line, line width, etc. * Text placement is possible, I'll consider a way of specifying in `dtext()` that parameters `x` and `y` represent the position of another corner than the top-left one. * We already talked about horizontal and vertical lines, so I implemented `dhline()` and `dvline()` that do the same as the Basic commands `Horizontal` and `Vertical` in an optimized way (commit ef0e5e3). * Is a square really needed? You only save one parameter out of 4 plus the color specification. x_x * Tile drawing would have much more parameters than that, starting with the distance which may not be 1px depending on the user. For instance on fx-CG 50, 1px is definitely too short.
Owner

I'm coming back to this now with a more concrete plan.

First off, image operations are now available through libimg, a library that manipulates a plain image format that is a lot more versatile than bopti (while also being a lot less efficient on fx-9860G). This leaves use with more basic geometry.

My plan is to have reasonable extensions to the current drawing API while keeping things short. I would like to:

  • Add border width and color parameters to drect().
  • Make fg, bg parameter pairs a single parameter in dtext() and dprint(), because most of the time bg is C_NONE and it shouldn't be necessary to specify that.
  • Add alignment settings to dtext() and dprint() at the same time.

I have a way to make this work reasonably well without additional work. The idea is to use a transparent union so that the user may equally provide a simple color name, or a full structure with more parameters.

/* Simple color name version */
drect(0,0,10,10, C_BLACK);
/* Full object version */
dpen_t pen = { .fg = C_BLACK, .bg = C_RED, .border_width = 2 };
drect(0,0,10,10, pen);

I also added a bit of preprocessor wizardry to make the pen specification easier.

/* Preprocessor wizardry version */
drect(0,0,10,10, dpen(fg=C_BLACK, bg=C_RED, border_width=2));

I'm still unsure as to how advanced gint's drawing should be. Currently it is drastically limited by its ability to write only to VRAM rather than general surfaces, but something more versatile would definitely not count as kernel stuff and is probably suited for a library.

I'm coming back to this now with a more concrete plan. First off, image operations are now available through [libimg](https://gitea.planet-casio.com/Lephenixnoir/libimg), a library that manipulates a plain image format that is a lot more versatile than bopti (while also being a lot less efficient on fx-9860G). This leaves use with more basic geometry. My plan is to have reasonable extensions to the current drawing API while keeping things short. I would like to: * Add border width and color parameters to `drect()`. * Make fg, bg parameter pairs a single parameter in `dtext()` and `dprint()`, because most of the time bg is `C_NONE` and it shouldn't be necessary to specify that. * Add alignment settings to `dtext()` and `dprint()` at the same time. I have a way to make this work reasonably well without additional work. The idea is to use a transparent union so that the user may equally provide a simple color name, or a full structure with more parameters. ```c /* Simple color name version */ drect(0,0,10,10, C_BLACK); /* Full object version */ dpen_t pen = { .fg = C_BLACK, .bg = C_RED, .border_width = 2 }; drect(0,0,10,10, pen); ``` I also added a bit of preprocessor wizardry to make the pen specification easier. ```c /* Preprocessor wizardry version */ drect(0,0,10,10, dpen(fg=C_BLACK, bg=C_RED, border_width=2)); ``` I'm still unsure as to how advanced gint's drawing should be. Currently it is drastically limited by its ability to write only to VRAM rather than general surfaces, but something more versatile would definitely not count as kernel stuff and is probably suited for a library.
Owner

After thinking this through for a few more hours, I'll leave the optional argument trick for another time and use other function names. I don't want to expand on the drawing API too much, but this should be enough.

  • I've added a drect_border() function for rectangles with borders.
  • I've added two new functions, dtext_opt() and dprint_opt() that have both fg/bg and alignment options.
  • Finally, I've changed dtext() and dprint() to have only fg.

Let's recap :

Rotate & invert sprite

See in libimg.

Rotate text

Not possible with topti fonts on fx9860g, at best I could do a vertical text mode and you'd have to convert fonts again. But this is already a niche for something to put in the kernel itself.

Stroke rectangle with 1px border (border color is configurable)

drect_border() lets you choose both border width and color.

Dashed line (pattern configurable)

Too many parameters here, doing this properly would require an immense API.

Text placement : vertical/horizontal center/align etc...

Added through dtext_opt() and dprint_opt().

Horizontal & Vertical lines, bewteen 2 points & between screen border

dhline() and dvline() will do as Horizontal and Vertical in Basic, for other horizontal/vertical lines use dline() with y1=y2/x1=x2.

Square, fill & stroke (simplified rectangle)

Not very interesting, you just save 1 parameter out of 7.

Draw tile directly from tileset wich tiles are separated by 1px and are the same size (shortcut for dsubimage)

Seems very application-specific, there are many ways to arrange a tileset, not always with only 1px of space between tiles. If it's just a shortcut it's better to add it in your own util file.

I'll be closing this now and pushing the changes shortly. Any remarks are still welcome ^^

After thinking this through for a few more hours, I'll leave the optional argument trick for another time and use other function names. I don't want to expand on the drawing API too much, but this should be enough. * I've added a `drect_border()` function for rectangles with borders. * I've added two new functions, `dtext_opt()` and `dprint_opt()` that have both fg/bg and alignment options. * Finally, I've changed `dtext()` and `dprint()` to have only fg. Let's recap : > Rotate & invert sprite See in libimg. > Rotate text Not possible with topti fonts on fx9860g, at best I could do a vertical text mode and you'd have to convert fonts again. But this is already a niche for something to put in the kernel itself. > Stroke rectangle with 1px border (border color is configurable) `drect_border()` lets you choose both border width and color. > Dashed line (pattern configurable) Too many parameters here, doing this properly would require an immense API. > Text placement : vertical/horizontal center/align etc... Added through `dtext_opt()` and `dprint_opt()`. > Horizontal & Vertical lines, bewteen 2 points & between screen border `dhline()` and `dvline()` will do as `Horizontal` and `Vertical` in Basic, for other horizontal/vertical lines use `dline()` with `y1=y2`/`x1=x2`. > Square, fill & stroke (simplified rectangle) Not very interesting, you just save 1 parameter out of 7. > Draw tile directly from tileset wich tiles are separated by 1px and are the same size (shortcut for dsubimage) Seems very application-specific, there are many ways to arrange a tileset, not always with only 1px of space between tiles. If it's just a shortcut it's better to add it in your own util file. I'll be closing this now and pushing the changes shortly. Any remarks are still welcome ^^
Sign in to join this conversation.
No Label
No Milestone
No Assignees
2 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: Lephenixnoir/gint#3
No description provided.