Replies: 7 comments 17 replies
-
Hi, I tried to replicate Bodmer's drawWideLine, but found out TFT_eSPI version is limited in terms of color input types (e.g. it doesn't handle rgb332 or rgb888) and filling options, so I extended it with gradients, which also enabled the creation of a couple other features such as radial gradient fill for {rect,circle}, all working seamlessly with rbg888, rgb565 and rgb332 color types. I will try to submit a PR once I'm done with polishing the code but this feels like feature creep and I'm not sure how to contribute that to LovyanGFX without creating a tech debt, maybe as a snippet in the |
Beta Was this translation helpful? Give feedback.
-
Ok, looks good! |
Beta Was this translation helpful? Give feedback.
-
hi @GOB52 @lovyan03 can we discuss the best way to contribute these features to LovyanGFX/M5GFX? https://gist.github.com/tobozo/cc379ae025391f64d69fb633f383c491#file-lgfx_wideline-hpp Possible integration strategies:
@jgauchia if you want to play with the features just download the gist but keep in mind it's not the final version.
However the best performances are obtained using Draw thick+smooth lines with single color fillvoid drawWideLine(LovyanGFX* gfx, int32_t x0, int32_t y0, int32_t x1, int32_t y1, float thick, COLOR fg_color) Draw thick+smooth lines with gradient fillvoid drawWideLine(LovyanGFX* gfx, int32_t x0, int32_t y0, int32_t x1, int32_t y1, float thick, const colors_t<COLOR> gradient) Draw wedge line with single color fillvoid drawWedgeLine(LovyanGFX* gfx, int32_t x0, int32_t y0, int32_t x1, int32_t y1, float thick0, float thick1, COLOR fg_color) Draw wedge line with gradient fillvoid drawWedgeLine(LovyanGFX* gfx, int32_t x0, int32_t y0, int32_t x1, int32_t y1, float thick0, float thick1, const colors_t<COLOR> gradient) Fill smooth circle with single color (redundant with lgfx::fillSmoothCircle)void drawSpot(LovyanGFX* gfx, int32_t x, int32_t y, float radius, COLOR fg_color) Fill smooth circle with gradientvoid drawGradientSpot(LovyanGFX* gfx, int32_t x, int32_t y, float radius, const colors_t<COLOR> gradient) Fill rect with radial/linear dual color (fill_style_t can be any of RADIAL, HLINEAR or VLINEAR)void fillGradientRect(LovyanGFX* gfx, int32_t x, int32_t y, uint32_t w, uint32_t h, COLOR start, COLOR end, fill_style_t style=RADIAL ) Fill rect with radial/linear gradient (fill_style_t can be any of RADIAL, HLINEAR or VLINEAR)void fillGradientRect(LovyanGFX* gfx, int32_t x, int32_t y, uint32_t w, uint32_t h, const colors_t<COLOR> gradient, fill_style_t style=RADIAL ) Create a gradientcolors_t createGradient( COLOR[] colors ) colors_t createGradient( COLOR* colors, uint32_t count ) Example:GradientPluginAdapter gfx(&tft);
uint16_t colors[] = { TFT_GREEN, TFT_YELLOW, TFT_ORANGE, TFT_RED };
auto gradient = gfx.createGradient( colors ); // create a gradient item
gfx.fillGradientRect( 10, 10, 200, 200, gradient, HLINEAR ); |
Beta Was this translation helpful? Give feedback.
-
Why do you want to include this in LovyanGFX instead of another library that LovyanGFX requires? |
Beta Was this translation helpful? Give feedback.
-
It would certainly be nice to be able to use functions extended by the user, like MODs in Game. |
Beta Was this translation helpful? Give feedback.
-
I have come up with a way to overload the arrow operator!
namespace lgfx { namespace plugin {
template<typename LGFX> class Adapter
{
public:
using lgfx_type = LGFX;
Adapter() = delete;
explicit Adapter(LGFX* gfx) : _gfx(gfx)
{
assert(gfx != nullptr && "nullptr");
}
virtual ~Adapter() {}
explicit operator LGFX*() { return _gfx; } // Cast
// Overload arrow operator (direct access to LGFX) this->drawLine => _gfx->drawLine
const LGFX* operator->() const noexcept { return _gfx; }
LGFX* operator->() noexcept { return _gfx; }
protected:
LGFX* _gfx;
};
}}
template<typename LGFX> class MyPlugin : public lgfx::plugin::Adapter<LGFX>
{
public:
using lgfx::plugin::Adapter<LGFX>::Adapter; // for constructor
using lgfx::plugin::Adapter<LGFX>::_gfx;
template<typename T> void myCustomFunction( int32_t x, int32_t y, uint32_t w, uint32_t h, T color )
{
_gfx->setClipRect( x, y, w, h );
_gfx->drawLine( x, y, x+w, y+h, color );
_gfx->fillCircle( x+w/2, y+h/2, std::min(w,h)/4, color );
_gfx->clearClipRect();
}
};
MyPlugin<decltype(M5.Display)> blah(&M5.Display);
LGFX_Sprite spr(&M5.Display);
spr.createSprite(64,64);
MyPlugin<decltype(spr)> blahs(&spr);
M5_LOGI("parent:%p", blahs->getParent());
Serial.printf("Width:%d\n", blah->width());
M5_LOGI("%p : %p", &M5.Display, (M5GFX*)blah);
blah->clear(TFT_ORANGE);
blah->drawPixel( 40, 50, TFT_BLUE );
blah->drawCircle( 10, 20, 30, TFT_WHITE );
blah.myCustomFunction( 0, 0, 40, 50, TFT_GREEN );
delay(5000);
blahs->clear(TFT_BLUE);
blahs.myCustomFunction( 0, 0, 40, 50, TFT_CYAN );
blahs->pushSprite(0,0); |
Beta Was this translation helpful? Give feedback.
-
@jgauchia wide line support has been integrated in the |
Beta Was this translation helpful? Give feedback.
-
In the TFT_eSPI library, there is the possibility to draw lines with thickness using drawWideLine. Is there an alternative in LovyanGFX?
Thank you.
Beta Was this translation helpful? Give feedback.
All reactions