diff --git a/_doc/documentation.dox b/_doc/documentation.dox index fc5d077..eaa4091 100644 --- a/_doc/documentation.dox +++ b/_doc/documentation.dox @@ -156,15 +156,15 @@ Designed by TFT : Terraneo Federico Technologies Options: --help Prints this. --in arg Input png file (required) - --depth arg Color depth, 1,8,16,18 or 24 bits (required) + --format arg Pixel format, gray1,gray4,RGB332,RGB565 (required) --out arg Output png file for validation --binary Generate a binary file instead of a .cpp/.h file \endcode To use it, assume you have an image called test.png that needs to be embedded -into a firmware at a 16 bit per pixel color depth, the command line to do so is +into a firmware with RGB565 pixel format, the command line to do so is \code -./pngconverter --in test.png --depth 16 +./pngconverter --in test.png --format rgb565 \endcode As a result, the program will produce, in the same directory where the test.png file is, two files: test.cpp and test.h diff --git a/_examples/benchmark/benchmark.cpp b/_examples/benchmark/benchmark.cpp index f097556..5cf9138 100644 --- a/_examples/benchmark/benchmark.cpp +++ b/_examples/benchmark/benchmark.cpp @@ -85,17 +85,17 @@ void Benchmark::start() //Then, do benchmarks fixedWidthTextBenchmark(); variableWidthTextBenchmark(); - #ifndef MXGUI_COLOR_DEPTH_1_BIT_LINEAR + #ifndef MXGUI_PIXEL_FORMAT_GRAY1 antialiasingBenchmark(); - #endif //MXGUI_COLOR_DEPTH_1_BIT_LINEAR + #endif //MXGUI_PIXEL_FORMAT_GRAY1 horizontalLineBenchmark(); verticalLineBenchmark(); obliqueLineBenchmark(); clearScreenBenchmark(); imageBenchmark(); - #ifndef MXGUI_COLOR_DEPTH_1_BIT_LINEAR + #ifndef MXGUI_PIXEL_FORMAT_GRAY1 scanLineBenchmark(); - #endif //MXGUI_COLOR_DEPTH_1_BIT_LINEAR + #endif //MXGUI_PIXEL_FORMAT_GRAY1 clippedDrawBenchmark(); clippedWriteBenchmark(); #ifdef MXGUI_ENABLE_RESOURCEFS @@ -150,11 +150,11 @@ void Benchmark::fixedWidthTextBenchmark() { DrawingContext dc(display); dc.setFont(miscFixed); - #ifndef MXGUI_COLOR_DEPTH_1_BIT_LINEAR + #ifndef MXGUI_PIXEL_FORMAT_GRAY1 dc.setTextColor(i%2==0 ? red : green,black); - #else //MXGUI_COLOR_DEPTH_1_BIT_LINEAR + #else //MXGUI_PIXEL_FORMAT_GRAY1 i%2==0 ? dc.setTextColor(white,black) : dc.setTextColor(black,white); - #endif //MXGUI_COLOR_DEPTH_1_BIT_LINEAR + #endif //MXGUI_PIXEL_FORMAT_GRAY1 } auto t=system_clock::now(); { @@ -186,11 +186,11 @@ void Benchmark::variableWidthTextBenchmark() { DrawingContext dc(display); dc.setFont(tahoma); - #ifndef MXGUI_COLOR_DEPTH_1_BIT_LINEAR + #ifndef MXGUI_PIXEL_FORMAT_GRAY1 dc.setTextColor(i%2==0 ? red : green,black); - #else //MXGUI_COLOR_DEPTH_1_BIT_LINEAR + #else //MXGUI_PIXEL_FORMAT_GRAY1 i%2==0 ? dc.setTextColor(white,black) : dc.setTextColor(black,white); - #endif //MXGUI_COLOR_DEPTH_1_BIT_LINEAR + #endif //MXGUI_PIXEL_FORMAT_GRAY1 } auto t=system_clock::now(); { @@ -206,7 +206,7 @@ void Benchmark::variableWidthTextBenchmark() } -#ifndef MXGUI_COLOR_DEPTH_1_BIT_LINEAR +#ifndef MXGUI_PIXEL_FORMAT_GRAY1 void Benchmark::antialiasingBenchmark() { unsigned int totalTime=0; @@ -237,18 +237,18 @@ void Benchmark::antialiasingBenchmark() totalTime/=4; results[index++]=BenchmarkResult("Antialiased text",totalTime); } -#endif //MXGUI_COLOR_DEPTH_1_BIT_LINEAR +#endif //MXGUI_PIXEL_FORMAT_GRAY1 void Benchmark::horizontalLineBenchmark() { unsigned int totalTime=0; for(int i=0;i<4;i++) { - #ifndef MXGUI_COLOR_DEPTH_1_BIT_LINEAR + #ifndef MXGUI_PIXEL_FORMAT_GRAY1 Color color=i%2==0?red:green; - #else //MXGUI_COLOR_DEPTH_1_BIT_LINEAR + #else //MXGUI_PIXEL_FORMAT_GRAY1 Color color=i%2==0?white:black; - #endif //MXGUI_COLOR_DEPTH_1_BIT_LINEAR + #endif //MXGUI_PIXEL_FORMAT_GRAY1 auto t=system_clock::now(); { DrawingContext dc(display); @@ -268,11 +268,11 @@ void Benchmark::verticalLineBenchmark() unsigned int totalTime=0; for(int i=0;i<4;i++) { - #ifndef MXGUI_COLOR_DEPTH_1_BIT_LINEAR + #ifndef MXGUI_PIXEL_FORMAT_GRAY1 Color color=i%2==0?red:green; - #else //MXGUI_COLOR_DEPTH_1_BIT_LINEAR + #else //MXGUI_PIXEL_FORMAT_GRAY1 Color color=i%2==0?white:black; - #endif //MXGUI_COLOR_DEPTH_1_BIT_LINEAR + #endif //MXGUI_PIXEL_FORMAT_GRAY1 auto t=system_clock::now(); { DrawingContext dc(display); @@ -292,18 +292,18 @@ void Benchmark::obliqueLineBenchmark() unsigned int totalTime=0; for(int i=0;i<4;i++) { - #ifndef MXGUI_COLOR_DEPTH_1_BIT_LINEAR - const Color darkRed(0x7800); - const Color darkGreen(0x3e00); - const Color darkBlue(0x000f); + #ifndef MXGUI_PIXEL_FORMAT_GRAY1 + const Color darkRed = Color::fromRGB565(0x7800); + const Color darkGreen = Color::fromRGB565(0x3e00); + const Color darkBlue = Color::fromRGB565(0x000f); Color colorA=i%2==0?darkRed:darkGreen; Color colorB=i%2==0?darkGreen:darkBlue; Color colorC=i%2==0?darkBlue:darkRed; - #else //MXGUI_COLOR_DEPTH_1_BIT_LINEAR + #else //MXGUI_PIXEL_FORMAT_GRAY1 Color colorA=i%2==0?white:black; Color colorB=colorA; Color colorC=i%2==0?black:white; - #endif //MXGUI_COLOR_DEPTH_1_BIT_LINEAR + #endif //MXGUI_PIXEL_FORMAT_GRAY1 auto t=system_clock::now(); { DrawingContext dc(display); @@ -355,11 +355,11 @@ void Benchmark::clearScreenBenchmark() unsigned int totalTime=0; for(int i=0;i<4;i++) { - #ifndef MXGUI_COLOR_DEPTH_1_BIT_LINEAR + #ifndef MXGUI_PIXEL_FORMAT_GRAY1 Color color=i%2==0?red:green; - #else //MXGUI_COLOR_DEPTH_1_BIT_LINEAR + #else //MXGUI_PIXEL_FORMAT_GRAY1 Color color=i%2==0?white:black; - #endif //MXGUI_COLOR_DEPTH_1_BIT_LINEAR + #endif //MXGUI_PIXEL_FORMAT_GRAY1 auto t=system_clock::now(); { DrawingContext dc(display); @@ -383,11 +383,11 @@ void Benchmark::imageBenchmark() DrawingContext dc(display); for(int j=0;j checkpattern2(height,width,pixelData); \ No newline at end of file +const basic_image checkpattern2(height,width,pixelData); \ No newline at end of file diff --git a/_examples/benchmark/checkpattern2.h b/_examples/benchmark/checkpattern2.h index efc9716..bc4938a 100644 --- a/_examples/benchmark/checkpattern2.h +++ b/_examples/benchmark/checkpattern2.h @@ -6,6 +6,6 @@ #include "mxgui/image.h" -extern const mxgui::basic_image checkpattern2; +extern const mxgui::basic_image checkpattern2; #endif //CHECKPATTERN2_H diff --git a/_examples/benchmark/micro_qr_code_from_wikipedia.cpp b/_examples/benchmark/micro_qr_code_from_wikipedia.cpp index 1708858..4d04797 100644 --- a/_examples/benchmark/micro_qr_code_from_wikipedia.cpp +++ b/_examples/benchmark/micro_qr_code_from_wikipedia.cpp @@ -43,4 +43,4 @@ static const unsigned short pixelData[]={ 65535,65535,65535,65535,65535,65535,65535,65535 }; -const basic_image micro_qr_code_from_wikipedia(height,width,pixelData); \ No newline at end of file +const basic_image micro_qr_code_from_wikipedia(height,width,pixelData); \ No newline at end of file diff --git a/_examples/display_er_oledm015/display_er_oledm015.cpp b/_examples/display_er_oledm015/display_er_oledm015.cpp index f4afa1e..9e0adad 100644 --- a/_examples/display_er_oledm015/display_er_oledm015.cpp +++ b/_examples/display_er_oledm015/display_er_oledm015.cpp @@ -26,6 +26,7 @@ ***************************************************************************/ #include "display_er_oledm015.h" +#include "misc_inst.h" #include #include #include @@ -290,10 +291,10 @@ DisplayErOledm015::DisplayErOledm015() : buffer(nullptr), buffer2(nullptr) cmd(0xc1); dat(0x88); dat(0x70); dat(0x88); // A B C brightness cmd(0xc7); dat(0x0f); // Master brightness cmd(0xca); dat(0x7f); // Duty 1:128 - clear(0); + clear(black); cmd(0xaf); // Display ON - setTextColor(make_pair(Color(0xffff),Color(0x0))); + setTextColor(make_pair(Color::white(),Color::black())); } void DisplayErOledm015::doTurnOn() diff --git a/_examples/display_er_oledm015/display_er_oledm015.h b/_examples/display_er_oledm015/display_er_oledm015.h index b44f47d..94210cd 100644 --- a/_examples/display_er_oledm015/display_er_oledm015.h +++ b/_examples/display_er_oledm015/display_er_oledm015.h @@ -40,7 +40,7 @@ namespace mxgui { //This display is 16 bit per pixel, check that the color depth is properly //configured -#ifndef MXGUI_COLOR_DEPTH_16_BIT +#ifndef MXGUI_PIXEL_FORMAT_RGB565 #error The SSD1351 driver requires a color depth of 16bit per pixel #endif diff --git a/_examples/display_er_oledm024/display_er_oledm024.cpp b/_examples/display_er_oledm024/display_er_oledm024.cpp index f60345c..b2c109f 100644 --- a/_examples/display_er_oledm024/display_er_oledm024.cpp +++ b/_examples/display_er_oledm024/display_er_oledm024.cpp @@ -26,6 +26,7 @@ ***************************************************************************/ #include "display_er_oledm024.h" +#include "misc_inst.h" #include #include @@ -172,10 +173,10 @@ DisplayErOledm024::DisplayErOledm024() : DisplayGeneric1BPP(128,64) cmd(0xdb); cmd(0x34); // VCOMH=.78*VCC cmd(0xa6); // Normal display mode cmd(0xa4); // Disable test mode - clear(0); + clear(black); update(); cmd(0xaf); // Display ON - setTextColor(std::make_pair(Color(0xf),Color(0x0))); + setTextColor(std::make_pair(Color::white(),Color::black())); } void DisplayErOledm024::doTurnOn() diff --git a/_examples/display_er_oledm028/display_er_oledm028.cpp b/_examples/display_er_oledm028/display_er_oledm028.cpp index f2fa8ca..2aa9e53 100644 --- a/_examples/display_er_oledm028/display_er_oledm028.cpp +++ b/_examples/display_er_oledm028/display_er_oledm028.cpp @@ -27,6 +27,7 @@ ***************************************************************************/ #include "display_er_oledm028.h" +#include "misc_inst.h" #include "miosix.h" #include @@ -198,7 +199,7 @@ DisplayErOledm028::DisplayErOledm028() : DisplayGeneric4BPP(256,64) cmd(0xb6); data(0x08); // Second precharge period cmd(0xbe); data(0x07); // VCOMH cmd(0xa6); // Normal display mode - clear(0); + clear(black); update(); cmd(0xaf); // Display on } diff --git a/_examples/display_gc9a01/display_gc9a01.cpp b/_examples/display_gc9a01/display_gc9a01.cpp index f94215e..671749a 100644 --- a/_examples/display_gc9a01/display_gc9a01.cpp +++ b/_examples/display_gc9a01/display_gc9a01.cpp @@ -184,7 +184,7 @@ DisplayGc9a01::DisplayGc9a01() : buffer(nullptr) clear(0x00); cmd(0x29); // Display ON this_thread::sleep_for(20ms); - setTextColor(make_pair(Color(0xffff),Color(0x0))); + setTextColor(make_pair(Color::white(),Color::black())); } void DisplayGc9a01::doTurnOn() diff --git a/_examples/display_gc9a01/display_gc9a01.h b/_examples/display_gc9a01/display_gc9a01.h index ac662de..1018bd0 100644 --- a/_examples/display_gc9a01/display_gc9a01.h +++ b/_examples/display_gc9a01/display_gc9a01.h @@ -40,7 +40,7 @@ namespace mxgui { //This display is 16 bit per pixel, check that the color depth is properly //configured -#ifndef MXGUI_COLOR_DEPTH_16_BIT +#ifndef MXGUI_PIXEL_FORMAT_RGB565 #error The QMI8658 driver requires a color depth of 16bit per pixel #endif diff --git a/_examples/display_ser2p7s/display_ser2p7s.cpp b/_examples/display_ser2p7s/display_ser2p7s.cpp index 287cc4f..c83347b 100644 --- a/_examples/display_ser2p7s/display_ser2p7s.cpp +++ b/_examples/display_ser2p7s/display_ser2p7s.cpp @@ -26,6 +26,7 @@ ***************************************************************************/ #include "display_ser2p7s.h" +#include "misc_inst.h" #include "miosix.h" #include @@ -166,7 +167,7 @@ DisplaySer2p7s::DisplaySer2p7s() : DisplayGeneric4BPP(256,128) cmd(0xbe); data(0x04); // VCOMH cmd(0xb9); // Linear gamma table cmd(0xa6); // Normal display mode - clear(0); + clear(black); update(); cmd(0xaf); // Display on } diff --git a/_examples/particles/particles.cpp b/_examples/particles/particles.cpp index 14da8f4..40cce97 100644 --- a/_examples/particles/particles.cpp +++ b/_examples/particles/particles.cpp @@ -26,20 +26,19 @@ class Particle */ void fadeColor() { - if(color>0x800) color-=0x800; - if((color & 0x7c0)>0) color-=0x40; - if((color & 0x01f)>0) color--; + static constexpr RGB565Color decrement = RGB565Color::fromRaw(0x0841); + color = color - decrement; } /** * \return particle color */ - Color getColor() const { return color; } + Color getColor() const { return Color::fromRGB565(color); } /** * \param c new color of the particle */ - void setColor(Color c) { color=c; } + void setColor(RGB565Color c) { color=c; } /** * \return particle position @@ -65,7 +64,7 @@ class Particle //Object size 8byte Point position; signed char xSpeed_, ySpeed_; - unsigned short color; + RGB565Color color; }; /** @@ -75,11 +74,19 @@ class Particle */ static bool particleAnimation(Particle *particles) { - static const unsigned short rainbow[]= + static constexpr RGB565Color rainbow[]= { - 63489,63495,63501,63507,63513,63519,53279,40991,28703,16415,4127,287, - 671,1055,1439,1823,2045,2039,2033,2027,2021,2016,14304,26592,38880, - 51168,63456,65216,64832,64448,64064,65535 + RGB565Color::fromRaw(63489),RGB565Color::fromRaw(63495),RGB565Color::fromRaw(63501), + RGB565Color::fromRaw(63507),RGB565Color::fromRaw(63513),RGB565Color::fromRaw(63519), + RGB565Color::fromRaw(53279),RGB565Color::fromRaw(40991),RGB565Color::fromRaw(28703), + RGB565Color::fromRaw(16415),RGB565Color::fromRaw(4127),RGB565Color::fromRaw(287), + RGB565Color::fromRaw(671),RGB565Color::fromRaw(1055),RGB565Color::fromRaw(1439), + RGB565Color::fromRaw(1823),RGB565Color::fromRaw(2045),RGB565Color::fromRaw(2039), + RGB565Color::fromRaw(2033),RGB565Color::fromRaw(2027),RGB565Color::fromRaw(2021), + RGB565Color::fromRaw(2016),RGB565Color::fromRaw(14304),RGB565Color::fromRaw(26592), + RGB565Color::fromRaw(38880),RGB565Color::fromRaw(51168),RGB565Color::fromRaw(63456), + RGB565Color::fromRaw(65216),RGB565Color::fromRaw(64832),RGB565Color::fromRaw(64448), + RGB565Color::fromRaw(64064),RGB565Color::fromRaw(65535) }; static const int cosTab[]={0, 1, 1, 1, 0,-1,-1,-1}; diff --git a/_examples/rgb_gradient_test/main.cpp b/_examples/rgb_gradient_test/main.cpp index d9c6fc7..bdb7867 100644 --- a/_examples/rgb_gradient_test/main.cpp +++ b/_examples/rgb_gradient_test/main.cpp @@ -11,7 +11,7 @@ void drawGradientBar(DrawingContext& dc, int y0, int y1, int r, int g, int b) unsigned int rr = x * r / (dc.getWidth()-1); unsigned int gg = x * g / (dc.getWidth()-1); unsigned int bb = x * b / (dc.getWidth()-1); - Color col = bb + (gg << 5) + (rr << 11); + Color col = Color::fromRGB565(bb + (gg << 5) + (rr << 11)); dc.line(Point(x,y0), Point(x,y1-1), col); } } @@ -49,7 +49,7 @@ void drawDitherBar(DrawingContext& dc, int y0, int y1, int r, int g, int b) unsigned int rr = cap ? r : 0; unsigned int gg = cap ? g : 0; unsigned int bb = cap ? b : 0; - Color col = bb + (gg << 5) + (rr << 11); + Color col = Color::fromRGB565((rr << 11) | (gg << 5) | bb); dc.setPixel(Point(x, y0+y), col); } // Shift columns to the left by 1 in the error matrix @@ -64,7 +64,7 @@ void drawDitherBar(DrawingContext& dc, int y0, int y1, int r, int g, int b) ENTRY() { - #ifndef MXGUI_COLOR_DEPTH_16_BIT + #ifndef MXGUI_PIXEL_FORMAT_RGB565 #error "selected color depth not yet handled by this program" #endif // Display four gradients, one for gray and one for each primary color, diff --git a/_examples/sony-newman/tea-time/CMakeLists.txt b/_examples/sony-newman/tea-time/CMakeLists.txt index 9309094..e53cb2b 100644 --- a/_examples/sony-newman/tea-time/CMakeLists.txt +++ b/_examples/sony-newman/tea-time/CMakeLists.txt @@ -18,7 +18,7 @@ function(preprocess_png out_var) set(cpp "${CMAKE_CURRENT_SOURCE_DIR}/${path}/${basename}.cpp") set(h "${CMAKE_CURRENT_SOURCE_DIR}/${path}/${basename}.h") add_custom_command(OUTPUT ${cpp} ${h} - COMMAND ${PNGCONV_EXECUTABLE} --in ${png} --depth 16 + COMMAND ${PNGCONV_EXECUTABLE} --in ${png} --format rgb565 DEPENDS ${png} WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} COMMENT "Preprocessing ${file}" diff --git a/_examples/sony-newman/tea-time/Makefile b/_examples/sony-newman/tea-time/Makefile index 706b2ce..f96f075 100644 --- a/_examples/sony-newman/tea-time/Makefile +++ b/_examples/sony-newman/tea-time/Makefile @@ -43,7 +43,7 @@ SRC2 := $(IMG:.png=.cpp) # Images should be compiled first to prevent missing includes SRC := $(SRC2) $(SRC) %.cpp : %.png - ./mxgui/_tools/code_generators/build/pngconverter --in $< --depth 16 + ./mxgui/_tools/code_generators/build/pngconverter --in $< --format rgb565 # This prevents make from deleting the intermediate .cpp files .PRECIOUS: $(SRC2) diff --git a/_examples/swarm/swarm.cpp b/_examples/swarm/swarm.cpp index 65320f4..eb10361 100644 --- a/_examples/swarm/swarm.cpp +++ b/_examples/swarm/swarm.cpp @@ -51,6 +51,7 @@ from the X Consortium. #include "mxgui/entry.h" #include "mxgui/display.h" +#include "mxgui/color.h" #include "mxgui/misc_inst.h" #include #include @@ -491,22 +492,14 @@ static void randomSmallChange(state *st) static int redValueForHSBPhase(int phase, int value) { switch (phase%6) { - case 0: case 5: return 31; - case 1: return 31-value; + case 0: case 5: return 255; + case 1: return 255-value; case 2: case 3: return 0; default: case 4: return value; } } -static mxgui::Color mixColor(int r, int g, int b, int l) -{ - r = r * l / 31; - g = g * l / 31; - b = b * l / 31; - return r + (g << 6) + (b << (5+6)); -} - static void eraseLastBugsTrail(DrawingContext& dc, state *st) { bug *b; @@ -536,18 +529,24 @@ static void drawBugs(DrawingContext& dc, state *st) int huePhase = st->colorWheelTime / (COLOR_CHANGE_PERIOD/6); int value = st->colorWheelTime % (COLOR_CHANGE_PERIOD/6); - value = value*31/(COLOR_CHANGE_PERIOD/6); + value = value*255/(COLOR_CHANGE_PERIOD/6); int bugR, bugG, bugB, targetR, targetG, targetB; bugR = targetB = redValueForHSBPhase(huePhase, value); bugG = targetR = redValueForHSBPhase(huePhase+2, value); bugB = targetG = redValueForHSBPhase(huePhase+4, value); + mxgui::RGB888Color fullBugColor(bugR, bugG, bugB); + mxgui::RGB888Color fullTargetColor(targetR, targetG, targetB); for (j = st->tail; j != st->head; j = temp) { int t = (j-st->head)%st->trailLen-1; if (t<0) t += st->trailLen; - t = t*31/(st->trailLen-2); - mxgui::Color bugSegmentColor = mixColor(bugR, bugG, bugB, t); - mxgui::Color targetSegmentColor = mixColor(targetR, targetG, targetB, t); + unsigned char scale = t*255/(st->trailLen-2); + mxgui::RGB888Color bugDimmed = mxgui::RGB888Color::mix( + mxgui::RGB888Color::black(), fullBugColor, scale); + mxgui::RGB888Color targetDimmed = mxgui::RGB888Color::mix( + mxgui::RGB888Color::black(), fullTargetColor, scale); + mxgui::Color bugSegmentColor(bugDimmed.getR(), bugDimmed.getG(), bugDimmed.getB()); + mxgui::Color targetSegmentColor(targetDimmed.getR(), targetDimmed.getG(), targetDimmed.getB()); temp = (j+1)%st->trailLen; b = st->bugs; for (i = 0; i < st->nbugs; i++, b++) @@ -597,10 +596,6 @@ static void free(state *st) ENTRY() { - #ifndef MXGUI_COLOR_DEPTH_16_BIT - #error "selected color depth not yet handled by this program" - #endif - state *st = init(); #ifndef _MIOSIX for(;;) diff --git a/_examples/teapot/bresenham_fsm.cpp b/_examples/teapot/bresenham_fsm.cpp index 2f82b15..2758060 100644 --- a/_examples/teapot/bresenham_fsm.cpp +++ b/_examples/teapot/bresenham_fsm.cpp @@ -148,6 +148,7 @@ std::pair BresenhamFSM::getLinePoints() #include "mxgui/entry.h" #include "mxgui/display.h" #include "mxgui/misc_inst.h" +#include "misc_inst.h" #include #include @@ -156,7 +157,7 @@ using namespace mxgui; void ll(float angle) { DrawingContext dc(DisplayManager::instance().getDisplay()); - dc.clear(0); + dc.clear(black); Point a(240/2,320/2),b(240/2+100*std::cos(angle),320/2+100*std::sin(angle)); //Testcase for BresenhamFSM::drawScanLine() diff --git a/_examples/teapot/rendering_engine.cpp b/_examples/teapot/rendering_engine.cpp index 4a2857f..bc07719 100644 --- a/_examples/teapot/rendering_engine.cpp +++ b/_examples/teapot/rendering_engine.cpp @@ -212,7 +212,8 @@ void WireframeRenderingEngine::doRender(Display& disp) for(;start<=b.y();start++) { Color *lineBuffer=dc.getScanLineBuffer(); - memset(lineBuffer,0,sizeof(Color)*lineBufferSize); + // Use a loop to assign default Color for pixel format flexibility + for(int i=0; ifirst],xfmVertices[2*it->first+1]); @@ -324,7 +325,8 @@ void SolidRenderingEngine::doRender(Display& disp) for(;start<=b.y();start++) { Color *lineBuffer=dc.getScanLineBuffer(); - memset(lineBuffer,0,sizeof(Color)*lineBufferSize); + // Use a loop to assign default Color for pixel format flexibility + for(int i=0; i::iterator it2; for(it2=activeTriangles.begin();it2!=activeTriangles.end();) { diff --git a/_examples/teapot/teapot.cpp b/_examples/teapot/teapot.cpp index 0d1c3da..e229bbf 100644 --- a/_examples/teapot/teapot.cpp +++ b/_examples/teapot/teapot.cpp @@ -89,24 +89,36 @@ static void shadowRectangle(DrawingContext& dc, Point a, Point b) */ void drawButton(DrawingContext& dc, Point a, Point b, const char *s, bool click) { - static const unsigned short tlp[]={ - 61276,46420,31661,48565,33741,46452,31661,46452,57050 + static const Color tlp[]={ + Color::fromRGB565(61276),Color::fromRGB565(46420),Color::fromRGB565(31661), + Color::fromRGB565(48565),Color::fromRGB565(33741),Color::fromRGB565(46452), + Color::fromRGB565(31661),Color::fromRGB565(46452),Color::fromRGB565(57050) }; const Image tl(3,3,tlp); //Button top left - static const unsigned short trp[]={ - 31661,46420,61276,57050,31628,48565,48499,42161,31661 + static const Color trp[]={ + Color::fromRGB565(31661),Color::fromRGB565(46420),Color::fromRGB565(61276), + Color::fromRGB565(57050),Color::fromRGB565(31628),Color::fromRGB565(48565), + Color::fromRGB565(48499),Color::fromRGB565(42161),Color::fromRGB565(31661) }; const Image tr(3,3,trp); //Button top right - static const unsigned short blp[]={ - 31661,57050,48499,48565,33741,42225,61276,46420,31661 + static const Color blp[]={ + Color::fromRGB565(31661),Color::fromRGB565(57050),Color::fromRGB565(48499), + Color::fromRGB565(48565),Color::fromRGB565(33741),Color::fromRGB565(42225), + Color::fromRGB565(61276),Color::fromRGB565(46420),Color::fromRGB565(31661) }; const Image bl(3,3,blp); //Button bottom left - static const unsigned short brp[]={ - 48499,42161,31661,42225,33741,48565,31661,46420,61276 + static const Color brp[]={ + Color::fromRGB565(48499),Color::fromRGB565(42161),Color::fromRGB565(31661), + Color::fromRGB565(42225),Color::fromRGB565(33741),Color::fromRGB565(48565), + Color::fromRGB565(31661),Color::fromRGB565(46420),Color::fromRGB565(61276) }; const Image br(3,3,brp); //Button bottom right - static const unsigned short topColors[]={31628,59131,48499}; - static const unsigned short botColors[]={48499,48499,31628}; + static const Color topColors[]={ + Color::fromRGB565(31628),Color::fromRGB565(59131),Color::fromRGB565(48499) + }; + static const Color botColors[]={ + Color::fromRGB565(48499),Color::fromRGB565(48499),Color::fromRGB565(31628) + }; //Draw button corners dc.drawImage(a,tl); dc.drawImage(Point(b.x()-2,a.y()),tr); @@ -145,7 +157,7 @@ static RenderingEngine *configureSolid() { SolidRenderingEngine *result=new SolidRenderingEngine; result->setModel(vertices,numVertices,polygons,numPolygons); - result->setColors((const Color*)colors); + result->setColors(colors); result->setDrawArea(Point(1,1),Point(238,158)); result->setTranslation(Point(120,160)); return result; diff --git a/_examples/teapot/teapot_model.h b/_examples/teapot/teapot_model.h index cb835f3..eaf34b4 100644 --- a/_examples/teapot/teapot_model.h +++ b/_examples/teapot/teapot_model.h @@ -11,6 +11,8 @@ #ifndef TEAPOT_MODEL_H #define TEAPOT_MODEL_H +#include + static const int numVertices=480; static const int numPolygons=448; @@ -1036,456 +1038,456 @@ int main() } */ -static const unsigned short colors[]= +static const mxgui::Color colors[]= { - 0x37f, - 0x1df, - 0x1df, - 0x37f, - 0x35f, - 0x19f, - 0x19f, - 0x35f, - 0x31f, - 0x15f, - 0x15f, - 0x31f, - 0x2df, - 0x13f, - 0x13f, - 0x2df, - 0x69f, - 0x7f5, - 0x7e5, - 0x47e0, - 0x67f, - 0x7f6, - 0x7e6, - 0x3fe0, - 0x65f, - 0x7f6, - 0x7e6, - 0x47e0, - 0x65f, - 0x7f6, - 0x7e5, - 0x57e0, - 0x9fe0, - 0xcfe0, - 0xcfe0, - 0x9fe0, - 0x9fe0, - 0xcfe0, - 0xcfe0, - 0x9fe0, - 0x9fe0, - 0xcfe0, - 0xcfe0, - 0x9fe0, - 0xb7e0, - 0xe7e0, - 0xe7e0, - 0xb7e0, - 0x47e0, - 0x7e5, - 0x7f5, - 0x69f, - 0x3fe0, - 0x7e6, - 0x7f6, - 0x67f, - 0x47e0, - 0x7e6, - 0x7f6, - 0x65f, - 0x57e0, - 0x7e5, - 0x7f6, - 0x65f, - 0x31f, - 0x13f, - 0x13f, - 0x31f, - 0x39f, - 0x15f, - 0x15f, - 0x39f, - 0x43f, - 0x1ff, - 0x1ff, - 0x43f, - 0x55f, - 0x2df, - 0x2df, - 0x55f, - 0x69f, - 0x7f3, - 0x7e1, - 0x7fe0, - 0x79f, - 0x7ee, - 0x2fe0, - 0xbfe0, - 0x7fd, - 0x7e8, - 0x67e0, - 0xffe0, - 0x7f9, - 0x7e3, - 0x8fe0, - 0xfea0, - 0xdfe0, - 0xff60, - 0xff60, - 0xdfe0, - 0xfea0, - 0xfd00, - 0xfd00, - 0xfea0, - 0xfca0, - 0xfac0, - 0xfac0, - 0xfca0, - 0xfae0, - 0xf920, - 0xf920, - 0xfae0, - 0x7fe0, - 0x7e1, - 0x7f3, - 0x69f, - 0xbfe0, - 0x2fe0, - 0x7ee, - 0x79f, - 0xffe0, - 0x67e0, - 0x7e8, - 0x7fd, - 0xfea0, - 0x8fe0, - 0x7e3, - 0x7f9, - 0x6df, - 0x49f, - 0x49f, - 0x6df, - 0x7fd, - 0x67f, - 0x67f, - 0x7fd, - 0x7f6, - 0x7fd, - 0x7fd, - 0x7f6, - 0x7f1, - 0x7f8, - 0x7f8, - 0x7f1, - 0x7f3, - 0xfe0, - 0xb7e0, - 0xfda0, - 0x7ed, - 0x2fe0, - 0xcfe0, - 0xfd20, - 0x7e8, - 0x4fe0, - 0xd7e0, - 0xfd60, - 0x7e5, - 0x5fe0, - 0xdfe0, - 0xfd60, - 0xfa00, - 0xf820, - 0xf820, - 0xfa00, - 0xf9e0, - 0xf820, - 0xf820, - 0xf9e0, - 0xfa20, - 0xf8a0, - 0xf8a0, - 0xfa20, - 0xfaa0, - 0xf920, - 0xf920, - 0xfaa0, - 0xfda0, - 0xb7e0, - 0xfe0, - 0x7f3, - 0xfd20, - 0xcfe0, - 0x2fe0, - 0x7ed, - 0xfd60, - 0xd7e0, - 0x4fe0, - 0x7e8, - 0xfd60, - 0xdfe0, - 0x5fe0, - 0x7e5, - 0xe7e0, - 0xcfe0, - 0xcfe0, - 0xd7e0, - 0xfe60, - 0xfea0, - 0xfe80, - 0xfde0, - 0xfc40, - 0xfca0, - 0xfc40, - 0xfb80, - 0xfb20, - 0xfb20, - 0xfac0, - 0xf9e0, - 0xefe0, - 0xffe0, - 0xffa0, - 0xffe0, - 0xfd20, - 0xfca0, - 0xfce0, - 0xfd60, - 0xfaa0, - 0xfa60, - 0xfac0, - 0xfb80, - 0xf920, - 0xf8e0, - 0xf960, - 0xfa60, - 0xfaa0, - 0xfaa0, - 0xf9e0, - 0xf8e0, - 0xfa20, - 0xfa60, - 0xf9a0, - 0xf8a0, - 0xfaa0, - 0xfac0, - 0xfa20, - 0xf940, - 0xfb80, - 0xfba0, - 0xfb80, - 0xfac0, - 0xf820, - 0xf800, - 0xf8a0, - 0xf9a0, - 0xf800, - 0xf800, - 0xf880, - 0xf960, - 0xf880, - 0xf860, - 0xf8e0, - 0xf9e0, - 0xfa00, - 0xf9a0, - 0xfa00, - 0xfaa0, - 0x4ff, - 0x43f, - 0x4ff, - 0x71f, - 0x2bf, - 0x1df, - 0x1ff, - 0x37f, - 0x11f, - 0x1f, - 0x1f, - 0x9f, - 0x181f, - 0x381f, - 0x481f, - 0x481f, - 0x7fc, - 0x7f9, - 0x7fc, - 0x6df, - 0x51f, - 0x61f, - 0x5bf, - 0x45f, - 0x1ff, - 0x2df, - 0x31f, - 0x25f, - 0x201f, - 0x1f, - 0x7f, - 0x5f, - 0x381f, - 0x601f, - 0x781f, - 0x781f, - 0x481f, - 0x681f, - 0x801f, - 0x801f, - 0x481f, - 0x681f, - 0x801f, - 0x801f, - 0x381f, - 0x501f, - 0x681f, - 0x681f, - 0x601f, - 0x381f, - 0x201f, - 0x201f, - 0x681f, - 0x481f, - 0x301f, - 0x301f, - 0x681f, - 0x501f, - 0x301f, - 0x301f, - 0x601f, - 0x481f, - 0x301f, - 0x301f, - 0x7fd, - 0x7ff, - 0x7ff, - 0x7fd, - 0x7ff, - 0x79f, - 0x79f, - 0x7ff, - 0x7fc, - 0x7fd, - 0x7fd, - 0x7fc, - 0x7f9, - 0x7fa, - 0x7fa, - 0x7f9, - 0x7fb, - 0x7f9, - 0x7f7, - 0x7f4, - 0x7fd, - 0x7f9, - 0x7f5, - 0x7f1, - 0x7fa, - 0x7f7, - 0x7f4, - 0x7f1, - 0x7f7, - 0x7f5, - 0x7f3, - 0x7f1, - 0x7f2, - 0x7f1, - 0x7f1, - 0x7f2, - 0x7ee, - 0x7ed, - 0x7ed, - 0x7ee, - 0x7ef, - 0x7ee, - 0x7ee, - 0x7ef, - 0x7ef, - 0x7ee, - 0x7ee, - 0x7ef, - 0x7f4, - 0x7f7, - 0x7f9, - 0x7fb, - 0x7f1, - 0x7f5, - 0x7f9, - 0x7fd, - 0x7f1, - 0x7f4, - 0x7f7, - 0x7fa, - 0x7f1, - 0x7f3, - 0x7f5, - 0x7f7, - 0x7fb, - 0x7fd, - 0x7fd, - 0x7fb, - 0x75f, - 0x69f, - 0x69f, - 0x75f, - 0x59f, - 0x45f, - 0x45f, - 0x59f, - 0x45f, - 0x2df, - 0x2df, - 0x45f, - 0x7f8, - 0x7f4, - 0x7f1, - 0x7ed, - 0x7fc, - 0x7f5, - 0x7ee, - 0x7e7, - 0x7df, - 0x7f5, - 0x7ea, - 0x7e0, - 0x73f, - 0x7f5, - 0x7e7, - 0x2fe0, - 0x7eb, - 0x7e9, - 0x7e9, - 0x7eb, - 0x7e2, - 0xfe0, - 0xfe0, - 0x7e2, - 0x3fe0, - 0x67e0, - 0x67e0, - 0x3fe0, - 0x7fe0, - 0xa7e0, - 0xa7e0, - 0x7fe0, - 0x7ed, - 0x7f1, - 0x7f4, - 0x7f8, - 0x7e7, - 0x7ee, - 0x7f5, - 0x7fc, - 0x7e0, - 0x7ea, - 0x7f5, - 0x7df, - 0x2fe0, - 0x7e7, - 0x7f5, - 0x73f + mxgui::Color::fromRGB565(0x37f), + mxgui::Color::fromRGB565(0x1df), + mxgui::Color::fromRGB565(0x1df), + mxgui::Color::fromRGB565(0x37f), + mxgui::Color::fromRGB565(0x35f), + mxgui::Color::fromRGB565(0x19f), + mxgui::Color::fromRGB565(0x19f), + mxgui::Color::fromRGB565(0x35f), + mxgui::Color::fromRGB565(0x31f), + mxgui::Color::fromRGB565(0x15f), + mxgui::Color::fromRGB565(0x15f), + mxgui::Color::fromRGB565(0x31f), + mxgui::Color::fromRGB565(0x2df), + mxgui::Color::fromRGB565(0x13f), + mxgui::Color::fromRGB565(0x13f), + mxgui::Color::fromRGB565(0x2df), + mxgui::Color::fromRGB565(0x69f), + mxgui::Color::fromRGB565(0x7f5), + mxgui::Color::fromRGB565(0x7e5), + mxgui::Color::fromRGB565(0x47e0), + mxgui::Color::fromRGB565(0x67f), + mxgui::Color::fromRGB565(0x7f6), + mxgui::Color::fromRGB565(0x7e6), + mxgui::Color::fromRGB565(0x3fe0), + mxgui::Color::fromRGB565(0x65f), + mxgui::Color::fromRGB565(0x7f6), + mxgui::Color::fromRGB565(0x7e6), + mxgui::Color::fromRGB565(0x47e0), + mxgui::Color::fromRGB565(0x65f), + mxgui::Color::fromRGB565(0x7f6), + mxgui::Color::fromRGB565(0x7e5), + mxgui::Color::fromRGB565(0x57e0), + mxgui::Color::fromRGB565(0x9fe0), + mxgui::Color::fromRGB565(0xcfe0), + mxgui::Color::fromRGB565(0xcfe0), + mxgui::Color::fromRGB565(0x9fe0), + mxgui::Color::fromRGB565(0x9fe0), + mxgui::Color::fromRGB565(0xcfe0), + mxgui::Color::fromRGB565(0xcfe0), + mxgui::Color::fromRGB565(0x9fe0), + mxgui::Color::fromRGB565(0x9fe0), + mxgui::Color::fromRGB565(0xcfe0), + mxgui::Color::fromRGB565(0xcfe0), + mxgui::Color::fromRGB565(0x9fe0), + mxgui::Color::fromRGB565(0xb7e0), + mxgui::Color::fromRGB565(0xe7e0), + mxgui::Color::fromRGB565(0xe7e0), + mxgui::Color::fromRGB565(0xb7e0), + mxgui::Color::fromRGB565(0x47e0), + mxgui::Color::fromRGB565(0x7e5), + mxgui::Color::fromRGB565(0x7f5), + mxgui::Color::fromRGB565(0x69f), + mxgui::Color::fromRGB565(0x3fe0), + mxgui::Color::fromRGB565(0x7e6), + mxgui::Color::fromRGB565(0x7f6), + mxgui::Color::fromRGB565(0x67f), + mxgui::Color::fromRGB565(0x47e0), + mxgui::Color::fromRGB565(0x7e6), + mxgui::Color::fromRGB565(0x7f6), + mxgui::Color::fromRGB565(0x65f), + mxgui::Color::fromRGB565(0x57e0), + mxgui::Color::fromRGB565(0x7e5), + mxgui::Color::fromRGB565(0x7f6), + mxgui::Color::fromRGB565(0x65f), + mxgui::Color::fromRGB565(0x31f), + mxgui::Color::fromRGB565(0x13f), + mxgui::Color::fromRGB565(0x13f), + mxgui::Color::fromRGB565(0x31f), + mxgui::Color::fromRGB565(0x39f), + mxgui::Color::fromRGB565(0x15f), + mxgui::Color::fromRGB565(0x15f), + mxgui::Color::fromRGB565(0x39f), + mxgui::Color::fromRGB565(0x43f), + mxgui::Color::fromRGB565(0x1ff), + mxgui::Color::fromRGB565(0x1ff), + mxgui::Color::fromRGB565(0x43f), + mxgui::Color::fromRGB565(0x55f), + mxgui::Color::fromRGB565(0x2df), + mxgui::Color::fromRGB565(0x2df), + mxgui::Color::fromRGB565(0x55f), + mxgui::Color::fromRGB565(0x69f), + mxgui::Color::fromRGB565(0x7f3), + mxgui::Color::fromRGB565(0x7e1), + mxgui::Color::fromRGB565(0x7fe0), + mxgui::Color::fromRGB565(0x79f), + mxgui::Color::fromRGB565(0x7ee), + mxgui::Color::fromRGB565(0x2fe0), + mxgui::Color::fromRGB565(0xbfe0), + mxgui::Color::fromRGB565(0x7fd), + mxgui::Color::fromRGB565(0x7e8), + mxgui::Color::fromRGB565(0x67e0), + mxgui::Color::fromRGB565(0xffe0), + mxgui::Color::fromRGB565(0x7f9), + mxgui::Color::fromRGB565(0x7e3), + mxgui::Color::fromRGB565(0x8fe0), + mxgui::Color::fromRGB565(0xfea0), + mxgui::Color::fromRGB565(0xdfe0), + mxgui::Color::fromRGB565(0xff60), + mxgui::Color::fromRGB565(0xff60), + mxgui::Color::fromRGB565(0xdfe0), + mxgui::Color::fromRGB565(0xfea0), + mxgui::Color::fromRGB565(0xfd00), + mxgui::Color::fromRGB565(0xfd00), + mxgui::Color::fromRGB565(0xfea0), + mxgui::Color::fromRGB565(0xfca0), + mxgui::Color::fromRGB565(0xfac0), + mxgui::Color::fromRGB565(0xfac0), + mxgui::Color::fromRGB565(0xfca0), + mxgui::Color::fromRGB565(0xfae0), + mxgui::Color::fromRGB565(0xf920), + mxgui::Color::fromRGB565(0xf920), + mxgui::Color::fromRGB565(0xfae0), + mxgui::Color::fromRGB565(0x7fe0), + mxgui::Color::fromRGB565(0x7e1), + mxgui::Color::fromRGB565(0x7f3), + mxgui::Color::fromRGB565(0x69f), + mxgui::Color::fromRGB565(0xbfe0), + mxgui::Color::fromRGB565(0x2fe0), + mxgui::Color::fromRGB565(0x7ee), + mxgui::Color::fromRGB565(0x79f), + mxgui::Color::fromRGB565(0xffe0), + mxgui::Color::fromRGB565(0x67e0), + mxgui::Color::fromRGB565(0x7e8), + mxgui::Color::fromRGB565(0x7fd), + mxgui::Color::fromRGB565(0xfea0), + mxgui::Color::fromRGB565(0x8fe0), + mxgui::Color::fromRGB565(0x7e3), + mxgui::Color::fromRGB565(0x7f9), + mxgui::Color::fromRGB565(0x6df), + mxgui::Color::fromRGB565(0x49f), + mxgui::Color::fromRGB565(0x49f), + mxgui::Color::fromRGB565(0x6df), + mxgui::Color::fromRGB565(0x7fd), + mxgui::Color::fromRGB565(0x67f), + mxgui::Color::fromRGB565(0x67f), + mxgui::Color::fromRGB565(0x7fd), + mxgui::Color::fromRGB565(0x7f6), + mxgui::Color::fromRGB565(0x7fd), + mxgui::Color::fromRGB565(0x7fd), + mxgui::Color::fromRGB565(0x7f6), + mxgui::Color::fromRGB565(0x7f1), + mxgui::Color::fromRGB565(0x7f8), + mxgui::Color::fromRGB565(0x7f8), + mxgui::Color::fromRGB565(0x7f1), + mxgui::Color::fromRGB565(0x7f3), + mxgui::Color::fromRGB565(0xfe0), + mxgui::Color::fromRGB565(0xb7e0), + mxgui::Color::fromRGB565(0xfda0), + mxgui::Color::fromRGB565(0x7ed), + mxgui::Color::fromRGB565(0x2fe0), + mxgui::Color::fromRGB565(0xcfe0), + mxgui::Color::fromRGB565(0xfd20), + mxgui::Color::fromRGB565(0x7e8), + mxgui::Color::fromRGB565(0x4fe0), + mxgui::Color::fromRGB565(0xd7e0), + mxgui::Color::fromRGB565(0xfd60), + mxgui::Color::fromRGB565(0x7e5), + mxgui::Color::fromRGB565(0x5fe0), + mxgui::Color::fromRGB565(0xdfe0), + mxgui::Color::fromRGB565(0xfd60), + mxgui::Color::fromRGB565(0xfa00), + mxgui::Color::fromRGB565(0xf820), + mxgui::Color::fromRGB565(0xf820), + mxgui::Color::fromRGB565(0xfa00), + mxgui::Color::fromRGB565(0xf9e0), + mxgui::Color::fromRGB565(0xf820), + mxgui::Color::fromRGB565(0xf820), + mxgui::Color::fromRGB565(0xf9e0), + mxgui::Color::fromRGB565(0xfa20), + mxgui::Color::fromRGB565(0xf8a0), + mxgui::Color::fromRGB565(0xf8a0), + mxgui::Color::fromRGB565(0xfa20), + mxgui::Color::fromRGB565(0xfaa0), + mxgui::Color::fromRGB565(0xf920), + mxgui::Color::fromRGB565(0xf920), + mxgui::Color::fromRGB565(0xfaa0), + mxgui::Color::fromRGB565(0xfda0), + mxgui::Color::fromRGB565(0xb7e0), + mxgui::Color::fromRGB565(0xfe0), + mxgui::Color::fromRGB565(0x7f3), + mxgui::Color::fromRGB565(0xfd20), + mxgui::Color::fromRGB565(0xcfe0), + mxgui::Color::fromRGB565(0x2fe0), + mxgui::Color::fromRGB565(0x7ed), + mxgui::Color::fromRGB565(0xfd60), + mxgui::Color::fromRGB565(0xd7e0), + mxgui::Color::fromRGB565(0x4fe0), + mxgui::Color::fromRGB565(0x7e8), + mxgui::Color::fromRGB565(0xfd60), + mxgui::Color::fromRGB565(0xdfe0), + mxgui::Color::fromRGB565(0x5fe0), + mxgui::Color::fromRGB565(0x7e5), + mxgui::Color::fromRGB565(0xe7e0), + mxgui::Color::fromRGB565(0xcfe0), + mxgui::Color::fromRGB565(0xcfe0), + mxgui::Color::fromRGB565(0xd7e0), + mxgui::Color::fromRGB565(0xfe60), + mxgui::Color::fromRGB565(0xfea0), + mxgui::Color::fromRGB565(0xfe80), + mxgui::Color::fromRGB565(0xfde0), + mxgui::Color::fromRGB565(0xfc40), + mxgui::Color::fromRGB565(0xfca0), + mxgui::Color::fromRGB565(0xfc40), + mxgui::Color::fromRGB565(0xfb80), + mxgui::Color::fromRGB565(0xfb20), + mxgui::Color::fromRGB565(0xfb20), + mxgui::Color::fromRGB565(0xfac0), + mxgui::Color::fromRGB565(0xf9e0), + mxgui::Color::fromRGB565(0xefe0), + mxgui::Color::fromRGB565(0xffe0), + mxgui::Color::fromRGB565(0xffa0), + mxgui::Color::fromRGB565(0xffe0), + mxgui::Color::fromRGB565(0xfd20), + mxgui::Color::fromRGB565(0xfca0), + mxgui::Color::fromRGB565(0xfce0), + mxgui::Color::fromRGB565(0xfd60), + mxgui::Color::fromRGB565(0xfaa0), + mxgui::Color::fromRGB565(0xfa60), + mxgui::Color::fromRGB565(0xfac0), + mxgui::Color::fromRGB565(0xfb80), + mxgui::Color::fromRGB565(0xf920), + mxgui::Color::fromRGB565(0xf8e0), + mxgui::Color::fromRGB565(0xf960), + mxgui::Color::fromRGB565(0xfa60), + mxgui::Color::fromRGB565(0xfaa0), + mxgui::Color::fromRGB565(0xfaa0), + mxgui::Color::fromRGB565(0xf9e0), + mxgui::Color::fromRGB565(0xf8e0), + mxgui::Color::fromRGB565(0xfa20), + mxgui::Color::fromRGB565(0xfa60), + mxgui::Color::fromRGB565(0xf9a0), + mxgui::Color::fromRGB565(0xf8a0), + mxgui::Color::fromRGB565(0xfaa0), + mxgui::Color::fromRGB565(0xfac0), + mxgui::Color::fromRGB565(0xfa20), + mxgui::Color::fromRGB565(0xf940), + mxgui::Color::fromRGB565(0xfb80), + mxgui::Color::fromRGB565(0xfba0), + mxgui::Color::fromRGB565(0xfb80), + mxgui::Color::fromRGB565(0xfac0), + mxgui::Color::fromRGB565(0xf820), + mxgui::Color::fromRGB565(0xf800), + mxgui::Color::fromRGB565(0xf8a0), + mxgui::Color::fromRGB565(0xf9a0), + mxgui::Color::fromRGB565(0xf800), + mxgui::Color::fromRGB565(0xf800), + mxgui::Color::fromRGB565(0xf880), + mxgui::Color::fromRGB565(0xf960), + mxgui::Color::fromRGB565(0xf880), + mxgui::Color::fromRGB565(0xf860), + mxgui::Color::fromRGB565(0xf8e0), + mxgui::Color::fromRGB565(0xf9e0), + mxgui::Color::fromRGB565(0xfa00), + mxgui::Color::fromRGB565(0xf9a0), + mxgui::Color::fromRGB565(0xfa00), + mxgui::Color::fromRGB565(0xfaa0), + mxgui::Color::fromRGB565(0x4ff), + mxgui::Color::fromRGB565(0x43f), + mxgui::Color::fromRGB565(0x4ff), + mxgui::Color::fromRGB565(0x71f), + mxgui::Color::fromRGB565(0x2bf), + mxgui::Color::fromRGB565(0x1df), + mxgui::Color::fromRGB565(0x1ff), + mxgui::Color::fromRGB565(0x37f), + mxgui::Color::fromRGB565(0x11f), + mxgui::Color::fromRGB565(0x1f), + mxgui::Color::fromRGB565(0x1f), + mxgui::Color::fromRGB565(0x9f), + mxgui::Color::fromRGB565(0x181f), + mxgui::Color::fromRGB565(0x381f), + mxgui::Color::fromRGB565(0x481f), + mxgui::Color::fromRGB565(0x481f), + mxgui::Color::fromRGB565(0x7fc), + mxgui::Color::fromRGB565(0x7f9), + mxgui::Color::fromRGB565(0x7fc), + mxgui::Color::fromRGB565(0x6df), + mxgui::Color::fromRGB565(0x51f), + mxgui::Color::fromRGB565(0x61f), + mxgui::Color::fromRGB565(0x5bf), + mxgui::Color::fromRGB565(0x45f), + mxgui::Color::fromRGB565(0x1ff), + mxgui::Color::fromRGB565(0x2df), + mxgui::Color::fromRGB565(0x31f), + mxgui::Color::fromRGB565(0x25f), + mxgui::Color::fromRGB565(0x201f), + mxgui::Color::fromRGB565(0x1f), + mxgui::Color::fromRGB565(0x7f), + mxgui::Color::fromRGB565(0x5f), + mxgui::Color::fromRGB565(0x381f), + mxgui::Color::fromRGB565(0x601f), + mxgui::Color::fromRGB565(0x781f), + mxgui::Color::fromRGB565(0x781f), + mxgui::Color::fromRGB565(0x481f), + mxgui::Color::fromRGB565(0x681f), + mxgui::Color::fromRGB565(0x801f), + mxgui::Color::fromRGB565(0x801f), + mxgui::Color::fromRGB565(0x481f), + mxgui::Color::fromRGB565(0x681f), + mxgui::Color::fromRGB565(0x801f), + mxgui::Color::fromRGB565(0x801f), + mxgui::Color::fromRGB565(0x381f), + mxgui::Color::fromRGB565(0x501f), + mxgui::Color::fromRGB565(0x681f), + mxgui::Color::fromRGB565(0x681f), + mxgui::Color::fromRGB565(0x601f), + mxgui::Color::fromRGB565(0x381f), + mxgui::Color::fromRGB565(0x201f), + mxgui::Color::fromRGB565(0x201f), + mxgui::Color::fromRGB565(0x681f), + mxgui::Color::fromRGB565(0x481f), + mxgui::Color::fromRGB565(0x301f), + mxgui::Color::fromRGB565(0x301f), + mxgui::Color::fromRGB565(0x681f), + mxgui::Color::fromRGB565(0x501f), + mxgui::Color::fromRGB565(0x301f), + mxgui::Color::fromRGB565(0x301f), + mxgui::Color::fromRGB565(0x601f), + mxgui::Color::fromRGB565(0x481f), + mxgui::Color::fromRGB565(0x301f), + mxgui::Color::fromRGB565(0x301f), + mxgui::Color::fromRGB565(0x7fd), + mxgui::Color::fromRGB565(0x7ff), + mxgui::Color::fromRGB565(0x7ff), + mxgui::Color::fromRGB565(0x7fd), + mxgui::Color::fromRGB565(0x7ff), + mxgui::Color::fromRGB565(0x79f), + mxgui::Color::fromRGB565(0x79f), + mxgui::Color::fromRGB565(0x7ff), + mxgui::Color::fromRGB565(0x7fc), + mxgui::Color::fromRGB565(0x7fd), + mxgui::Color::fromRGB565(0x7fd), + mxgui::Color::fromRGB565(0x7fc), + mxgui::Color::fromRGB565(0x7f9), + mxgui::Color::fromRGB565(0x7fa), + mxgui::Color::fromRGB565(0x7fa), + mxgui::Color::fromRGB565(0x7f9), + mxgui::Color::fromRGB565(0x7fb), + mxgui::Color::fromRGB565(0x7f9), + mxgui::Color::fromRGB565(0x7f7), + mxgui::Color::fromRGB565(0x7f4), + mxgui::Color::fromRGB565(0x7fd), + mxgui::Color::fromRGB565(0x7f9), + mxgui::Color::fromRGB565(0x7f5), + mxgui::Color::fromRGB565(0x7f1), + mxgui::Color::fromRGB565(0x7fa), + mxgui::Color::fromRGB565(0x7f7), + mxgui::Color::fromRGB565(0x7f4), + mxgui::Color::fromRGB565(0x7f1), + mxgui::Color::fromRGB565(0x7f7), + mxgui::Color::fromRGB565(0x7f5), + mxgui::Color::fromRGB565(0x7f3), + mxgui::Color::fromRGB565(0x7f1), + mxgui::Color::fromRGB565(0x7f2), + mxgui::Color::fromRGB565(0x7f1), + mxgui::Color::fromRGB565(0x7f1), + mxgui::Color::fromRGB565(0x7f2), + mxgui::Color::fromRGB565(0x7ee), + mxgui::Color::fromRGB565(0x7ed), + mxgui::Color::fromRGB565(0x7ed), + mxgui::Color::fromRGB565(0x7ee), + mxgui::Color::fromRGB565(0x7ef), + mxgui::Color::fromRGB565(0x7ee), + mxgui::Color::fromRGB565(0x7ee), + mxgui::Color::fromRGB565(0x7ef), + mxgui::Color::fromRGB565(0x7ef), + mxgui::Color::fromRGB565(0x7ee), + mxgui::Color::fromRGB565(0x7ee), + mxgui::Color::fromRGB565(0x7ef), + mxgui::Color::fromRGB565(0x7f4), + mxgui::Color::fromRGB565(0x7f7), + mxgui::Color::fromRGB565(0x7f9), + mxgui::Color::fromRGB565(0x7fb), + mxgui::Color::fromRGB565(0x7f1), + mxgui::Color::fromRGB565(0x7f5), + mxgui::Color::fromRGB565(0x7f9), + mxgui::Color::fromRGB565(0x7fd), + mxgui::Color::fromRGB565(0x7f1), + mxgui::Color::fromRGB565(0x7f4), + mxgui::Color::fromRGB565(0x7f7), + mxgui::Color::fromRGB565(0x7fa), + mxgui::Color::fromRGB565(0x7f1), + mxgui::Color::fromRGB565(0x7f3), + mxgui::Color::fromRGB565(0x7f5), + mxgui::Color::fromRGB565(0x7f7), + mxgui::Color::fromRGB565(0x7fb), + mxgui::Color::fromRGB565(0x7fd), + mxgui::Color::fromRGB565(0x7fd), + mxgui::Color::fromRGB565(0x7fb), + mxgui::Color::fromRGB565(0x75f), + mxgui::Color::fromRGB565(0x69f), + mxgui::Color::fromRGB565(0x69f), + mxgui::Color::fromRGB565(0x75f), + mxgui::Color::fromRGB565(0x59f), + mxgui::Color::fromRGB565(0x45f), + mxgui::Color::fromRGB565(0x45f), + mxgui::Color::fromRGB565(0x59f), + mxgui::Color::fromRGB565(0x45f), + mxgui::Color::fromRGB565(0x2df), + mxgui::Color::fromRGB565(0x2df), + mxgui::Color::fromRGB565(0x45f), + mxgui::Color::fromRGB565(0x7f8), + mxgui::Color::fromRGB565(0x7f4), + mxgui::Color::fromRGB565(0x7f1), + mxgui::Color::fromRGB565(0x7ed), + mxgui::Color::fromRGB565(0x7fc), + mxgui::Color::fromRGB565(0x7f5), + mxgui::Color::fromRGB565(0x7ee), + mxgui::Color::fromRGB565(0x7e7), + mxgui::Color::fromRGB565(0x7df), + mxgui::Color::fromRGB565(0x7f5), + mxgui::Color::fromRGB565(0x7ea), + mxgui::Color::fromRGB565(0x7e0), + mxgui::Color::fromRGB565(0x73f), + mxgui::Color::fromRGB565(0x7f5), + mxgui::Color::fromRGB565(0x7e7), + mxgui::Color::fromRGB565(0x2fe0), + mxgui::Color::fromRGB565(0x7eb), + mxgui::Color::fromRGB565(0x7e9), + mxgui::Color::fromRGB565(0x7e9), + mxgui::Color::fromRGB565(0x7eb), + mxgui::Color::fromRGB565(0x7e2), + mxgui::Color::fromRGB565(0xfe0), + mxgui::Color::fromRGB565(0xfe0), + mxgui::Color::fromRGB565(0x7e2), + mxgui::Color::fromRGB565(0x3fe0), + mxgui::Color::fromRGB565(0x67e0), + mxgui::Color::fromRGB565(0x67e0), + mxgui::Color::fromRGB565(0x3fe0), + mxgui::Color::fromRGB565(0x7fe0), + mxgui::Color::fromRGB565(0xa7e0), + mxgui::Color::fromRGB565(0xa7e0), + mxgui::Color::fromRGB565(0x7fe0), + mxgui::Color::fromRGB565(0x7ed), + mxgui::Color::fromRGB565(0x7f1), + mxgui::Color::fromRGB565(0x7f4), + mxgui::Color::fromRGB565(0x7f8), + mxgui::Color::fromRGB565(0x7e7), + mxgui::Color::fromRGB565(0x7ee), + mxgui::Color::fromRGB565(0x7f5), + mxgui::Color::fromRGB565(0x7fc), + mxgui::Color::fromRGB565(0x7e0), + mxgui::Color::fromRGB565(0x7ea), + mxgui::Color::fromRGB565(0x7f5), + mxgui::Color::fromRGB565(0x7df), + mxgui::Color::fromRGB565(0x2fe0), + mxgui::Color::fromRGB565(0x7e7), + mxgui::Color::fromRGB565(0x7f5), + mxgui::Color::fromRGB565(0x73f) }; #endif //TEAPOT_MODEL_H diff --git a/_tools/code_generators/pngconverter.cpp b/_tools/code_generators/pngconverter.cpp index 1e3cd5e..8971c65 100644 --- a/_tools/code_generators/pngconverter.cpp +++ b/_tools/code_generators/pngconverter.cpp @@ -18,8 +18,7 @@ /* * pngconverter.cpp * convert a png image into a .cpp file to be used with mxgui. - * number of bit per pixel of output image can be configured as - * 1bitlinear, 8, 16, 18 or 24. + * Supported pixel formats: gray1, gray4, rgb332, rgb565. */ #include @@ -69,23 +68,21 @@ static string toUpper(const string& x) // class ImageWriter // -std::shared_ptr ImageWriter::fromPixDepth(image& img, - bool binary, PixDepth pd) +std::shared_ptr ImageWriter::fromPixelFormat(image& img, + bool binary, PixelFormat pf) { - switch(pd) + switch(pf) { - case _1bitlinear: - return shared_ptr(new ImageWriter1bitLinear(img,binary)); - case _8: - return shared_ptr(new ImageWriter8bit(img,binary)); - case _16: - return shared_ptr(new ImageWriter16bit(img,binary)); - case _18: - return shared_ptr(new ImageWriter18bit(img,binary)); - case _24: - return shared_ptr(new ImageWriter24bit(img,binary)); + case PixelFormat::Gray1: + return shared_ptr(new ImageWriterGray1(img,binary)); + case PixelFormat::Gray4: + return shared_ptr(new ImageWriterGray4(img,binary)); + case PixelFormat::RGB332: + return shared_ptr(new ImageWriterRGB332(img,binary)); + case PixelFormat::RGB565: + return shared_ptr(new ImageWriterRGB565(img,binary)); default: - throw runtime_error("Unsupported pixel depth"); + throw runtime_error("Unsupported pixel format"); } } @@ -114,10 +111,10 @@ void ImageWriter::write(ofstream& out, image *outImage) } // -// class ImageWriter1bitLinear +// class ImageWriterGray1 // -void ImageWriter1bitLinear::write(ofstream& out, +void ImageWriterGray1::write(ofstream& out, image *outImage) { int numPerLine=0;//Number of pixel per line. when reaches limit, wrap @@ -180,10 +177,88 @@ void ImageWriter1bitLinear::write(ofstream& out, } // -// class ImageWriter8bit +// class ImageWriterGray4 // -void ImageWriter8bit::writePixel(int x, int y, ofstream& out, +void ImageWriterGray4::write(ofstream& out, + image *outImage) +{ + int numPerLine=0;//Number of pixel per line. when reaches limit, wrap + int ctr=0; + unsigned char buffer=0; + for(int y=0;y> 12 + unsigned char gray = (pix.red * 77 + pix.green * 150 + pix.blue * 29) >> 12; + if (gray > 15) gray = 15; + + if(outImage) + { + // Convert back to RGB for preview + unsigned char c = (gray << 4) | gray; + outImage->set_pixel(x,y,rgb_pixel(c,c,c)); + } + + // Pack into buffer. MSB first means first pixel is in high nibble. + if(ctr==0) + { + buffer = (gray << 4); + ctr++; + } + else + { + buffer |= (gray & 0x0F); + ctr=0; + + // Write byte + if(binary) out.write(reinterpret_cast(&buffer),1); + else { + out<<"0x"<(buffer)<(&buffer),1); + else { + out<<"0x"<(buffer)< *outImage, rgb_pixel pix) { unsigned int r=pix.red & (7<<5); @@ -194,15 +269,16 @@ void ImageWriter8bit::writePixel(int x, int y, ofstream& out, { unsigned char c=static_cast(i); out.write(reinterpret_cast(&c),1); - } else out<set_pixel(x,y,rgb_pixel(r,g,b)); } // -// class ImageWriter16bit +// class ImageWriterRGB565 // -void ImageWriter16bit::writePixel(int x, int y, ofstream& out, +void ImageWriterRGB565::writePixel(int x, int y, ofstream& out, png::image *outImage, rgb_pixel pix) { unsigned int r=(pix.red & (31<<3))>>3; @@ -213,39 +289,10 @@ void ImageWriter16bit::writePixel(int x, int y, ofstream& out, { unsigned short s=toLittleEndian(static_cast(i)); out.write(reinterpret_cast(&s),2); - } else out<set_pixel(x,y,rgb_pixel(r,g,b)); } -// -// class ImageWriter18bit -// - -void ImageWriter18bit::writePixel(int x, int y, ofstream& out, - png::image *outImage, rgb_pixel pix) -{ - throw(runtime_error("Implement me")); -// r=pix.red & 0xfc; -// g=pix.green & 0xfc; -// b=pix.blue & 0xfc; -// file<<(r>>2)<<','<<(g>>2)<<','<<(b>>2); -// if(outRequested) outImage.set_pixel(x,y,rgb_pixel(r,g,b)); -} - -// -// class ImageWriter24bit -// - -void ImageWriter24bit::writePixel(int x, int y, ofstream& out, - png::image *outImage, rgb_pixel pix) -{ - throw(runtime_error("Implement me")); -// file<<(int)(pix.red)<<',' -// <<(int)(pix.green)<<',' -// <<(int)(pix.blue); -// if(outRequested) outImage.set_pixel(x,y,pix); -} - int main(int argc, char *argv[]) { //Check args @@ -254,7 +301,7 @@ int main(int argc, char *argv[]) desc.add_options() ("help", "Prints this.") ("in", value(), "Input png file (required)") - ("depth", value(), "Color depth, 1bitlinear,8,16,18 or 24 bits (required)") + ("format", value(), "Pixel format: gray1, gray4, rgb332, rgb565 (required)") ("out", value(), "Output png file for validation") ("outdir", value(), "Directory where to generate files (default is src dir)") ("binary", "Generate a binary file instead of a .cpp/.h file") @@ -264,7 +311,7 @@ int main(int argc, char *argv[]) store(parse_command_line(argc,argv,desc),vm); notify(vm); - if(vm.count("help") || (!vm.count("in")) || (!vm.count("depth"))) + if(vm.count("help") || (!vm.count("in")) || (!vm.count("format"))) { cerr<(); - PixDepth pixDepth; - int pixDepthInt=0; - if(depth=="1bitlinear") - { - pixDepth=_1bitlinear; - pixDepthInt=1 | 0x80; //Bit #0=1bit, bit #16=linear - } else if(depth=="8") + string format=vm["format"].as(); + PixelFormat pf; + if(format=="gray1") { - pixDepth=_8; - pixDepthInt=8; - } else if(depth=="16") + pf=PixelFormat::Gray1; + } else if(format=="gray4") { - pixDepth=_16; - pixDepthInt=16; - } else if(depth=="18") + pf=PixelFormat::Gray4; + } else if(format=="rgb332") { - pixDepth=_16; - pixDepthInt=18; - } else if(depth=="24") + pf=PixelFormat::RGB332; + } else if(format=="rgb565") { - pixDepth=_24; - pixDepthInt=24; + pf=PixelFormat::RGB565; } else - throw runtime_error("Unsupported pixel depth (not 1bitlinear,8,16,18,24)"); - + throw runtime_error("Unsupported pixel format (not gray1, gray4, rgb332, rgb565)"); /* * Get output filemane from input filename * Example: if in is "/home/mypng.png" @@ -343,54 +380,53 @@ int main(int argc, char *argv[]) if(binary==false) { - file<(pf)); file.write(reinterpret_cast(&header),sizeof(header)); } - shared_ptr imgw=ImageWriter::fromPixDepth(img,binary,pixDepth); + shared_ptr imgw=ImageWriter::fromPixelFormat(img,binary,pf); imgw->write(file, outRequested ? &outImage : 0); if(!binary) { // The image is declared simply as "Image" in the .h, while as // "basic_image" in the .cpp. This is a trick to allow a - // compile time check that the image pixel depth is correct. + // compile time check that the image pixel format is correct. // If both the image and the mxgui configurations agree the file // will compile. Also, using "Image" in the .h allows to include - // heaer files that refer to "optional" images without causing + // header files that refer to "optional" images without causing // compiler errors string classname; - switch(pixDepth) + switch(pf) { - case _1bitlinear: - classname="Color1bitlinear"; - break; - case _8: - classname="unsigned char"; + case PixelFormat::Gray1: + classname="Gray1Color"; break; - case _16: - classname="unsigned short"; + case PixelFormat::Gray4: + classname="Gray4Color"; break; - case _18: - throw runtime_error("TODO"); + case PixelFormat::RGB332: + classname="RGB332Color"; break; - case _24: - throw runtime_error("TODO"); + case PixelFormat::RGB565: + classname="RGB565Color"; break; } file< " diff --git a/_tools/code_generators/pngconverter.h b/_tools/code_generators/pngconverter.h index 60ab16b..748a1d7 100644 --- a/_tools/code_generators/pngconverter.h +++ b/_tools/code_generators/pngconverter.h @@ -10,31 +10,30 @@ /** * Possible pixel formats for an image */ -enum PixDepth +enum class PixelFormat { - _1bitlinear, ///< 1bit per pixels, arranged as hoizontal scanlines - _8, ///< 8bit per pixel - _16, ///< 16bit per pixel - _18, ///< 18bit per pixel - _24 ///< 24bit per pixel + Gray1, ///< 1bit per pixels, arranged as hoizontal scanlines + Gray4, ///< 4bit per pixel grayscale + RGB332, ///< 8bit per pixel 332 + RGB565 ///< 16bit per pixel 565 }; /** - * Abstract base class from which image drivers derive + * Abstract base class from which image writers derive */ class ImageWriter { public: /** * Factory member function, returns an appropriate image writer - * depending on the pixel depth + * depending on the pixel format * \param img source image * \param binary whether the desired output format is a binary file * or a C++ header file - * \param pd desired pixel depth for the target image + * \param pf desired pixel format for the target image */ - static std::shared_ptr fromPixDepth( - png::image& img, bool binary, PixDepth pd); + static std::shared_ptr fromPixelFormat( + png::image& img, bool binary, PixelFormat pf); /** * Write the image to its output format @@ -58,7 +57,7 @@ class ImageWriter * \param y y coord of the pixel to write * \param out ostream where to write the pixel data * \param outImage if not NULL the implementation needs to set a pixel - * also in this image, with the same colr depth conversion. + * also in this image, with the same pixel format conversion. * \param pix pixel taken from the source image, that needs to be written * to the target image */ @@ -85,21 +84,21 @@ class ImageWriter }; /** - * Class to produce 1 bit linear images. + * Class to produce Gray1 pixel format images. * The image is stored as a sequence of bits representing horizontal * lines of the image. Lines are padded to 8bit boundaries */ -class ImageWriter1bitLinear : public ImageWriter +class ImageWriterGray1 : public ImageWriter { public: - /** - * Constructor - * \param img source image - * \param binary whether the desired output format is a binary file - * or a C++ header file - */ - ImageWriter1bitLinear(png::image& img, bool binary) - : ImageWriter(img, binary) {} + /** + * Constructor + * \param img source image + * \param binary whether the desired output format is a binary file + * or a C++ header file + */ + ImageWriterGray1(png::image& img, bool binary) + : ImageWriter(img, binary) {} /** * This image format is a bit different, and has to redefine @@ -123,67 +122,28 @@ class ImageWriter1bitLinear : public ImageWriter }; /** - * Class to produce 8 bit per pixel images + * Class to produce Gray4 pixel format images. 0-15 grayscale. Packed. */ -class ImageWriter8bit : public ImageWriter +class ImageWriterGray4 : public ImageWriter { public: - /** - * Constructor - * \param img source image - * \param binary whether the desired output format is a binary file - * or a C++ header file - */ - ImageWriter8bit(png::image& img, bool binary) + ImageWriterGray4(png::image& img, bool binary) : ImageWriter(img, binary) {} - -protected: - /** - * \return after how many pixel to insert a carriage return when - * the output format is a C++ header file - */ - virtual int pixPerLine() const { return 16; } - /** - * Write a pixel using the appropriate image format - */ - virtual void writePixel(int x, int y, std::ofstream& out, - png::image *outImage, png::rgb_pixel pix); -}; - -/** - * Class to produce 16 bit per pixel images - */ -class ImageWriter16bit : public ImageWriter -{ -public: - /** - * Constructor - * \param img source image - * \param binary whether the desired output format is a binary file - * or a C++ header file - */ - ImageWriter16bit(png::image& img, bool binary) - : ImageWriter(img, binary) {} + virtual void write(std::ofstream& out, + png::image *outImage=0); protected: - /** - * \return after how many pixel to insert a carriage return when - * the output format is a C++ header file - */ - virtual int pixPerLine() const { return 8; } + virtual int pixPerLine() const { return 16; } - /** - * Write a pixel using the appropriate image format - */ virtual void writePixel(int x, int y, std::ofstream& out, - png::image *outImage, png::rgb_pixel pix); + png::image *outImage, png::rgb_pixel pix) {} //Unused }; /** - * Class to produce 18 bit per pixel images + * Class to produce RGB332 pixel format images */ -class ImageWriter18bit : public ImageWriter +class ImageWriterRGB332 : public ImageWriter { public: /** @@ -192,15 +152,15 @@ class ImageWriter18bit : public ImageWriter * \param binary whether the desired output format is a binary file * or a C++ header file */ - ImageWriter18bit(png::image& img, bool binary) + ImageWriterRGB332(png::image& img, bool binary) : ImageWriter(img, binary) {} - + protected: /** * \return after how many pixel to insert a carriage return when * the output format is a C++ header file */ - virtual int pixPerLine() const { return 6; } + virtual int pixPerLine() const { return 16; } /** * Write a pixel using the appropriate image format @@ -210,9 +170,9 @@ class ImageWriter18bit : public ImageWriter }; /** - * Class to produce 24 bit per pixel images + * Class to produce RGB565 pixel format images */ -class ImageWriter24bit : public ImageWriter +class ImageWriterRGB565 : public ImageWriter { public: /** @@ -221,16 +181,16 @@ class ImageWriter24bit : public ImageWriter * \param binary whether the desired output format is a binary file * or a C++ header file */ - ImageWriter24bit(png::image& img, bool binary) + ImageWriterRGB565(png::image& img, bool binary) : ImageWriter(img, binary) {} - + protected: /** * \return after how many pixel to insert a carriage return when * the output format is a C++ header file */ - virtual int pixPerLine() const { return 6; } - + virtual int pixPerLine() const { return 8; } + /** * Write a pixel using the appropriate image format */ diff --git a/_tools/qtsimulator/CMakeLists.txt b/_tools/qtsimulator/CMakeLists.txt index 916cf55..eb2cb8f 100644 --- a/_tools/qtsimulator/CMakeLists.txt +++ b/_tools/qtsimulator/CMakeLists.txt @@ -19,7 +19,7 @@ function(preprocess_png out_var) set(cpp "${CMAKE_CURRENT_SOURCE_DIR}/${path}/${basename}.cpp") set(h "${CMAKE_CURRENT_SOURCE_DIR}/${path}/${basename}.h") add_custom_command(OUTPUT ${cpp} ${h} - COMMAND ${PNGCONV_EXECUTABLE} --in ${png} --depth 16 + COMMAND ${PNGCONV_EXECUTABLE} --in ${png} --format rgb565 DEPENDS ${png} WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} COMMENT "Preprocessing ${file}" @@ -39,12 +39,28 @@ set(FOO_IMG preprocess_png(IMG_OUT ${FOO_IMG}) # List here your application files +# set(FOO_SRCS +# ../../_examples/benchmark/benchmark.cpp +# ../../_examples/benchmark/checkpattern2.cpp +# ../../_examples/benchmark/micro_qr_code_from_wikipedia.cpp +# ../../_examples/benchmark/bm_main.cpp) +# set(FOO_SRCS +# ../../_examples/swarm/swarm.cpp) set(FOO_SRCS ../../_examples/teapot/fps_counter.cpp ../../_examples/teapot/bresenham_fsm.cpp ../../_examples/teapot/triangle_fsm.cpp ../../_examples/teapot/rendering_engine.cpp ../../_examples/teapot/teapot.cpp) +# set(FOO_SRCS +# ../../_examples/hello/hello_world.cpp) +# set(FOO_SRCS +# ../../_examples/drawboard/drawboard.cpp) +# set(FOO_SRCS +# ../../_examples/particles/fps_counter.cpp +# ../../_examples/particles/particles.cpp) +# set(FOO_SRCS +# ../../_examples/clipped-image/clipped_image.cpp) # These are the sources of the mxgui library and the simulator set(LIB_SRCS diff --git a/_tools/qtsimulator/qtbackend.h b/_tools/qtsimulator/qtbackend.h index 5fcc51b..447dcb7 100644 --- a/_tools/qtsimulator/qtbackend.h +++ b/_tools/qtsimulator/qtbackend.h @@ -52,7 +52,7 @@ class basic_framebuffer */ void clear() { - for(int i=0;i -class basic_framebuffer +class basic_framebuffer { public: /// Height of framebuffer @@ -119,9 +119,9 @@ class basic_framebuffer * \param y * \return the pixel */ - mxgui::Color1bitlinear getPixel(int x, int y) const + mxgui::Gray1Color getPixel(int x, int y) const { - return data[y][x/8] & (1<<(x & 7)) ? 1 : 0; + return (data[y][x/8] & (1<<(x & 7))) ? mxgui::Gray1Color::white() : mxgui::Gray1Color::black(); } /** @@ -130,7 +130,7 @@ class basic_framebuffer * \param y * \param pixel pixel to set */ - void setPixel(int x, int y, mxgui::Color1bitlinear pixel) + void setPixel(int x, int y, mxgui::Gray1Color pixel) { if(pixel) data[y][x/8] |= (1<<(x & 7)); else data[y][x/8] &=~ (1<<(x & 7)); @@ -144,14 +144,15 @@ class basic_framebuffer private: ///Pixel data, stored as [M][N] because matches QImage's representation - unsigned char data[M][(N+7)/8]; + ///Note: QImage requires scanlines to be 32-bit aligned. + unsigned char data[M][((N+31)/32)*4]; }; ///Framebuffer instantiation typedef basic_framebuffer FrameBuffer; + 0> FrameBuffer; /** * Class that interfaces QT GUI (running from main thread) and mxgui (running diff --git a/_tools/qtsimulator/window.cpp b/_tools/qtsimulator/window.cpp index 1f7fc1a..3476de0 100644 --- a/_tools/qtsimulator/window.cpp +++ b/_tools/qtsimulator/window.cpp @@ -19,6 +19,7 @@ #include "qtbackend.h" #include "drivers/event_qt.h" #include +#include #include using namespace mxgui; @@ -38,14 +39,23 @@ void UpdateSignalSender::update() Window::Window(QWidget *parent): QWidget(parent), image(QSize(FrameBuffer::width,FrameBuffer::height), -#ifdef MXGUI_COLOR_DEPTH_16_BIT - QImage::Format_RGB16), -#elif defined(MXGUI_COLOR_DEPTH_1_BIT_LINEAR) +#if defined(MXGUI_PIXEL_FORMAT_GRAY1) QImage::Format_MonoLSB), +#elif defined(MXGUI_PIXEL_FORMAT_RGB565) + QImage::Format_RGB16), +#else + QImage::Format_ARGB32), #endif w(this), layout(&w), buttonA("<"), buttonB(">"), sender(std::make_shared()) { +#ifdef MXGUI_PIXEL_FORMAT_GRAY1 + image.setColorCount(2); + image.setColor(0,qRgb(0,0,0)); + image.setColor(1,qRgb(255,255,255)); +#elif !defined(MXGUI_PIXEL_FORMAT_RGB565) + std::cout<<"Warning: using generic pixel format fallback in qtsimulator"<setFixedSize(FrameBuffer::width,FrameBuffer::height+50); w.setFixedSize(FrameBuffer::width,50); w.move(QPoint(0,FrameBuffer::height)); @@ -63,7 +73,7 @@ Window::Window(QWidget *parent): QWidget(parent), this->setWindowTitle(tr("Mxgui simulator")); this->show(); QTBackend& qb=QTBackend::instance(); - std::memcpy(image.bits(),qb.getFrameBuffer().getData(),image.sizeInBytes()); + updateFrameBuffer(); this->update(); qb.start(sender); } @@ -71,7 +81,24 @@ Window::Window(QWidget *parent): QWidget(parent), void Window::updateFrameBuffer() { FrameBuffer& buffer=QTBackend::instance().getFrameBuffer(); +#if defined(MXGUI_PIXEL_FORMAT_GRAY1) || defined(MXGUI_PIXEL_FORMAT_RGB565) std::memcpy(image.bits(),buffer.getData(),image.sizeInBytes()); +#else + static bool warned = false; + if(!warned) + { + qDebug("Warning: using slow fallback for pixel format conversion in simulator."); + warned = true; + } + for(int y=0;yupdate(); } diff --git a/_tools/winsimulator/ReadMe.txt b/_tools/winsimulator/ReadMe.txt index b04fcfa..065cce0 100644 --- a/_tools/winsimulator/ReadMe.txt +++ b/_tools/winsimulator/ReadMe.txt @@ -12,7 +12,7 @@ I hope this simple simulator will help in designing MXGUI applications without the need to use real boards. The limitations: -* Currently only MXGUI_COLOR_DEPTH_16_BIT is supported. +* Currently only MXGUI_PIXEL_FORMAT_RGB565 is supported. * MXGUI_ORIENTATION_VERTICAL and MXGUI_ORIENTATION_HORIZONTAL are supported, of course, if application supports them. But you should take care of properly setting diff --git a/color.h b/color.h index 2c92773..18d771d 100644 --- a/color.h +++ b/color.h @@ -31,32 +31,668 @@ namespace mxgui { +// Move RGB565Color definition above all uses /** - * This class is designed to behave just like a regular unsigned char, take the same - * amount of storage and, thanks to inlining, be as fast as dealing with an unsigned char. - * The reason why it exists is to avoid Color being a typedef for an unsigned char - * both when MXGUI_COLOR_DEPTH_1_BIT_LINEAR and MXGUI_COLOR_DEPTH_8_BIT, which would - * prevent template specialization to handle the 1 bit per pixel color depth + * \ingroup pub_iface + * An RGB565Color is used to represent colors in the RGB565 format. + * It is suggested to work with the Color typedef to keep the program portable + * to different color formats. */ -class Color1bitlinear +class RGB565Color { public: - Color1bitlinear() {} //Uninitialized just like a regular unsigned char - Color1bitlinear(unsigned char c) : color(c) {} //Not explicit by design - operator unsigned char() const { return color; } - Color1bitlinear& operator=(unsigned char c) { color=c; return *this; } + constexpr RGB565Color() : color(0) {} + + /** + * Construct a color from red, green, blue values + * \param r red value (0-255) + * \param g green value (0-255) + * \param b blue value (0-255) + */ + constexpr RGB565Color(unsigned char r, unsigned char g, unsigned char b) + : color(((r & 0xf8) << 8) | ((g & 0xfc) << 3) | (b >> 3)) {} + + /** + * Get the red channel value, upscaled to 8 bits + * \return red value (0-255) + */ + constexpr unsigned char getR() const + { + unsigned char r = (color >> 8) & 0xf8; + return r | (r >> 5); + } + + /** + * Get the green channel value, upscaled to 8 bits + * \return green value (0-255) + */ + constexpr unsigned char getG() const + { + unsigned char g = (color >> 3) & 0xfc; + return g | (g >> 6); + } + + /** + * Get the blue channel value, upscaled to 8 bits + * \return blue value (0-255) + */ + constexpr unsigned char getB() const + { + unsigned char b = (color & 0x1f) << 3; + return b | (b >> 5); + } + + /** Comparison operators */ + constexpr bool operator==(const RGB565Color& other) const { return color == other.color; } + constexpr bool operator!=(const RGB565Color& other) const { return color != other.color; } + + /** Explicit conversion to the raw data type */ + constexpr operator unsigned short() const { return color; } + + /** + * Creates a color object from the raw data type + * \param raw an unsigned short representing the raw color value + */ + static constexpr RGB565Color fromRaw(unsigned short raw) + { + RGB565Color c; + c.color = raw; + return c; + } + + /** + * Creates a color object from the raw data type of an RGB565 color + * \param c an unsigned short representing the raw color value of an RGB565 color + */ + static constexpr RGB565Color fromRGB565(unsigned short c) { return fromRaw(c); } + + static constexpr RGB565Color black() { return fromRaw(0x0000); } + static constexpr RGB565Color white() { return fromRaw(0xffff); } + + /** + * Linearly interpolate between two colors + * \param c1 the first color + * \param c2 the second color + * \param scale a blend factor (0-255), where 0 is entirely c1, 255 is entirely c2 + */ + static constexpr RGB565Color mix(RGB565Color c1, RGB565Color c2, unsigned char scale) + { + unsigned short s = scale; + unsigned short inv = 255 - s; + + unsigned short r_val = (static_cast(c1.color >> 11) * inv) + + (static_cast(c2.color >> 11) * s); + unsigned short r = (r_val + 1 + (r_val >> 8)) >> 8; + + unsigned short g_val = (static_cast((c1.color & 0x07E0) >> 5) * inv) + + (static_cast((c2.color & 0x07E0) >> 5) * s); + unsigned short g = (g_val + 1 + (g_val >> 8)) >> 8; + + unsigned short b_val = (static_cast(c1.color & 0x001F) * inv) + + (static_cast(c2.color & 0x001F) * s); + unsigned short b = (b_val + 1 + (b_val >> 8)) >> 8; + + return fromRaw( static_cast((r << 11) | (g << 5) | b) ); + } + +private: + unsigned short color; +}; + +/** + * \ingroup pub_iface + * A Gray1Color is used to represent colors with 1 bit (black or white). + * It is suggested to work with the Color typedef to keep the program portable + * to different color formats. + */ +class Gray1Color +{ +public: + constexpr Gray1Color() : color(0) {} + + /** + * Construct a color from red, green, blue values + * \param r red value (0-255) + * \param g green value (0-255) + * \param b blue value (0-255) + */ + constexpr Gray1Color(unsigned char r, unsigned char g, unsigned char b) + : color(((static_cast(r) + g + b) >= MXGUI_1BPP_THRESHOLD) ? 1 : 0) {} + + /** + * Get the red channel value, upscaled to 8 bits + * \return red value (0-255) + */ + constexpr unsigned char getR() const { return color ? 255 : 0; } + + /** + * Get the green channel value, upscaled to 8 bits + * \return green value (0-255) + */ + constexpr unsigned char getG() const { return color ? 255 : 0; } + + /** + * Get the blue channel value, upscaled to 8 bits + * \return blue value (0-255) + */ + constexpr unsigned char getB() const { return color ? 255 : 0; } + + /** Comparison operators */ + constexpr bool operator==(const Gray1Color& other) const { return color == other.color; } + constexpr bool operator!=(const Gray1Color& other) const { return color != other.color; } + + /** Explicit conversion to the raw data type */ + constexpr operator unsigned char() const { return color; } + + /** + * Creates a color object from the raw data type + * \param raw an unsigned char representing the raw color value + */ + static constexpr Gray1Color fromRaw(unsigned char raw) + { + Gray1Color c; + c.color = raw & 0x01; + return c; + } + + /** + * Creates a color object from the raw data type of an RGB565 color + * \param c an unsigned short representing the raw color value of an RGB565 color + */ + static constexpr Gray1Color fromRGB565(unsigned short c) + { + RGB565Color col = RGB565Color::fromRaw(c); + return Gray1Color(col.getR(), col.getG(), col.getB()); + } + + static constexpr Gray1Color black() { return fromRaw(0); } + static constexpr Gray1Color white() { return fromRaw(1); } + + /** + * Interpolate between two colors. Mix for 1bpp is thresholding. + * \param c1 the first color + * \param c2 the second color + * \param scale a blend factor (0-255), where 0 is entirely c1, 255 is entirely c2 + */ + static constexpr Gray1Color mix(Gray1Color c1, Gray1Color c2, unsigned char scale) + { + if (c1 == c2) return c1; + if (c1 == black()) + return (scale >= (MXGUI_1BPP_THRESHOLD / 3)) ? c2 : c1; + else + return ((255 - scale) >= (MXGUI_1BPP_THRESHOLD / 3)) ? c1 : c2; + } + +private: + unsigned char color; +}; + +/** + * \ingroup pub_iface + * A Gray4Color is used to represent colors with 4 bits (grayscale). + * It is suggested to work with the Color typedef to keep the program portable + * to different color formats. + */ +class Gray4Color +{ +public: + constexpr Gray4Color() : color(0) {} + + /** + * Construct a color from red, green, blue values + * \param r red value (0-255) + * \param g green value (0-255) + * \param b blue value (0-255) + */ + constexpr Gray4Color(unsigned char r, unsigned char g, unsigned char b) + : color(static_cast( + (static_cast(r) * 77u + + static_cast(g) * 150u + + static_cast(b) * 29u) >> 12)) {} + + /** + * Get the red channel value, upscaled to 8 bits + * \return red value (0-255) + */ + constexpr unsigned char getR() const { return (color << 4) | color; } + + /** + * Get the green channel value, upscaled to 8 bits + * \return green value (0-255) + */ + constexpr unsigned char getG() const { return (color << 4) | color; } + + /** + * Get the blue channel value, upscaled to 8 bits + * \return blue value (0-255) + */ + constexpr unsigned char getB() const { return (color << 4) | color; } + + /** Comparison operators */ + constexpr bool operator==(const Gray4Color& other) const { return color == other.color; } + constexpr bool operator!=(const Gray4Color& other) const { return color != other.color; } + + /** Explicit conversion to the raw data type */ + constexpr operator unsigned char() const { return color; } + + /** + * Creates a color object from the raw data type + * \param raw an unsigned char representing the raw color value + */ + static constexpr Gray4Color fromRaw(unsigned char raw) + { + Gray4Color c; + c.color = raw & 0x0F; + return c; + } + + /** + * Creates a color object from the raw data type of an RGB565 color + * \param c an unsigned short representing the raw color value of an RGB565 color + */ + static constexpr Gray4Color fromRGB565(unsigned short c) + { + RGB565Color col = RGB565Color::fromRaw(c); + return Gray4Color(col.getR(), col.getG(), col.getB()); + } + + static constexpr Gray4Color black() { return fromRaw(0x0); } + static constexpr Gray4Color white() { return fromRaw(0xF); } + + /** + * Linearly interpolate between two colors + * \param c1 the first color + * \param c2 the second color + * \param scale a blend factor (0-255), where 0 is entirely c1, 255 is entirely c2 + */ + static constexpr Gray4Color mix(Gray4Color c1, Gray4Color c2, unsigned char scale) + { + unsigned short s = scale; + unsigned short inv = 255 - s; + unsigned short val = static_cast(c1.color) * inv + static_cast(c2.color) * s; + unsigned short res = (val + 1 + (val >> 8)) >> 8; + return fromRaw( static_cast(res & 0x0F) ); + } + +private: + unsigned char color; +}; + +/** + * \ingroup pub_iface + * An RGB332Color is used to represent colors in the RGB332 format. + * It is suggested to work with the Color typedef to keep the program portable + * to different color formats. + */ +class RGB332Color +{ +public: + constexpr RGB332Color() : color(0) {} + + /** + * Construct a color from red, green, blue values + * \param r red value (0-255) + * \param g green value (0-255) + * \param b blue value (0-255) + */ + constexpr RGB332Color(unsigned char r, unsigned char g, unsigned char b) + : color((r & 0xe0) | ((g & 0xe0) >> 3) | (b >> 6)) {} + + /** + * Get the red channel value, upscaled to 8 bits + * \return red value (0-255) + */ + constexpr unsigned char getR() const + { + unsigned char r = color & 0xe0; + return r | (r >> 3) | (r >> 6); + } + + /** + * Get the green channel value, upscaled to 8 bits + * \return green value (0-255) + */ + constexpr unsigned char getG() const + { + unsigned char g = (color << 3) & 0xe0; + return g | (g >> 3) | (g >> 6); + } + + /** + * Get the blue channel value, upscaled to 8 bits + * \return blue value (0-255) + */ + constexpr unsigned char getB() const + { + unsigned char b = (color & 0x03); + b |= b << 2; + return b | (b << 4); + } + + /** Comparison operators */ + constexpr bool operator==(const RGB332Color& other) const { return color == other.color; } + constexpr bool operator!=(const RGB332Color& other) const { return color != other.color; } + + /** Explicit conversion to the raw data type */ + constexpr operator unsigned char() const { return color; } + + /** + * Creates a color object from the raw data type + * \param raw an unsigned char representing the raw color value + */ + static constexpr RGB332Color fromRaw(unsigned char raw) + { + RGB332Color c; + c.color = raw; + return c; + } + + /** + * Creates a color object from the raw data type of an RGB565 color + * \param c an unsigned short representing the raw color value of an RGB565 color + */ + static constexpr RGB332Color fromRGB565(unsigned short c) + { + RGB565Color col = RGB565Color::fromRaw(c); + return RGB332Color(col.getR(), col.getG(), col.getB()); + } + + static constexpr RGB332Color black() { return fromRaw(0x00); } + static constexpr RGB332Color white() { return fromRaw(0xff); } + + /** + * Linearly interpolate between two colors + * \param c1 the first color + * \param c2 the second color + * \param scale a blend factor (0-255), where 0 is entirely c1, 255 is entirely c2 + */ + static constexpr RGB332Color mix(RGB332Color c1, RGB332Color c2, unsigned char scale) + { + unsigned short s = scale; + unsigned short inv = 255 - s; + + unsigned short r_val = (static_cast(c1.color & 0xE0) * inv) + (static_cast(c2.color & 0xE0) * s); + unsigned short r = (r_val + 1 + (r_val >> 8)) >> 8; + + unsigned short g_val = (static_cast(c1.color & 0x1C) * inv) + (static_cast(c2.color & 0x1C) * s); + unsigned short g = (g_val + 1 + (g_val >> 8)) >> 8; + + unsigned short b_val = (static_cast(c1.color & 0x03) * inv) + (static_cast(c2.color & 0x03) * s); + unsigned short b = (b_val + 1 + (b_val >> 8)) >> 8; + + return fromRaw( static_cast((r & 0xE0) | (g & 0x1C) | (b & 0x03)) ); + } + +private: + unsigned char color; +}; + +/** + * \ingroup pub_iface + * An RGB888Color is used to represent colors in the RGB888 format. + * For now, as there are no drivers using this format, + * this can be used to have a program perform computations on 24-bit color depth, + * and then construct on the fly the correct Color type to interface with the display, + * decoupling the program color precision from the display pixel format. + */ +class RGB888Color +{ +public: + constexpr RGB888Color() : color(0) {} + + /** + * Construct a color from red, green, blue values + * \param r red value (0-255) + * \param g green value (0-255) + * \param b blue value (0-255) + */ + constexpr RGB888Color(unsigned char r, unsigned char g, unsigned char b) + : color((static_cast(r) << 16) | + (static_cast(g) << 8) | b) {} + + /** + * Get the red channel value, upscaled to 8 bits + * \return red value (0-255) + */ + constexpr unsigned char getR() const { return (color >> 16) & 0xFF; } + + /** + * Get the green channel value, upscaled to 8 bits + * \return green value (0-255) + */ + constexpr unsigned char getG() const { return (color >> 8) & 0xFF; } + + /** + * Get the blue channel value, upscaled to 8 bits + * \return blue value (0-255) + */ + constexpr unsigned char getB() const { return color & 0xFF; } + + /** Comparison operators */ + constexpr bool operator==(const RGB888Color& other) const { return color == other.color; } + constexpr bool operator!=(const RGB888Color& other) const { return color != other.color; } + + /** Explicit conversion to the raw data type */ + constexpr operator unsigned int() const { return color; } + + /** + * Creates a color object from the raw data type + * \param raw an unsigned int representing the raw color value + */ + static constexpr RGB888Color fromRaw(unsigned int raw) + { + RGB888Color c; + c.color = raw & 0x00FFFFFF; + return c; + } + + /** + * Creates a color object from the raw data type of an RGB565 color + * \param c an unsigned short representing the raw color value of an RGB565 color + */ + static constexpr RGB888Color fromRGB565(unsigned short c) + { + RGB565Color col = RGB565Color::fromRaw(c); + return RGB888Color(col.getR(), col.getG(), col.getB()); + } + + static constexpr RGB888Color black() { return fromRaw(0x000000); } + static constexpr RGB888Color white() { return fromRaw(0xFFFFFF); } + + /** + * Linearly interpolate between two colors + * \param c1 the first color + * \param c2 the second color + * \param scale a blend factor (0-255), where 0 is entirely c1, 255 is entirely c2 + */ + static constexpr RGB888Color mix(RGB888Color c1, RGB888Color c2, unsigned char scale) + { + unsigned int v1 = static_cast(c1), v2 = static_cast(c2); + unsigned short s = scale, inv = 255 - s; + + unsigned int r_val = ((v1 >> 16) & 0xFF) * inv + ((v2 >> 16) & 0xFF) * s; + unsigned char r = (r_val + 1 + (r_val >> 8)) >> 8; + + unsigned int g_val = ((v1 >> 8) & 0xFF) * inv + ((v2 >> 8) & 0xFF) * s; + unsigned char g = (g_val + 1 + (g_val >> 8)) >> 8; + + unsigned int b_val = (v1 & 0xFF) * inv + (v2 & 0xFF) * s; + unsigned char b = (b_val + 1 + (b_val >> 8)) >> 8; + + return RGB888Color(r, g, b); + } + private: - unsigned char color; + unsigned int color; }; -///\ingroup pub_iface -///Define the Color type, depending on the COLOR_DEPTH constant -#ifdef MXGUI_COLOR_DEPTH_1_BIT_LINEAR -typedef Color1bitlinear Color; //Only 0 and 1 allowed -#elif defined(MXGUI_COLOR_DEPTH_8_BIT) -typedef unsigned char Color; -#elif defined(MXGUI_COLOR_DEPTH_16_BIT) -typedef unsigned short Color; + +// Gray1 Operations +constexpr Gray1Color operator+(Gray1Color a, Gray1Color b) +{ + return Gray1Color::fromRaw(static_cast(a) | static_cast(b)); +} +constexpr Gray1Color operator-(Gray1Color a, Gray1Color b) +{ + return Gray1Color::fromRaw(static_cast(a) & ~static_cast(b)); +} +constexpr Gray1Color operator|(Gray1Color a, Gray1Color b) +{ + return Gray1Color::fromRaw(static_cast(a) | static_cast(b)); +} + +// Gray4 Operations +constexpr Gray4Color operator+(Gray4Color a, Gray4Color b) +{ + unsigned short val = static_cast(a) + static_cast(b); + if(val > 0xF) val = 0xF; + return Gray4Color::fromRaw(static_cast(val)); +} +constexpr Gray4Color operator-(Gray4Color a, Gray4Color b) +{ + unsigned char ca = a; + unsigned char cb = b; + unsigned char val = ca - cb; + if(val > ca) val = 0; + return Gray4Color::fromRaw(val); +} +constexpr Gray4Color operator|(Gray4Color a, Gray4Color b) +{ + return Gray4Color::fromRaw(static_cast(a) | static_cast(b)); +} + +// RGB332 Operations +constexpr RGB332Color operator+(RGB332Color a, RGB332Color b) +{ + unsigned char ca = a; + unsigned char cb = b; + unsigned short intermediate = static_cast(ca & 0xE0) + (cb & 0xE0); + if (intermediate > 0xE0) intermediate = 0xE0; + + unsigned short g = static_cast(ca & 0x1C) + (cb & 0x1C); + if (g > 0x1C) g = 0x1C; + intermediate |= g; + unsigned short b_val = static_cast(ca & 0x03) + (cb & 0x03); + if (b_val > 0x03) b_val = 0x03; + intermediate |= b_val; + + return RGB332Color::fromRaw(static_cast(intermediate)); +} +constexpr RGB332Color operator-(RGB332Color a, RGB332Color b) +{ + unsigned char ca = a; + unsigned char cb = b; + + unsigned char ra = ca & 0xE0; + unsigned char rb = cb & 0xE0; + unsigned char r = (ra > rb) ? ra - rb : 0; + + unsigned char ga = ca & 0x1C; + unsigned char gb = cb & 0x1C; + unsigned char g = (ga > gb) ? ga - gb : 0; + + unsigned char ba = ca & 0x03; + unsigned char bb = cb & 0x03; + unsigned char b_val = (ba > bb) ? ba - bb : 0; + + return RGB332Color::fromRaw(r | g | b_val); +} +constexpr RGB332Color operator|(RGB332Color a, RGB332Color b) +{ + return RGB332Color::fromRaw(static_cast(a) | static_cast(b)); +} + +// RGB565 Operations +constexpr RGB565Color operator+(RGB565Color a, RGB565Color b) +{ + unsigned short ca = a; + unsigned short cb = b; + + unsigned short ra = ca & 0xF800; + unsigned short rb = cb & 0xF800; + unsigned short r = ra + rb; + if (r < ra || r > 0xF800) r = 0xF800; + + unsigned short ga = ca & 0x07E0; + unsigned short gb = cb & 0x07E0; + unsigned short g = ga + gb; + if (g > 0x07E0) g = 0x07E0; + + unsigned short ba = ca & 0x001F; + unsigned short bb = cb & 0x001F; + unsigned short b_val = ba + bb; + if (b_val > 0x001F) b_val = 0x001F; + + return RGB565Color::fromRaw(r | g | b_val); +} +constexpr RGB565Color operator-(RGB565Color a, RGB565Color b) +{ + unsigned short ca = a; + unsigned short cb = b; + unsigned short ra = ca & 0xF800; + unsigned short rb = cb & 0xF800; + unsigned short r = (ra > rb) ? ra - rb : 0; + + unsigned short ga = ca & 0x07E0; + unsigned short gb = cb & 0x07E0; + unsigned short g = (ga > gb) ? ga - gb : 0; + + unsigned short ba = ca & 0x001F; + unsigned short bb = cb & 0x001F; + unsigned short b_val = (ba > bb) ? ba - bb : 0; + + return RGB565Color::fromRaw(r | g | b_val); +} +constexpr RGB565Color operator|(RGB565Color a, RGB565Color b) +{ + return RGB565Color::fromRaw(static_cast(a) | static_cast(b)); +} + +// RGB888 Operations (computation aid, not a pixel format) +constexpr RGB888Color operator+(RGB888Color a, RGB888Color b) +{ + unsigned int va = static_cast(a); + unsigned int vb = static_cast(b); + unsigned short r = ((va >> 16) & 0xFF) + ((vb >> 16) & 0xFF); + if (r > 255) r = 255; + unsigned short g = ((va >> 8) & 0xFF) + ((vb >> 8) & 0xFF); + if (g > 255) g = 255; + unsigned short b_val = (va & 0xFF) + (vb & 0xFF); + if (b_val > 255) b_val = 255; + return RGB888Color(r, g, b_val); +} +constexpr RGB888Color operator-(RGB888Color a, RGB888Color b) +{ + unsigned int va = static_cast(a); + unsigned int vb = static_cast(b); + unsigned char ra = (va >> 16) & 0xFF, rb = (vb >> 16) & 0xFF; + unsigned char ga = (va >> 8) & 0xFF, gb = (vb >> 8) & 0xFF; + unsigned char ba = va & 0xFF, bb = vb & 0xFF; + return RGB888Color(ra > rb ? ra - rb : 0, + ga > gb ? ga - gb : 0, + ba > bb ? ba - bb : 0); +} +constexpr RGB888Color operator|(RGB888Color a, RGB888Color b) +{ + return RGB888Color::fromRaw(static_cast(a) | static_cast(b)); +} + +// Check there is only one active Color type +#if (defined(MXGUI_PIXEL_FORMAT_GRAY1) + defined(MXGUI_PIXEL_FORMAT_GRAY4) + \ + defined(MXGUI_PIXEL_FORMAT_RGB332) + defined(MXGUI_PIXEL_FORMAT_RGB565)) > 1 +#error "Multiple pixel formats defined in mxgui_settings.h" +#endif + +#if defined(MXGUI_PIXEL_FORMAT_GRAY1) +typedef Gray1Color Color; +#elif defined(MXGUI_PIXEL_FORMAT_GRAY4) +typedef Gray4Color Color; +#elif defined(MXGUI_PIXEL_FORMAT_RGB332) +typedef RGB332Color Color; +#elif defined(MXGUI_PIXEL_FORMAT_RGB565) +typedef RGB565Color Color; +#else +#error "No pixel format defined" #endif } // namespace mxgui diff --git a/config/mxgui_settings.h b/config/mxgui_settings.h index 59bd418..fd87766 100644 --- a/config/mxgui_settings.h +++ b/config/mxgui_settings.h @@ -61,9 +61,18 @@ static const unsigned int level2MaxNumApps=4; /// /// Choose color depth. Three options are provided for 1, 8 or 16 bit per pixel /// -//#define MXGUI_COLOR_DEPTH_1_BIT_LINEAR -//#define MXGUI_COLOR_DEPTH_8_BIT //Untested -#define MXGUI_COLOR_DEPTH_16_BIT +//#define MXGUI_PIXEL_FORMAT_GRAY1 +//#define MXGUI_PIXEL_FORMAT_GRAY4 +//#define MXGUI_PIXEL_FORMAT_RGB332 //Untested +#define MXGUI_PIXEL_FORMAT_RGB565 + +/// +/// 1BPP color threshold. +/// The threshold at which a color is considered white in 1BPP mode. +/// The value is the sum of the red, green and blue components (0-255 each). +/// Default is 384 (128*3, or 50% gray). +/// +#define MXGUI_1BPP_THRESHOLD 384 /// /// Display orientation settings. Four options are provided for HORIZONTAL or @@ -116,16 +125,29 @@ static const int level2MaxNumApps=4; //#define MXGUI_ENABLE_RESOURCEFS // -// Choose color depth. +// Choose pixel format. // -//#define MXGUI_COLOR_DEPTH_1_BIT_LINEAR -//#define MXGUI_COLOR_DEPTH_8_BIT //Untested -#define MXGUI_COLOR_DEPTH_16_BIT +// #define MXGUI_PIXEL_FORMAT_GRAY1 +// #define MXGUI_PIXEL_FORMAT_GRAY4 +// #define MXGUI_PIXEL_FORMAT_RGB332 +#define MXGUI_PIXEL_FORMAT_RGB565 + +/// +/// 1BPP color threshold. +/// The threshold at which a color is considered white in 1BPP mode. +/// The value is the sum of the red, green and blue components (0-255 each). +/// Default is 384 (128*3, or 50% gray). +/// +#define MXGUI_1BPP_THRESHOLD 384 static const unsigned int SIMULATOR_DISP_HEIGHT=320; static const unsigned int SIMULATOR_DISP_WIDTH=240; -static const unsigned int SIMULATOR_FGCOLOR=0xffff; -static const unsigned int SIMULATOR_BGCOLOR=0; +static const unsigned char SIMULATOR_FG_R=255; +static const unsigned char SIMULATOR_FG_G=255; +static const unsigned char SIMULATOR_FG_B=255; +static const unsigned char SIMULATOR_BG_R=0; +static const unsigned char SIMULATOR_BG_G=0; +static const unsigned char SIMULATOR_BG_B=0; // // Display orientation settings, choose ONE of these. Their meaninig depends diff --git a/drivers/display_bitsboard.h b/drivers/display_bitsboard.h index 0ad37f2..90576e3 100644 --- a/drivers/display_bitsboard.h +++ b/drivers/display_bitsboard.h @@ -46,7 +46,7 @@ //This display is 1 bit per pixel, check that the color depth is properly //configured -#ifndef MXGUI_COLOR_DEPTH_1_BIT_LINEAR +#ifndef MXGUI_PIXEL_FORMAT_GRAY1 #error The bitsboard driver requires a color depth of 1bit per pixel #endif diff --git a/drivers/display_generic_4bpp.h b/drivers/display_generic_4bpp.h index f5abbfc..bbee336 100644 --- a/drivers/display_generic_4bpp.h +++ b/drivers/display_generic_4bpp.h @@ -318,13 +318,9 @@ class DisplayGeneric4BPP : public Display unsigned char *backbuffer; ///< Display backbuffer (frontbuffer is in the display chip) private: - //FIXME: these displays are black and white with 4 bit per pixel, but we - //still don't have 4 bit per pixel color format in the rest of the library, - //so for now use 16 bit per pixel RGB565 format and take the 4 MSBs from the - //blue channel. Images should be exported as RGB565 even if they are black - //and white until this is fixed - static unsigned char conv1(Color c) { return (c & 0x1f)>>1; } - static unsigned char conv2(Color c) { unsigned char x=(c & 0x1f)>>1; return x | x<<4; } + // These displays are black and white with 4 bit per pixel. + static unsigned char conv1(Color c) { return static_cast(c); } + static unsigned char conv2(Color c) { unsigned char x=static_cast(c); return x | x<<4; } /** * Non bound checked no color conversion non virtual setPixel. @@ -352,7 +348,7 @@ DisplayGeneric4BPP::DisplayGeneric4BPP(short width, shor : width(width), height(height), fbSize(width*height/2), backbuffer(new unsigned char[fbSize]), buffer(new Color[width]) { - setTextColor(std::make_pair(Color(0xffff),Color(0x0))); + setTextColor(std::make_pair(Color::white(),Color::black())); } template diff --git a/drivers/display_gme128128.h b/drivers/display_gme128128.h index 060dec6..85af663 100644 --- a/drivers/display_gme128128.h +++ b/drivers/display_gme128128.h @@ -29,6 +29,7 @@ #pragma once #include "display_generic_1bpp.h" +#include "misc_inst.h" #include #include @@ -143,10 +144,10 @@ DisplayGME128128::DisplayGME128128() : DisplayGeneric1BPP(128,128 cmd(0xd9); cmd(0xf1); // Precharge periods cmd(0xdb); cmd(0x40); // VCOMH cmd(0xa6); // Normal display mode - clear(0); + clear(black); update(); cmd(0xaf); // Display on - setTextColor(std::make_pair(Color(0xf),Color(0x0))); + setTextColor(std::make_pair(Color::white(),Color::black())); } template diff --git a/drivers/display_ly091wg14.h b/drivers/display_ly091wg14.h index ffcaa2b..07943e9 100644 --- a/drivers/display_ly091wg14.h +++ b/drivers/display_ly091wg14.h @@ -28,6 +28,7 @@ #pragma once #include "display_generic_1bpp.h" +#include "misc_inst.h" #include #include @@ -131,10 +132,10 @@ DisplayLy091wg14::DisplayLy091wg14() : DisplayGeneric1BPP(128,32) cmd(0xd9); cmd(0xf1); // Precharge periods cmd(0xdb); cmd(0x40); // VCOMH cmd(0xa6); // Normal display mode - clear(0); + clear(black); update(); cmd(0xaf); // Display on - setTextColor(std::make_pair(Color(0xf),Color(0x0))); + setTextColor(std::make_pair(Color::white(),Color::black())); } template diff --git a/drivers/display_mp3v2.cpp b/drivers/display_mp3v2.cpp index 07913b1..ee9e149 100644 --- a/drivers/display_mp3v2.cpp +++ b/drivers/display_mp3v2.cpp @@ -178,7 +178,7 @@ void DisplayImpl::drawImage(Point p, const ImageBase& img) short int yEnd=p.y()+img.getHeight()-1; if(xEnd >= width || yEnd >= height) return; - const unsigned short *imgData=img.getData(); + const unsigned short *imgData=reinterpret_cast(img.getData()); if(imgData!=0) { //Optimized version for memory-loaded images @@ -221,7 +221,7 @@ void DisplayImpl::clippedDrawImage(Point p, Point a, Point b, const ImageBase& i short nx=xb-xa+1; short ny=yb-ya+1; int skipStart=(ya-p.y())*img.getWidth()+(xa-p.x()); - const unsigned short *pix=img.getData()+skipStart; + const unsigned short *pix=reinterpret_cast(img.getData())+skipStart; int toSkip=(xa-p.x())+((p.x()+img.getWidth()-1)-xb); short fastNx=nx/2; if((nx & 0x1)==0) //Scanline has odd number of pixels @@ -351,7 +351,7 @@ DisplayImpl::DisplayImpl(): buffer(0) writeReg(0x77,0x211a); writeReg(0x78,0x2013); - clear(Color(0x0000));//Clear screen before activating display + clear(Color::black());//Clear screen before activating display disp::ncpEn::high(); delayMs(32);//Let AR_VDD and AR_VSS stabilize writeReg(0x05,0x0001);//DISP_ON = 1 (display active) @@ -359,7 +359,7 @@ DisplayImpl::DisplayImpl(): buffer(0) //Power up sequence -- end // - setTextColor(make_pair(Color(0xffff),Color(0x0000))); + setTextColor(make_pair(Color::white(),Color::black())); clear(black); } diff --git a/drivers/display_mp3v2.h b/drivers/display_mp3v2.h index 89388db..ec5d5be 100644 --- a/drivers/display_mp3v2.h +++ b/drivers/display_mp3v2.h @@ -51,7 +51,7 @@ namespace mxgui { //This display is 16 bit per pixel, check that the color depth is properly //configured -#ifndef MXGUI_COLOR_DEPTH_16_BIT +#ifndef MXGUI_PIXEL_FORMAT_RGB565 #error The S6E63D6 driver requires a color depth of 16bit per pixel #endif diff --git a/drivers/display_oledboard2.cpp b/drivers/display_oledboard2.cpp index 511e0e5..04aaea3 100644 --- a/drivers/display_oledboard2.cpp +++ b/drivers/display_oledboard2.cpp @@ -487,7 +487,7 @@ DisplayImpl::DisplayImpl() sendCommand8(0x23,0x00); sendCommand8(0x26,0xa0); - setTextColor(make_pair(Color(0xffff),Color(0x0000))); + setTextColor(make_pair(Color::white(),Color::black())); clear(black); doTurnOn(); } diff --git a/drivers/display_oledboard2.h b/drivers/display_oledboard2.h index 99fcb4a..765efe2 100644 --- a/drivers/display_oledboard2.h +++ b/drivers/display_oledboard2.h @@ -51,7 +51,7 @@ namespace mxgui { //This display is 16 bit per pixel, check that the color depth is properly //configured -#ifndef MXGUI_COLOR_DEPTH_16_BIT +#ifndef MXGUI_PIXEL_FORMAT_RGB565 #error The AMS369FG03-0 driver requires a color depth of 16bit per pixel #endif diff --git a/drivers/display_qt.cpp b/drivers/display_qt.cpp index 9342e29..b6bd642 100644 --- a/drivers/display_qt.cpp +++ b/drivers/display_qt.cpp @@ -252,7 +252,8 @@ DisplayImpl::~DisplayImpl() DisplayImpl::DisplayImpl(): buffer(nullptr), last(), beginPixelCalled(false), backend(QTBackend::instance()) { - setTextColor(make_pair(Color(SIMULATOR_FGCOLOR),Color(SIMULATOR_BGCOLOR))); + setTextColor(make_pair(Color(SIMULATOR_FG_R, SIMULATOR_FG_G, SIMULATOR_FG_B), + Color(SIMULATOR_BG_R, SIMULATOR_BG_G, SIMULATOR_BG_B))); } } //namespace mxgui diff --git a/drivers/display_qt.h b/drivers/display_qt.h index 8f02045..534ea2a 100644 --- a/drivers/display_qt.h +++ b/drivers/display_qt.h @@ -45,10 +45,10 @@ #include #include -//This display is 16 or 1 bit per pixel, check that the color depth is properly -//configured -#if !defined(MXGUI_COLOR_DEPTH_16_BIT) && !defined(MXGUI_COLOR_DEPTH_1_BIT_LINEAR) -#error The Qt driver requires a color depth of 16 or 1bit per pixel +//This display supports multiple pixel formats +#if !defined(MXGUI_PIXEL_FORMAT_RGB565) && !defined(MXGUI_PIXEL_FORMAT_GRAY1) \ + && !defined(MXGUI_PIXEL_FORMAT_RGB332) && !defined(MXGUI_PIXEL_FORMAT_GRAY4) +#error The Qt driver requires a supported pixel format #endif //Uncomment only to check precise pixel_iterator algorithms, used for displays diff --git a/drivers/display_redbull_v2.cpp b/drivers/display_redbull_v2.cpp index c9e0b8a..d279a03 100644 --- a/drivers/display_redbull_v2.cpp +++ b/drivers/display_redbull_v2.cpp @@ -163,7 +163,7 @@ void DisplayImpl::drawImage(Point p, const ImageBase& img) short int yEnd=p.y()+img.getHeight()-1; if(xEnd >= width || yEnd >= height) return; - const unsigned short *imgData=img.getData(); + const unsigned short *imgData=reinterpret_cast(img.getData()); if(imgData!=0) { //Optimized version for memory-loaded images diff --git a/drivers/display_redbull_v2.h b/drivers/display_redbull_v2.h index 87926a8..4557f7d 100644 --- a/drivers/display_redbull_v2.h +++ b/drivers/display_redbull_v2.h @@ -51,7 +51,7 @@ namespace mxgui { //This display is 16 bit per pixel, check that the color depth is properly //configured -#ifndef MXGUI_COLOR_DEPTH_16_BIT +#ifndef MXGUI_PIXEL_FORMAT_RGB565 #error This SSD1289 driver requires a color depth of 16bit per pixel #endif diff --git a/drivers/display_sony-newman.cpp b/drivers/display_sony-newman.cpp index 2fa4305..44c2127 100644 --- a/drivers/display_sony-newman.cpp +++ b/drivers/display_sony-newman.cpp @@ -320,7 +320,7 @@ void DisplayImpl::drawImage(Point p, const ImageBase& img) waitDmaCompletion(); - const unsigned short *imgData=img.getData(); + const unsigned short *imgData=reinterpret_cast(img.getData()); if(imgData!=0) { //Optimized version for memory-loaded images @@ -375,7 +375,7 @@ DisplayImpl::~DisplayImpl() {} DisplayImpl::DisplayImpl(): which(0) { doTurnOn(); - setTextColor(make_pair(Color(0xffff),Color(0x0000))); + setTextColor(make_pair(Color::white(),Color::black())); } void DisplayImpl::window(Point p1, Point p2) diff --git a/drivers/display_sony-newman.h b/drivers/display_sony-newman.h index 1823c03..292da6c 100644 --- a/drivers/display_sony-newman.h +++ b/drivers/display_sony-newman.h @@ -50,7 +50,7 @@ namespace mxgui { //This display is 16 bit per pixel, chech that the color depth is properly //configured -#ifndef MXGUI_COLOR_DEPTH_16_BIT +#ifndef MXGUI_PIXEL_FORMAT_RGB565 #error The LD7131 driver requires a color depth of 16bit per pixel #endif diff --git a/drivers/display_st25dvdiscovery.cpp b/drivers/display_st25dvdiscovery.cpp index 10f3e16..63f1ed3 100644 --- a/drivers/display_st25dvdiscovery.cpp +++ b/drivers/display_st25dvdiscovery.cpp @@ -235,7 +235,7 @@ void DisplayImpl::drawImage(Point p, const ImageBase& img) short int yEnd = p.y() + img.getHeight() - 1; if(xEnd >= width || yEnd >= height) { return; } - const unsigned short *imgData = img.getData(); + const unsigned short *imgData = reinterpret_cast(img.getData()); if(imgData != 0) { unsigned char lsb = 0x00; diff --git a/drivers/display_st25dvdiscovery.h b/drivers/display_st25dvdiscovery.h index 75c668d..6cbd020 100644 --- a/drivers/display_st25dvdiscovery.h +++ b/drivers/display_st25dvdiscovery.h @@ -41,7 +41,7 @@ namespace mxgui { //This display is 16 bit per pixel, check that the color depth is properly //configured -#ifndef MXGUI_COLOR_DEPTH_16_BIT +#ifndef MXGUI_PIXEL_FORMAT_RGB565 #error The ILI9341 driver requires a color depth of 16bit per pixel #endif diff --git a/drivers/display_st7735.cpp b/drivers/display_st7735.cpp index 9819860..60a1062 100644 --- a/drivers/display_st7735.cpp +++ b/drivers/display_st7735.cpp @@ -32,7 +32,7 @@ #include "line.h" //The ST7735 driver requires a color depth 16 per pixel -#ifdef MXGUI_COLOR_DEPTH_16_BIT +#ifdef MXGUI_PIXEL_FORMAT_RGB565 using namespace std; using namespace miosix; @@ -209,7 +209,7 @@ void DisplayGenericST7735::drawImage(Point p, const ImageBase& img) { short int yEnd = p.y() + img.getHeight() - 1; if(xEnd >= width || yEnd >= height) { return; } - const unsigned short *imgData = img.getData(); + const unsigned short *imgData = reinterpret_cast(img.getData()); if(imgData != 0) { unsigned char lsb = 0x00; @@ -352,4 +352,4 @@ void DisplayGenericST7735::sendCmds(const unsigned char *cmds) { } //mxgui -#endif //MXGUI_COLOR_DEPTH_16_BIT +#endif //MXGUI_PIXEL_FORMAT_RGB565 diff --git a/drivers/display_st7735.h b/drivers/display_st7735.h index 5b783ef..ab1df1b 100644 --- a/drivers/display_st7735.h +++ b/drivers/display_st7735.h @@ -40,7 +40,7 @@ namespace mxgui { //The ST7735 driver requires a color depth 16 per pixel -#ifdef MXGUI_COLOR_DEPTH_16_BIT +#ifdef MXGUI_PIXEL_FORMAT_RGB565 //Used to transiently pull low either the csx or dcx pin class Transaction @@ -437,6 +437,6 @@ class DisplayGenericST7735 : public Display Color *buffer; ///< For scanLineBuffer }; -#endif //MXGUI_COLOR_DEPTH_16_BIT +#endif //MXGUI_PIXEL_FORMAT_RGB565 } //namespace mxgui diff --git a/drivers/display_stm3210e-eval.cpp b/drivers/display_stm3210e-eval.cpp index 6522218..5f0f488 100644 --- a/drivers/display_stm3210e-eval.cpp +++ b/drivers/display_stm3210e-eval.cpp @@ -191,7 +191,7 @@ void DisplayImpl::drawImage(Point p, const ImageBase& img) short int yEnd=p.y()+img.getHeight()-1; if(xEnd >= width || yEnd >= height) return; - const unsigned short *imgData=img.getData(); + const unsigned short *imgData=reinterpret_cast(img.getData()); if(imgData!=0) { //Optimized version for memory-loaded images @@ -290,7 +290,7 @@ DisplayImpl::DisplayImpl(): buffer(0), displayType(UNKNOWN) break; } - setTextColor(make_pair(Color(0xffff),Color(0x0000))); + setTextColor(make_pair(Color::white(),Color::black())); clear(black); } diff --git a/drivers/display_stm3210e-eval.h b/drivers/display_stm3210e-eval.h index 1e87b43..1d3c1f8 100644 --- a/drivers/display_stm3210e-eval.h +++ b/drivers/display_stm3210e-eval.h @@ -49,7 +49,7 @@ namespace mxgui { //This display is 16 bit per pixel, chech that the color depth is properly //configured -#ifndef MXGUI_COLOR_DEPTH_16_BIT +#ifndef MXGUI_PIXEL_FORMAT_RGB565 #error The SPFD5408 driver requires a color depth of 16bit per pixel #endif diff --git a/drivers/display_stm3220g-eval.cpp b/drivers/display_stm3220g-eval.cpp index 58a6b10..da7d410 100644 --- a/drivers/display_stm3220g-eval.cpp +++ b/drivers/display_stm3220g-eval.cpp @@ -255,7 +255,7 @@ void DisplayImpl::drawImage(Point p, const ImageBase& img) short int yEnd=p.y()+img.getHeight()-1; if(xEnd >= width || yEnd >= height) return; - const unsigned short *imgData=img.getData(); + const unsigned short *imgData=reinterpret_cast(img.getData()); if(imgData!=0) { //Optimized version for memory-loaded images diff --git a/drivers/display_stm3220g-eval.h b/drivers/display_stm3220g-eval.h index b48d3ec..174830c 100644 --- a/drivers/display_stm3220g-eval.h +++ b/drivers/display_stm3220g-eval.h @@ -53,7 +53,7 @@ namespace mxgui { //This display is 16 bit per pixel, check that the color depth is properly //configured -#ifndef MXGUI_COLOR_DEPTH_16_BIT +#ifndef MXGUI_PIXEL_FORMAT_RGB565 #error This IL9325 driver requires a color depth of 16bit per pixel #endif diff --git a/drivers/display_stm32f4discovery.cpp b/drivers/display_stm32f4discovery.cpp index 6300411..aead938 100644 --- a/drivers/display_stm32f4discovery.cpp +++ b/drivers/display_stm32f4discovery.cpp @@ -469,7 +469,7 @@ DisplayImpl::DisplayImpl() | 0 //no dithering | LTDC_GCR_LTDCEN; //Display enabled - setTextColor(make_pair(Color(0xffff),Color(0x0000))); + setTextColor(make_pair(Color::white(),Color::black())); clear(black); } @@ -780,7 +780,7 @@ DisplayImpl::pixel_iterator DisplayImpl::begin(Point p1, Point p2, DisplayImpl::~DisplayImpl() {} DisplayImpl::DisplayImpl() - : framebuffer1(reinterpret_cast(0xc0c00000)), + : framebuffer1(reinterpret_cast(0xc0c00000)), buffer(framebuffer1 + numPixels) { /* This driver uses DSI interface in command mode, but it was firstly programmed in video mode. @@ -1316,7 +1316,7 @@ DisplayImpl::DisplayImpl() // Update the display DSI->WCR |= DSI_WCR_LTDCEN; - setTextColor(make_pair(Color(0xffff), Color(0x0000))); + setTextColor(make_pair(Color::white(), Color::black())); clear(black); } diff --git a/drivers/display_stm32f4discovery.h b/drivers/display_stm32f4discovery.h index d358273..a63e890 100644 --- a/drivers/display_stm32f4discovery.h +++ b/drivers/display_stm32f4discovery.h @@ -51,7 +51,7 @@ namespace mxgui { //This display is 16 bit per pixel, check that the color depth is properly //configured -#ifndef MXGUI_COLOR_DEPTH_16_BIT +#ifndef MXGUI_PIXEL_FORMAT_RGB565 #error The ILI9341 driver requires a color depth of 16bit per pixel #endif @@ -379,7 +379,7 @@ namespace mxgui { //This display is 16 bit per pixel, check that the color depth is properly //configured -#ifndef MXGUI_COLOR_DEPTH_16_BIT +#ifndef MXGUI_PIXEL_FORMAT_RGB565 #error The OTM8009A driver requires a color depth of 16bit per pixel #endif diff --git a/drivers/display_strive.cpp b/drivers/display_strive.cpp index 63d3ff0..c431f9b 100644 --- a/drivers/display_strive.cpp +++ b/drivers/display_strive.cpp @@ -269,7 +269,7 @@ void DisplayImpl::drawImage(Point p, const ImageBase& img) short int yEnd=p.y()+img.getHeight()-1; if(xEnd >= width || yEnd >= height) return; - const unsigned short *imgData=img.getData(); + const unsigned short *imgData=reinterpret_cast(img.getData()); if(imgData!=0) { //Optimized version for memory-loaded images @@ -313,7 +313,7 @@ void DisplayImpl::clippedDrawImage(Point p, Point a, Point b, const ImageBase& i short nx=xb-xa+1; short ny=yb-ya+1; int skipStart=(ya-p.y())*img.getWidth()+(xa-p.x()); - const unsigned short *pix=img.getData()+skipStart; + const unsigned short *pix=reinterpret_cast(img.getData())+skipStart; int toSkip=(xa-p.x())+((p.x()+img.getWidth()-1)-xb); short fastNx=nx/2; if((nx & 0x1)==0) //Scanline has odd number of pixels diff --git a/drivers/display_strive.h b/drivers/display_strive.h index 3e67224..8616ec4 100644 --- a/drivers/display_strive.h +++ b/drivers/display_strive.h @@ -51,7 +51,7 @@ namespace mxgui { //This display is 16 bit per pixel, check that the color depth is properly //configured -#ifndef MXGUI_COLOR_DEPTH_16_BIT +#ifndef MXGUI_PIXEL_FORMAT_RGB565 #error This IL9325 driver requires a color depth of 16bit per pixel #endif diff --git a/drivers/display_win.cpp b/drivers/display_win.cpp index d6d8635..9678a33 100644 --- a/drivers/display_win.cpp +++ b/drivers/display_win.cpp @@ -250,7 +250,7 @@ DisplayImpl::DisplayImpl(): beginPixelCalled(false), backend(WinBackend::instance()) { - setTextColor(make_pair(Color(0xffff), Color(0x0000))); + setTextColor(make_pair(Color::white(), Color::black())); } } //namespace mxgui diff --git a/drivers/display_win.h b/drivers/display_win.h index b7a17e8..91cab30 100644 --- a/drivers/display_win.h +++ b/drivers/display_win.h @@ -46,7 +46,7 @@ //This display is 16 bit per pixel, check that the color depth is properly //configured -#ifndef MXGUI_COLOR_DEPTH_16_BIT +#ifndef MXGUI_PIXEL_FORMAT_RGB565 #error The Windows driver requires a color depth of 16bit per pixel #endif diff --git a/font.cpp b/font.cpp index 281dbe8..4e81be2 100644 --- a/font.cpp +++ b/font.cpp @@ -72,7 +72,7 @@ short int Font::calculateLength(const char *s) const void Font::generatePalette(Color out[4], Color fgcolor, Color bgcolor) { - #ifdef MXGUI_COLOR_DEPTH_16_BIT + #ifdef MXGUI_PIXEL_FORMAT_RGB565 unsigned short fgR=fgcolor; //& 0xf800; Optimization, & not required unsigned short bgR=bgcolor; //& 0xf800; Optimization, & not required unsigned short fgG=fgcolor & 0x7e0; @@ -83,17 +83,21 @@ void Font::generatePalette(Color out[4], Color fgcolor, Color bgcolor) unsigned short deltaG=((fgG-bgG)/3) & 0x7e0; unsigned short deltaB=((fgB-bgB)/3) & 0x1f; unsigned short delta=deltaR | deltaG | deltaB; - out[3]=fgcolor; - out[2]=Color(bgcolor+2*delta); - out[1]=Color(bgcolor+delta); - out[0]=bgcolor; - #elif defined(MXGUI_COLOR_DEPTH_8_BIT) - #error TODO - #elif defined(MXGUI_COLOR_DEPTH_1_BIT_LINEAR) - out[0]=out[1]=bgcolor ? white : black; - out[2]=out[3]=fgcolor ? white : black; + out[3]=Color::fromRaw(fgcolor); + out[2]=Color::fromRaw(bgcolor+2*delta); + out[1]=Color::fromRaw(bgcolor+delta); + out[0]=Color::fromRaw(bgcolor); + #elif defined(MXGUI_PIXEL_FORMAT_GRAY1) + // For 1bpp, we want a hard threshold to keep fonts sharp and thick. + // Mapping Level 0,1 to background and 2,3 to foreground. + out[0] = out[1] = bgcolor; + out[2] = out[3] = fgcolor; #else - #error unsupported color depth + // For all other pixel formats + out[0] = bgcolor; + out[3] = fgcolor; + out[1] = Color::mix(bgcolor, fgcolor, 85); // ~33% foreground + out[2] = Color::mix(bgcolor, fgcolor, 170); // ~66% foreground #endif } diff --git a/image.h b/image.h index e8b96a3..129fcac 100644 --- a/image.h +++ b/image.h @@ -32,6 +32,7 @@ #include "color.h" #include "iterator_direction.h" #include +#include namespace mxgui { @@ -156,7 +157,85 @@ bool basic_image_base::getScanLine(mxgui::Point p, mxgui::Color colors[], const T* data=this->getData(); if(data==0) return false; data+=p.x()+p.y()*this->getWidth(); - for(unsigned short i=0;i::value) + { + for(unsigned short i=0;i +inline bool basic_image_base::getScanLine(mxgui::Point p, mxgui::Color colors[], + unsigned short length) const +{ + if(p.x()<0 || p.y()<0) return false; + if(p.x()>=this->getWidth() || p.y()>=this->getHeight()) return false; + const unsigned char* data = reinterpret_cast(this->getData()); + if(data==0) return false; + + // Calculate stride: 1bpp are byte aligned + int stride = ((this->getWidth() + 7) & (~7)) / 8; + const unsigned char* rowData = data + (p.y() * stride); + + for(unsigned short i=0; i= this->getWidth()) break; + + unsigned char byte = rowData[x / 8]; + int bitIndex = x & 7; + + bool set = (byte & (0x80 >> bitIndex)); + colors[i] = set ? Color::white() : Color::black(); + } + return true; +} + +// Specialization for Gray4Color +template<> +inline bool basic_image_base::getScanLine(mxgui::Point p, mxgui::Color colors[], + unsigned short length) const +{ + if(p.x()<0 || p.y()<0) return false; + if(p.x()>=this->getWidth() || p.y()>=this->getHeight()) return false; + const unsigned char* data = reinterpret_cast(this->getData()); + if(data==0) return false; + + // Calculate stride: 4bpp are byte aligned + int stride = (this->getWidth() + 1) / 2; + const unsigned char* rowData = data + (p.y() * stride); + + for(unsigned short i=0; i= this->getWidth()) break; + + unsigned char byte = rowData[x / 2]; + unsigned char val = (x % 2 == 0) ? (byte >> 4) : (byte & 0x0F); + + if constexpr (std::is_same::value) + { + colors[i] = Color::fromRaw(val); + } + else + { + Gray4Color srcColor = Gray4Color::fromRaw(val); + colors[i] = Color(srcColor.getR(), srcColor.getG(), srcColor.getB()); + } + } return true; } @@ -171,8 +250,22 @@ void basic_image_base::draw(U& surface, Point p) const short int yEnd=p.y()+this->getHeight()-1; typename U::pixel_iterator it=surface.begin(p,Point(xEnd,yEnd),RD); int imgSize=this->getHeight()*this->getWidth(); - for(int i=0;i::value) + { + for(int i=0;iwidth; impl::AutoArray line(new Color[length]); for(short i=0;iheight;i++) @@ -183,12 +276,12 @@ void basic_image_base::draw(U& surface, Point p) const } } -// Specialization for Color1bitlinear +// Specialization for Gray1Color template<> template -void basic_image_base::draw(U& surface, Point p) const +void basic_image_base::draw(U& surface, Point p) const { using namespace std; - const Color1bitlinear *imgData=this->getData(); + const unsigned char *imgData=reinterpret_cast(this->getData()); if(imgData!=0) { short int xEnd=p.x()+this->getWidth()-1; @@ -197,27 +290,96 @@ void basic_image_base::draw(U& surface, Point p) const int h=this->getHeight(); int w=this->getWidth(); int stride=((w+7) & (~7))/8; //1bpp images have lines byte aligned - int last= w/8==stride ? stride : stride-1; + int last= w/8; for(int i=0;iwidth; + impl::AutoArray line(new Color[length]); + for(short i=0;iheight;i++) + { + if(this->getScanLine(Point(0,i),line.get(),length)==false) return; + surface.scanLine(Point(p.x(),p.y()+i),line.get(),length); + } + } +} + +// Specialization for Gray4Color +template<> template +void basic_image_base::draw(U& surface, Point p) const +{ + using namespace std; + const unsigned char *imgData=reinterpret_cast(this->getData()); + if(imgData!=0) + { + short int xEnd=p.x()+this->getWidth()-1; + short int yEnd=p.y()+this->getHeight()-1; + typename U::pixel_iterator it=surface.begin(p,Point(xEnd,yEnd),RD); + int h=this->getHeight(); + int w=this->getWidth(); + int stride=((w+1) & (~1))/2; // 4bpp images have lines byte aligned (2 pixels per byte) + int pairs= w/2; + + for(int i=0;i::value) + { + *it = Color::fromRaw(data >> 4); + *it = Color::fromRaw(data & 0x0F); + } + else + { + Gray4Color srcHigh = Gray4Color::fromRaw(data >> 4); + Gray4Color srcLow = Gray4Color::fromRaw(data & 0x0F); + *it = Color(srcHigh.getR(), srcHigh.getG(), srcHigh.getB()); + *it = Color(srcLow.getR(), srcLow.getG(), srcLow.getB()); + } + } + if (w & 1) { - *it=Color(data & 0x80 ? 1 : 0); - data<<=1; + unsigned char data=imgData[base+pairs]; // Last partial byte + if constexpr (std::is_same::value) + { + *it = Color::fromRaw(data >> 4); + } + else + { + Gray4Color srcHigh = Gray4Color::fromRaw(data >> 4); + *it = Color(srcHigh.getR(), srcHigh.getG(), srcHigh.getB()); + } } } } else { + // Fallback for non-memory-mapped images short length=this->width; impl::AutoArray line(new Color[length]); for(short i=0;iheight;i++) @@ -256,10 +418,22 @@ void basic_image_base::clippedDraw(U& surface, int toSkip=(xa-p.x())+((p.x()+this->getWidth()-1)-xb); for(short i=0;i::value) + { + for(short j=0;j line(new Color[nx]); for(short i=0;i::clippedDraw(U& surface, } } -// Specialization for Color1bitlinear +// Specialization for Gray1Color template<> template -void basic_image_base::clippedDraw(U& surface, +void basic_image_base::clippedDraw(U& surface, Point p, Point a, Point b) const { using namespace std; @@ -286,54 +460,101 @@ void basic_image_base::clippedDraw(U& surface, short yb=min(p.y()+this->getHeight()-1,b.y()); if(ya>yb) return; //Empty intersection - //Draw image short nx=xb-xa+1; short ny=yb-ya+1; - const Color1bitlinear *imgData=this->getData(); + const unsigned char *imgData=reinterpret_cast(this->getData()); if(imgData!=0) { typename U::pixel_iterator it=surface.begin(Point(xa,ya), Point(xb,yb),RD); - int stride=(this->getWidth()+7) & (~7); //1bpp images have lines byte aligned - int skipStart=(ya-p.y())*stride/8+(xa-p.x())/8; - imgData+=skipStart; - int toSkip=(xa-p.x())/8+((p.x()+stride-1)-xb)/8; - int head=(xa-p.x()) & 7; - int body=head ? nx-(8-head) : nx; - int tail=body & 7; - body/=8; + + int w=this->getWidth(); + int stride=((w+7) & (~7))/8; + + // Loop over rows in the clipped region for(int i=0;i> bitIndex)); + *it = set ? Color::white() : Color::black(); } - for(int j=0;j line(new Color[nx]); + for(short i=0;igetScanLine(Point(xa-p.x(),ya-p.y()+i), + line.get(),nx)==false) return; + surface.scanLine(Point(xa,ya+i),line.get(),nx); + } + } +} + +// Specialization for clippedDraw Gray4Color +template<> template +void basic_image_base::clippedDraw(U& surface, + Point p, Point a, Point b) const +{ + using namespace std; + //Find rectangle wich is the non-empty intersection of the image rectangle + //with the clip rectangle + short xa=max(p.x(),a.x()); + short xb=min(p.x()+this->getWidth()-1,b.x()); + if(xa>xb) return; //Empty intersection + + short ya=max(p.y(),a.y()); + short yb=min(p.y()+this->getHeight()-1,b.y()); + if(ya>yb) return; //Empty intersection + + short nx=xb-xa+1; + short ny=yb-ya+1; + const unsigned char *imgData=reinterpret_cast(this->getData()); + if(imgData!=0) + { + typename U::pixel_iterator it=surface.begin(Point(xa,ya), + Point(xb,yb),RD); + + int w=this->getWidth(); + int stride=((w+1) & (~1))/2; + + // Loop over rows in the clipped region + for(int i=0;i> 4) : (data & 0x0F); + + if constexpr (std::is_same::value) { - *it=Color(data & 0x80 ? 1 : 0); - data<<=1; + *it = Color::fromRaw(val); } - } - if(tail) - { - unsigned char data=*imgData++; - for(int k=0;k line(new Color[nx]); for(short i=0;i=this->getWidth() || p.y()>=this->getHeight()) return false; int o=p.x()+this->getWidth()*p.y(); fseek(f,this->offset+3*o,SEEK_SET); - //TODO: specialize: this only works if MXGUI_COLOR_DEPTH_16_BIT for(int i=0;i>3; + colors[i]=Color(pix[2], pix[1], pix[0]); // Red, Green, Blue } return true; }