sporniket / esp32-idf-experiment-spi-st7789

Addressing the ST7789 TFT controller through SPI on the ESP32 using the IDF toolchain.
GNU General Public License v3.0
0 stars 0 forks source link

draft a graphic context to provide usual drawing operations #1

Open sporniket opened 1 year ago

sporniket commented 1 year ago

Technical details

Heavily inspired by Java's Graphics2D and Javascript's graphical context of the canvas.

typical use after setting up :


GraphicContext2D *context = new GraphicContext2D12Bpp(FrameBuffer12Bpp * fb);

// ...

context->setColor(c) ;
context->setFill(...) ; // give more thoughts to the setting api
context->draw(Shape.rectangle(x1,y1,x2,h2)) ; // draw the path instanciated by Shape.rectangle(...)
context->fill(Shape.ellipse(x1,y1,x2,y2)) ; // fill the path instanciated by Shape.ellipse(...)

An integer coordinate lies in the infinitesimal space between pixels, and the drawing pen is a square of 1 pixel wide with the top left corner lying on said integer coordinate.

Path / Point


Path = {{10,10},{10,20},{20,20},PathItem.CYCLE} ; // PathItem.CYCLE is a special instance to tag a cycling path.

Shape API

Context attribute

...

sporniket commented 1 month ago

Typical code to be written :


// Canvas Buffer
// ---
// * Define working memory area, pixel format, canvas dimension
// * Provides low-level primitives : 
//   * draw horizontal or vertical segment with "active" color (by index or rgb, according to format)
//   * draw copy bloc from another compatible buffer (same pixel format)
CanvasBuffer cbuf = new CanvasBuffer(memoryArea, pixelFormat, width, eight) ;

// Palette
// ---
// A collection of RGB colors. Depending on the pixel format, it may have an effect or not.
// e.g.
// * On RGB displays (like TFT panels), the RGB value will be converted into the actual pixel format. Changing the palette will change the set of colors used after.
// * On Atari ST low resolution (320x200) : each color index will be rendered using the RGB color. Changing the palette will change the whole image immediately to use the new colors.
// * On Atari ST High resolution (640x400) : RGB(0,0,0) as first color will force inverted palette (white on black), any other color will give normal black on white. Changing the palette will change the whole image immediately to use the new colors (following the rule described about the first color)
// * Monochrome OLED displays are fixed color on black (white, blue, yellow, whatever), that cannot be changed, RGB is indicative
// * e-ink display with three fixed color (e.g. white, black, red) have fixed palette (white, black, color e.g. red), that cannot be changed, RGB is indicative
//
Palette pGreenMonochrome = new Palette(5, RGB(0,0,0), RGB(0x39,0x9b,0x6a) , RGB(0x42,0xd2,0x97), RGB(0x15,0xf9,0xe6), RGB(0xce,0xfc,0xfc)) ;

// Glyph Map
// ---
// A set of bitmap glyphes of the same dimensions, as a set of monochrome bitmap tiles vertically arranged, and a logic weight.
// Supports FontX2 file format
GlyphMap light = nem GlyphMap("assets/fonts/AtariHighRegular.stx", FontWeight::LIGHT) ;
GlyphMap regular = nem GlyphMap("assets/fonts/AtariHighRegular.stx", FontWeight::REGULAR) ;
GlyphMap bold = nem GlyphMap("assets/fonts/AtariHighRegular.stx", FontWeight::BOLD) ;

// Font
// ---
// A collection of coordinated glyph maps
Font fsAtari = new Font(light, regular, bold) ;

// Font Registry
// ---
// A map of named fonts. Name are specified by the vendor/producer.
//
// TO DO
FontRegistry theRegitry = {
  "Atari ST High":fsAtari
} ;

// Font Set
// ---
// A normalized font registry, that has only normalized keys (FIXE_WIDTH, SERIF, SANS_SERIF), and points to a font from the registry
//
// TO DO 
FontSet theFontSet = {
  FontSetKey::FIXED_WIDTH : "Atari ST High"
}

Canvas c = new Canvas(cbuf, pGreenMonochrome, theFontSet, theRegistry) ; // color #1 is selected by default

// --> Canvas c = new Canvas(memoryArea, pixelFormat, width, eight, palette) ;

c.clear() // clear always use color 0
c.plot(10,20);
c.plot(12,20);
c.plot(14,20);
c.plot(12,18);
c.plot(12,22);
c.selectColor(2);
c.line(15,20,45,40);
c.rect(20,20,50,50);
c.selectColor(3);
c.ellipse(35,30,30,15);
c.selectColor(4);
c.selectSystemFont(FontSetKey::FIXED_WIDTH) // useless with only this font in the font set
c.setFontWeight(FontWeigth::LIGHT)
// TODO : concept of font size
c.text(16,64,"Hello World !")
//
c.selectFont("Atari ST High", FontWeight::REGULAR) // useless with only this font in the font registry
c.setFontWeight(FontWeigth::REGULAR)
c.text(16,72,"Hello World !")
//
c.setFontWeight(FontWeigth::BOLD)
c.text(16,80,"Hello World !")

// etc...
// TODO send memory area to display, if appliable
sporniket commented 1 month ago

FONTX2 file format :