void Graphics::drawRoundedRectangle (const Rectangle<float>& r, const float cornerSize, const float lineThickness) const { drawRoundedRectangle (r.getX(), r.getY(), r.getWidth(), r.getHeight(), cornerSize, lineThickness); }
void TangoBlock::drawCell (cairo_t *cr, gint x, gint y) { int i; cairo_pattern_t *pat = NULL; /* the following garbage is derived from the official tango style guide */ const gdouble colours[8][3][3] = { {{0.93725490196078431, 0.16078431372549021, 0.16078431372549021}, {0.8, 0.0, 0.0}, {0.64313725490196083, 0.0, 0.0}}, /* red */ {{0.54117647058823526, 0.88627450980392153, 0.20392156862745098}, {0.45098039215686275, 0.82352941176470584, 0.086274509803921567}, {0.30588235294117649, 0.60392156862745094, 0.023529411764705882}}, /* green */ {{0.44705882352941179, 0.62352941176470589, 0.81176470588235294}, {0.20392156862745098, 0.396078431372549, 0.64313725490196083}, {0.12549019607843137, 0.29019607843137257, 0.52941176470588236}}, /* blue */ {{0.93333333333333335, 0.93333333333333335, 0.92549019607843142}, {0.82745098039215681, 0.84313725490196079, 0.81176470588235294}, {0.72941176470588232, 0.74117647058823533, 0.71372549019607845}}, /* white */ {{0.9882352941176471, 0.9137254901960784, 0.30980392156862746}, {0.92941176470588238, 0.83137254901960789, 0.0}, {0.7686274509803922, 0.62745098039215685, 0.0}}, /* yellow */ {{0.67843137254901964, 0.49803921568627452, 0.6588235294117647}, {0.45882352941176469, 0.31372549019607843, 0.4823529411764706}, {0.36078431372549019, 0.20784313725490197, 0.4}}, /* purple */ {{0.9882352941176471, 0.68627450980392157, 0.24313725490196078}, {0.96078431372549022, 0.47450980392156861, 0.0}, {0.80784313725490198, 0.36078431372549019, 0.0}}, /* orange (replacing cyan) */ {{0.33, 0.34, 0.32}, {0.18, 0.2, 0.21}, {0.10, 0.12, 0.13}} /* grey */ }; if (data[x][y].what == EMPTY) return; if (data[x][y].what == TARGET) { i = 7; } else { i = data[x][y].color; i = CLAMP (i, 0, 6); } if (usegrads) { pat = cairo_pattern_create_linear (x+0.35, y, x+0.55, y+0.9); cairo_pattern_add_color_stop_rgb (pat, 0.0, colours[i][0][0], colours[i][0][1], colours[i][0][2]); cairo_pattern_add_color_stop_rgb (pat, 1.0, colours[i][1][0], colours[i][1][1], colours[i][1][2]); cairo_set_source (cr, pat); } else { cairo_set_source_rgb (cr, colours[i][0][0], colours[i][0][1], colours[i][0][2]); } drawRoundedRectangle (cr, x+0.05, y+0.05, 0.9, 0.9, 0.2); cairo_fill_preserve (cr); /* fill with shaded gradient */ if (usegrads) cairo_pattern_destroy(pat); cairo_set_source_rgb(cr, colours[i][2][0], colours[i][2][1], colours[i][2][2]); cairo_set_line_width (cr, 0.1); cairo_stroke (cr); /* add darker outline */ drawRoundedRectangle (cr, x+0.15, y+0.15, 0.7, 0.7, 0.08); if (data[x][y].what != TARGET) { if (usegrads) { pat = cairo_pattern_create_linear (x-0.3, y-0.3, x+0.8, y+0.8); switch (i) { /* yellow and white blocks need a brighter highlight */ case 3: case 4: cairo_pattern_add_color_stop_rgba (pat, 0.0, 1.0, 1.0, 1.0, 1.0); cairo_pattern_add_color_stop_rgba (pat, 1.0, 1.0, 1.0, 1.0, 0.0); break; default: cairo_pattern_add_color_stop_rgba (pat, 0.0, 0.9295, 0.9295, 0.9295, 1.0); cairo_pattern_add_color_stop_rgba (pat, 1.0, 0.9295, 0.9295, 0.9295, 0.0); break; } cairo_set_source (cr, pat); } else { cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 0.35); } } else { /* black preview block, use a much weaker highlight */ cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 0.15); } cairo_stroke (cr); /* add inner edge highlight */ if (usegrads && (data[x][y].what != TARGET)) cairo_pattern_destroy (pat); }
void Graphics::drawRoundedRectangle (float x, float y, float width, float height, float cornerSize, float lineThickness) const { drawRoundedRectangle (coordsToRectangle (x, y, width, height), cornerSize, lineThickness); }
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; } } }