void Graphics::fillRoundedRectangle (float x, float y, float width, float height, float cornerSize) const { fillRoundedRectangle (coordsToRectangle (x, y, width, height), cornerSize); }
void Graphics::fillRoundedRectangle (const Rectangle<float>& r, const float cornerSize) const { fillRoundedRectangle (r.getX(), r.getY(), r.getWidth(), r.getHeight(), cornerSize); }
void ArduRCT_Graphics::_executeMacroCommand(ardurct_graphicsMacroCommand_t *mc, int16_t x, int16_t y, uint16_t scaleMul, uint16_t scaleDiv) { uint8_t group = mc->cmd & GRAPHICS_MACRO_CMD_GROUP_MASK; // presets if (group == GRAPHICS_MACRO_CMD_GROUP_PRESET) { if (mc->cmd == GRAPHICS_MACRO_CMD_PRESET_FOREGROUND) _mForegroundColor = mc->color; else if (mc->cmd == GRAPHICS_MACRO_CMD_PRESET_BACKGROUND) _mBackgroundColor = mc->color; else if (mc->cmd == GRAPHICS_MACRO_CMD_PRESET_THICKNESS) { _mThickness = mc->param[GRAPHICS_MACRO_PARAM_THICKNESS]; _mIsThicknessScalable = mc->param[GRAPHICS_MACRO_PARAM_THICKNESS_IS_SCALABLE] != 0; } else if (mc->cmd == GRAPHICS_MACRO_CMD_PRESET_ERASE) fillScreen(_mBackgroundColor); else if (mc->cmd == GRAPHICS_MACRO_CMD_PRESET_FONT) { _mFontSize = mc->param[GRAPHICS_MACRO_PARAM_FONT_SIZE]; _mIsFontBold = (mc->param[GRAPHICS_MACRO_PARAM_FONT_IS_BOLD] != 0); _mIsFontOverlay = (mc->param[GRAPHICS_MACRO_PARAM_FONT_IS_OVERLAY] != 0); } else if (mc->cmd == GRAPHICS_MACRO_CMD_PRESET_SCALE) { _mScaleMul = mc->param[GRAPHICS_MACRO_PARAM_SCALE_MUL]; _mScaleDiv = 1; if ((mc->nbParams > 1) && (mc->param[GRAPHICS_MACRO_PARAM_SCALE_DIV] != 0)) _mScaleDiv = mc->param[GRAPHICS_MACRO_PARAM_SCALE_DIV]; } #ifdef GRAPHICS_MACRO_DEBUG Serial.println("preset"); #endif return; } int32_t sMul = _mScaleMul; sMul = sMul * (scaleMul == 0 ? 1 : scaleMul); int32_t sDiv = _mScaleDiv; sDiv = sDiv * (scaleDiv == 0 ? 1 : scaleDiv); int32_t sX = mc->param[GRAPHICS_MACRO_PARAM_X1]; sX = sX * sMul/sDiv + x; int32_t sY = mc->param[GRAPHICS_MACRO_PARAM_Y1]; sY = sY * sMul/sDiv + y; int32_t sThickness = _mThickness; if (_mIsThicknessScalable) sThickness = sThickness * sMul/sDiv; // lines if (group == GRAPHICS_MACRO_CMD_GROUP_LINE) { int32_t sX2, sY2; if (mc->nbParams < 2) return; if (mc->cmd == GRAPHICS_MACRO_CMD_LINE) { if (mc->nbParams > 2) { sX2 = mc->param[GRAPHICS_MACRO_PARAM_X2]; sX2 = x + sX2 * sMul/sDiv; sY2 = mc->param[GRAPHICS_MACRO_PARAM_Y2]; sY2 = y + sY2 * sMul/sDiv; // p2 becomes the end point _mX = mc->param[GRAPHICS_MACRO_PARAM_X2]; _mY = mc->param[GRAPHICS_MACRO_PARAM_Y2]; } else { sX2 = sX; sY2 = sY; sX = _mX; sX = x + sX * sMul/sDiv; sY = _mY; sY = y + sY * sMul/sDiv; // p1 becomes the end point _mX = mc->param[GRAPHICS_MACRO_PARAM_X1]; _mY = mc->param[GRAPHICS_MACRO_PARAM_Y1]; } } else { // delta values if (mc->nbParams > 2) { // p2 = p1+delta sX2 = mc->param[GRAPHICS_MACRO_PARAM_X1] + mc->param[GRAPHICS_MACRO_PARAM_X2]; sX2 = x + sX2 * sMul/sDiv; sY2 = mc->param[GRAPHICS_MACRO_PARAM_Y1] + mc->param[GRAPHICS_MACRO_PARAM_Y2]; sY2 = y + sY2 * sMul/sDiv; // p1+delta becomes the end point _mX = mc->param[GRAPHICS_MACRO_PARAM_X1] + mc->param[GRAPHICS_MACRO_PARAM_X2]; _mY = mc->param[GRAPHICS_MACRO_PARAM_Y1] + mc->param[GRAPHICS_MACRO_PARAM_Y2]; } else { // p2 = old_point+delta sX2 = _mX + mc->param[GRAPHICS_MACRO_PARAM_X1]; sX2 = x + sX2 * sMul/sDiv; sY2 = _mY + mc->param[GRAPHICS_MACRO_PARAM_Y1]; sY2 = y + sY2 * sMul/sDiv; sX = _mX; sX = x + sX * sMul/sDiv; sY = _mY; sY = y + sY * sMul/sDiv; // old_point+delta becomes the end point _mX += mc->param[GRAPHICS_MACRO_PARAM_X1]; _mY += mc->param[GRAPHICS_MACRO_PARAM_Y1]; } } #ifdef GRAPHICS_MACRO_DEBUG Serial.print("line "); Serial.print(sX); Serial.print(" "); Serial.print(sY); Serial.print(" "); Serial.print(sX2); Serial.print(" "); Serial.println(sY2); #endif drawLine(sX, sY, sX2, sY2, _mForegroundColor, sThickness, false); return; } // arcs if (group == GRAPHICS_MACRO_CMD_GROUP_ARC) { if (mc->nbParams < 1) return; boolean reversed = (mc->cmd == GRAPHICS_MACRO_CMD_ARC_REVERSED) || (mc->cmd == GRAPHICS_MACRO_CMD_ARC_FILLED_REVERSED); int32_t sRadius = 0; if (mc->nbParams == 1) { sRadius = mc->param[GRAPHICS_MACRO_PARAM_ARC_1]; sRadius = sRadius * sMul/sDiv; int32_t sArcStartX = _getArcEnd(sRadius, mc->param[GRAPHICS_MACRO_PARAM_ARC_OCTANT], !reversed, true); int32_t sArcStartY = _getArcEnd(sRadius, mc->param[GRAPHICS_MACRO_PARAM_ARC_OCTANT], !reversed, false); int32_t sArcEndX = _getArcEnd(sRadius, mc->param[GRAPHICS_MACRO_PARAM_ARC_OCTANT], reversed, true); int32_t sArcEndY = _getArcEnd(sRadius, mc->param[GRAPHICS_MACRO_PARAM_ARC_OCTANT], reversed, false); sX = _mX; sX = x + sX * sMul/sDiv - sArcStartX; sY = _mY; sY = y + sY * sMul/sDiv - sArcStartY; _mX += sArcEndX - sArcStartX; _mY += sArcEndY - sArcStartY; } else if (mc->nbParams == 3) { sRadius = mc->param[GRAPHICS_MACRO_PARAM_ARC_3]; sRadius = sRadius * sMul/sDiv; _mX = mc->param[GRAPHICS_MACRO_PARAM_X1] + _getArcEnd(mc->param[GRAPHICS_MACRO_PARAM_ARC_3], mc->param[GRAPHICS_MACRO_PARAM_ARC_OCTANT], reversed, true); _mY = mc->param[GRAPHICS_MACRO_PARAM_Y1] + _getArcEnd(mc->param[GRAPHICS_MACRO_PARAM_ARC_3], mc->param[GRAPHICS_MACRO_PARAM_ARC_OCTANT], reversed, false); } else return; if ((mc->cmd == GRAPHICS_MACRO_CMD_ARC_REVERSED) || (mc->cmd == GRAPHICS_MACRO_CMD_ARC)) drawArc(sX, sY, sRadius, mc->param[GRAPHICS_MACRO_PARAM_ARC_OCTANT], _mForegroundColor, sThickness, false); else fillArc(sX, sY, sRadius, mc->param[GRAPHICS_MACRO_PARAM_ARC_OCTANT], _mForegroundColor, false); #ifdef GRAPHICS_MACRO_DEBUG Serial.print("arc "); Serial.print(sX); Serial.print(" "); Serial.print(sY); Serial.print(" "); Serial.println(sRadius); #endif return; } // circles if (group == GRAPHICS_MACRO_CMD_GROUP_CIRCLE) { // we need at least 3 parameters if (mc->nbParams < 3) return; int32_t sRadius = mc->param[GRAPHICS_MACRO_PARAM_RADIUS]; sRadius = sRadius * sMul/sDiv; if (mc->cmd == GRAPHICS_MACRO_CMD_CIRCLE) drawCircle(sX, sY, sRadius, _mForegroundColor, sThickness, false); else fillCircle(sX, sY, sRadius, _mForegroundColor, false); #ifdef GRAPHICS_MACRO_DEBUG Serial.print("circle "); Serial.print(sX); Serial.print(" "); Serial.print(sY); Serial.print(" "); Serial.println(sRadius); #endif return; } // rectangles if (group == GRAPHICS_MACRO_CMD_GROUP_RECTANGLE) { // we need at least 4 parameters if (mc->nbParams < 4) return; int32_t sWidth = mc->param[GRAPHICS_MACRO_PARAM_WIDTH]; sWidth = sWidth * sMul/sDiv; int32_t sHeight = mc->param[GRAPHICS_MACRO_PARAM_HEIGHT]; sHeight = sHeight * sMul/sDiv; if (mc->cmd == GRAPHICS_MACRO_CMD_RECTANGLE) drawRectangle(sX, sY, sWidth, sHeight, _mForegroundColor, sThickness, false); else if (mc->cmd == GRAPHICS_MACRO_CMD_RECTANGLE_FILLED) fillRectangle(sX, sY, sWidth, sHeight, _mForegroundColor, false); #ifdef GRAPHICS_MACRO_DEBUG Serial.print("rectangle "); Serial.print(sX); Serial.print(" "); Serial.print(sY); Serial.print(" "); Serial.print(sWidth); Serial.print(" "); Serial.println(sHeight); #endif // we need at least 1 more parameter to display the rounded rectangle if (mc->nbParams < 5) return; int32_t sRadius = mc->param[GRAPHICS_MACRO_PARAM_ROUNDING]; sRadius = sRadius * sMul/sDiv; if (mc->cmd == GRAPHICS_MACRO_CMD_RECTANGLE_ROUNDED) drawRoundedRectangle(sX, sY, sWidth, sHeight, sRadius, _mForegroundColor, sThickness, false); else if (mc->cmd == GRAPHICS_MACRO_CMD_RECTANGLE_ROUNDED_FILLED) fillRoundedRectangle(sX, sY, sWidth, sHeight, sRadius, _mForegroundColor, false); return; } // triangles if (group == GRAPHICS_MACRO_CMD_GROUP_TRIANGLE) { // we need at least 6 parameters if (mc->nbParams < 6) return; int32_t sX2 = mc->param[GRAPHICS_MACRO_PARAM_X2]; sX2 = x + sX2 * sMul/sDiv; int32_t sY2 = mc->param[GRAPHICS_MACRO_PARAM_Y2]; sY2 = y + sY2 * sMul/sDiv; int32_t sX3 = mc->param[GRAPHICS_MACRO_PARAM_X3]; sX3 = x + sX3 * sMul/sDiv; int32_t sY3 = mc->param[GRAPHICS_MACRO_PARAM_Y3]; sY3 = y + sY3 * sMul/sDiv; if (mc->cmd == GRAPHICS_MACRO_CMD_TRIANGLE) drawTriangle(sX, sY, sX2, sY2, sX3, sY3, _mForegroundColor, sThickness, false); else if (mc->cmd == GRAPHICS_MACRO_CMD_TRIANGLE_FILLED) fillTriangle(sX, sY, sX2, sY2, sX3, sY3, _mForegroundColor, false); #ifdef GRAPHICS_MACRO_DEBUG Serial.print("triangle "); Serial.print(sX); Serial.print(" "); Serial.print(sY); Serial.print(" "); Serial.print(sX2); Serial.print(" "); Serial.print(sY2); Serial.print(" "); Serial.print(sX3); Serial.print(" "); Serial.println(sY3); #endif return; } // strings if (mc->cmd == GRAPHICS_MACRO_CMD_STRING) { if (mc->nbParams < 2) return; int bc = _backgroundColor; if (!_mIsFontOverlay) setBackgroundColor(_mBackgroundColor); drawString((char *)mc->text, sX, sY, _mForegroundColor, _mFontSize, _mIsFontBold, _mIsFontOverlay, false); if (!_mIsFontOverlay) setBackgroundColor(bc); #ifdef GRAPHICS_MACRO_DEBUG Serial.print("text "); Serial.println((char *)mc->text); #endif return; } // executes if (group == GRAPHICS_MACRO_CMD_GROUP_EXECUTE) { if (mc->param[GRAPHICS_MACRO_PARAM_MACRO_NUMBER] >= GRAPHICS_MACRO_MAX_NUMBER) return; // read the length in the EEPROM allocation table int length = eeprom_read_uint8_t(mc->param[GRAPHICS_MACRO_PARAM_MACRO_NUMBER]); if (length == 0xFF) return; // read the EEPROM pointers table to get the start int start = GRAPHICS_MACRO_MAX_NUMBER + mc->param[GRAPHICS_MACRO_PARAM_MACRO_NUMBER] * GRAPHICS_MACRO_MAX_SIZE; // get the compressed macro uint8_t buffer[GRAPHICS_MACRO_MAX_SIZE]; uint8_t i=0; while (i < length) { buffer[i] = eeprom_read_uint8_t(start+i); i++; } buffer[i] = 0; ardurct_graphicsMacroCommand_t emc; // uncompress the macro commands and execute them if (mc->cmd == GRAPHICS_MACRO_CMD_EXECUTE_WITH_RESET) _initializeMacros(); i = 0; while (i < length) { int8_t len = _uncompressMacroCommand(buffer, i, &emc); if (len == GRAPHICS_MACRO_FORMAT_ERROR) return; _executeMacroCommand(&emc, x, y, scaleMul, scaleDiv); i = len; } } }