public static Gtk.Image GetCircle(Color circleColor, byte alpha, int radius) { Pixmap color = new Pixmap(MainWindow.main.GdkWindow, radius * 2, radius * 2); Pixmap mask = new Pixmap(MainWindow.main.GdkWindow, radius * 2, radius * 2); Gdk.GC background = new Gdk.GC(color) { RgbFgColor = circleColor }; Gdk.GC visible = new Gdk.GC(mask) { RgbFgColor = new Color(alpha, alpha, alpha) }; Gdk.GC invisible = new Gdk.GC(mask) { RgbFgColor = new Color(0, 0, 0) }; color.DrawRectangle(background, true, new Rectangle(0, 0, radius * 2, radius * 2)); mask.DrawRectangle(invisible, true, new Rectangle(0, 0, radius * 2, radius * 2)); mask.DrawArc(visible, true, 0, 0, radius * 2, radius * 2, 0, FULL_CIRCLE); if (PlatformDetection.os == OS.Linux) { mask = Bitmapize(mask, 128); } return(new Gtk.Image(color, mask)); }
private void Redraw() { TooltipText = GetToolTip(); using (Gdk.GC gc = new Gdk.GC(map)) { gc.Colormap = Gdk.Colormap.System; gc.RgbFgColor = new Color(255, 255, 255); map.DrawRectangle(gc, true, 0, 0, Diameter, Diameter); // Paint a black ring gc.RgbFgColor = new Color(0, 0, 0); map.DrawArc(gc, true, Radius / 2, Radius / 2, Radius, Radius, 0, 360 * 64); // Paint the inner colour gc.RgbFgColor = GetColour(); map.DrawArc(gc, true, Radius / 2 + 1, Radius / 2 + 1, Radius - 2, Radius - 2, 0, 360 * 64); } image.QueueDraw(); }
void Draw() { if (pixmap == null) { return; } Style style = Style; StateType state = Sensitive ? StateType.Normal : StateType.Insensitive; if (width <= 0 || height <= 0) { return; } //clear the pixmap GtkBeans.Style.PaintFlatBox(style, pixmap, StateType.Normal, ShadowType.None, null, this, "curve_bg", 0, 0, Allocation.Width, Allocation.Height); //draw the grid lines for (int i = 0; i < 5; i++) { pixmap.DrawLine(style.DarkGC(state), x_offset, i * (int)(height / 4.0) + y_offset, width + x_offset, i * (int)(height / 4.0) + y_offset); pixmap.DrawLine(style.DarkGC(state), i * (int)(width / 4.0) + x_offset, y_offset, i * (int)(width / 4.0) + x_offset, height + y_offset); } //draw the curve pixmap.DrawPoints(style.ForegroundGC(state), Interpolate(width, height)); //draw the bullets if (CurveType != CurveType.Free) { foreach (var keyval in points) { if (keyval.Key < MinX) { continue; } int x = Project(keyval.Key, MinX, MaxX, width); int y = height - Project(keyval.Value, MinY, MaxY, height); pixmap.DrawArc(style.ForegroundGC(state), true, x, y, radius * 2, radius * 2, 0, 360 * 64); } } GdkWindow.DrawDrawable(style.ForegroundGC(state), pixmap, 0, 0, 0, 0, Allocation.Width, Allocation.Height); }
public static Gtk.Image GetLocationPin(Color pinColor, int pinWidth, int pinHeight) { double pixelWidth = pinWidth; double pixelHeight = pinHeight; //Independent quantities double w = pixelWidth * RESOLUTION_FACTOR; double r = w / 2; double h = pixelHeight * RESOLUTION_FACTOR; double m = BLACK_TRIM_WIDTH * RESOLUTION_FACTOR; //Dependent quantities double v = Math.Sqrt(h * h - h * w); double u = r / (h - r); Pixmap color = new Pixmap(MainWindow.main.GdkWindow, (int)w, (int)h); Pixmap mask = new Pixmap(MainWindow.main.GdkWindow, (int)w, (int)h); Gdk.GC markerShape = new Gdk.GC(color) { RgbFgColor = pinColor }; color.DrawRectangle(black, true, new Rectangle(0, 0, (int)w, (int)h)); mask.DrawRectangle(invisible, true, new Rectangle(0, 0, (int)w, (int)h)); color.DrawArc(markerShape, true, (int)m, (int)m, (int)(w - m * 2), (int)(w - m * 2), 0, FULL_CIRCLE); mask.DrawArc(visible, true, 0, 0, (int)w, (int)w, 0, FULL_CIRCLE); // The "triangle" here refers to the triangle formed by the bottom vertex, a tangent point and the bottom of the image. // // ------- --- Independent quantities: // / | \ | r = radius of circle // | |_____| | h = height of pin // | | r | | m = thickness of black trim // \ | /. h // \ | / . | Dependent quantities: // \ |θ /v . | θ = angle between axis of symmetry and the sides of the spear // \ |^/ . | u = sin θ // \|/..... _|_ v = hypotenuse of the spear // r // // [center] O___ // | ---___[innerRight] // | O--___ // |________/______--O [outerRight] // | / / // | / / // | / / // | / / // | / / // | / / // | / / // |/ / v // [innerBottom] O--___ / // | m --/ // | / // | / // | / // | / // |θ / // |^/ // |/ // [outerBottom] O Vector2 center = new Vector2(r, r); Vector2 outerBottom = new Vector2(w / 2, h); Vector2 innerBottom = new Vector2(r, h - m / u); Vector2 outerLeft = center + new Vector2(-u * v, u * r); Vector2 outerRight = center + new Vector2(u * v, u * r); Vector2 innerLeft = outerLeft - new Vector2(-m * u * v / r, u * m); Vector2 innerRight = outerRight - new Vector2(m * u * v / r, u * m); //u*v/r = cos θ. color.DrawPolygon(markerShape, true, new Point[] { innerBottom.ToPoint(), innerLeft.ToPoint(), innerRight.ToPoint() }); mask.DrawPolygon(visible, true, new Point[] { outerBottom.ToPoint(), outerLeft.ToPoint(), outerRight.ToPoint() }); double coreRadius = w / 5; double coreCenter = w / 2; color.DrawArc(black, true, (int)(coreCenter - coreRadius - m), (int)(coreCenter - coreRadius - m), (int)(coreRadius * 2 + m * 2), (int)(coreRadius * 2 + m * 2), 0, FULL_CIRCLE); mask.DrawArc(film, true, (int)(coreCenter - coreRadius), (int)(coreCenter - coreRadius), (int)(coreRadius * 2), (int)(coreRadius * 2), 0, FULL_CIRCLE); Pixmap scaledColor = Scale(color, w, h, 0.1); Pixmap scaledMask = Scale(mask, w, h, 0.1); if (PlatformDetection.os == OS.Linux) { scaledMask = Bitmapize(scaledMask, 128); } return(new Gtk.Image(scaledColor, scaledMask)); }
public static Gtk.Image GetIcon(object iconified, Color iconColor, int iconSize, bool decor = false) { IconRequest request = new IconRequest(iconified, iconColor, iconSize); if (iconCache.ContainsKey(request)) { return(new Gtk.Image(iconCache[request].color, iconCache[request].mask)); } double pixelSize = iconSize; double size = pixelSize * RESOLUTION_FACTOR; //Since 12 across is 0-11; we don't want to draw on 12 and lose pixels. Pixmap color = new Pixmap(MainWindow.main.GdkWindow, (int)size, (int)size); Pixmap mask = new Pixmap(MainWindow.main.GdkWindow, (int)size, (int)size); Gdk.GC colorGC = new Gdk.GC(color) { RgbFgColor = iconColor }; if (iconified is Threat) { color.DrawRectangle(colorGC, true, new Rectangle(0, 0, (int)size, (int)size)); mask.DrawRectangle(invisible, true, new Rectangle(0, 0, (int)size, (int)size)); switch ((Threat)iconified) { case Threat.C: // a circle mask.DrawArc(visible, true, (int)(size * 0.225), (int)(size * 0.225), (int)(size * 0.55), (int)(size * 0.55), 0, FULL_CIRCLE); break; case Threat.B: // A square double squareSize = 0.55 * size; double margin = (size - squareSize) / 2; mask.DrawPolygon(visible, true, new Point[] { new Point((int)margin, (int)margin), new Point((int)(margin + squareSize), (int)margin), new Point((int)(margin + squareSize), (int)(margin + squareSize)), new Point((int)margin, (int)(margin + squareSize)) }); break; case Threat.A: // A triangle with the point upwards. double width = size * 0.75; double height = width * Math.Sqrt(3) / 2; mask.DrawPolygon(visible, true, new Point[] { new Point((int)(size * 0.1), (int)(size - height) / 2), new Point((int)(size * 0.9), (int)(size - height) / 2), new Point((int)(size / 2), (int)(size + height) / 2) }); break; case Threat.S: // A four-pointed star. mask.DrawPolygon(visible, true, new Point[] { new Point(0, (int)(size / 2)), new Point((int)(size / 3), (int)(size / 3)), new Point((int)(size / 2), 0), new Point((int)(size * 2 / 3), (int)(size / 3)), new Point((int)size, (int)(size / 2)), new Point((int)(size * 2 / 3), (int)(size * 2 / 3)), new Point((int)(size / 2), (int)size), new Point((int)(size / 3), (int)(size * 2 / 3)) }); break; case Threat.X: mask.DrawArc(visible, true, (int)(size * 0.05), (int)(size * 0.05), (int)(size * 0.9), (int)(size * 0.9), 0, FULL_CIRCLE); mask.DrawArc(invisible, true, (int)(size * 0.15), (int)(size * 0.15), (int)(size * 0.7), (int)(size * 0.7), 0, FULL_CIRCLE); mask.DrawArc(visible, true, (int)(size * 0.4), (int)(size * 0.4), (int)(size * 0.2), (int)(size * 0.2), 0, FULL_CIRCLE); mask.DrawPoint(visible, (int)(size / 2), (int)(size / 2)); break; } } else if (iconified is StructureType) { if (decor) { color.DrawRectangle(black, true, new Rectangle(0, 0, (int)size, (int)size)); mask.DrawRectangle(invisible, true, new Rectangle(0, 0, (int)size, (int)size)); mask.DrawArc(translucent, true, 0, 0, (int)size, (int)size, 0, FULL_CIRCLE); } else { color.DrawRectangle(colorGC, true, new Rectangle(0, 0, (int)size, (int)size)); mask.DrawRectangle(invisible, true, new Rectangle(0, 0, (int)size, (int)size)); } switch ((StructureType)iconified) { case StructureType.Tactical: double width = size * 0.7; double height = size * 0.75; double xMargin = (size - width) / 2; double yMargin = (size - height) / 2; double dipHeight = size * 0.1; double peakHeight = size * 0.3; Vector2 upperLeft = new Vector2(xMargin, yMargin); Vector2 upperRight = upperLeft + new Vector2(width, 0); Vector2 lowerLeft = upperLeft + new Vector2(0, height - peakHeight); Vector2 lowerRight = upperRight + new Vector2(0, height - peakHeight); Vector2 upperMiddle = new Vector2(size / 2, yMargin + dipHeight); Vector2 lowerMiddle = new Vector2(size / 2, size - yMargin); mask.DrawPolygon(visible, true, new Point[] { upperLeft.ToPoint(), upperMiddle.ToPoint(), upperRight.ToPoint(), lowerRight.ToPoint(), lowerMiddle.ToPoint(), lowerLeft.ToPoint() }); if (decor) { color.DrawPolygon(colorGC, true, new Point[] { upperLeft.ToPoint(), upperMiddle.ToPoint(), upperRight.ToPoint(), lowerRight.ToPoint(), lowerMiddle.ToPoint(), lowerLeft.ToPoint() }); } break; case StructureType.Economic: Vector2 center = new Vector2(size / 2, size / 2); double radii = 0.2 * size; double diameter = radii * 2; Vector2 topCenter = center - new Vector2(0, 2 * radii / Math.Sqrt(3)); Vector2 leftCenter = center + new Vector2(radii, Math.Sqrt(2) / 2 * radii); Vector2 rightCenter = center + new Vector2(-radii, Math.Sqrt(2) / 2 * radii); Vector2 topCorner = topCenter - new Vector2(radii, radii); Vector2 leftCorner = leftCenter - new Vector2(radii, radii); Vector2 rightCorner = rightCenter - new Vector2(radii, radii); mask.DrawArc(visible, true, (int)topCorner.x, (int)topCorner.y, (int)diameter, (int)diameter, 0, FULL_CIRCLE); if (decor) { color.DrawArc(colorGC, true, (int)topCorner.x, (int)topCorner.y, (int)diameter, (int)diameter, 0, FULL_CIRCLE); } mask.DrawArc(visible, true, (int)leftCorner.x, (int)leftCorner.y, (int)diameter, (int)diameter, 0, FULL_CIRCLE); if (decor) { color.DrawArc(colorGC, true, (int)leftCorner.x, (int)leftCorner.y, (int)diameter, (int)diameter, 0, FULL_CIRCLE); } mask.DrawArc(visible, true, (int)rightCorner.x, (int)rightCorner.y, (int)diameter, (int)diameter, 0, FULL_CIRCLE); if (decor) { color.DrawArc(colorGC, true, (int)rightCorner.x, (int)rightCorner.y, (int)diameter, (int)diameter, 0, FULL_CIRCLE); } break; case StructureType.Aesthetic: double radius1 = size * 0.4; double margin1 = size / 2 - radius1; double radius2 = radius1 * 0.75; double margin2 = size / 2 - radius2; mask.DrawArc(visible, true, (int)margin1, (int)margin1, (int)(radius1 * 2), (int)(radius1 * 2), 0, FULL_CIRCLE); if (decor) { color.DrawArc(colorGC, true, (int)margin1, (int)margin1, (int)(radius1 * 2), (int)(radius1 * 2), 0, FULL_CIRCLE); color.DrawArc(black, true, (int)margin2, (int)margin1, (int)(radius2 * 2), (int)(radius2 * 2), 0, FULL_CIRCLE); mask.DrawArc(translucent, true, (int)margin2, (int)margin1, (int)(radius2 * 2), (int)(radius2 * 2), 0, FULL_CIRCLE); } else { mask.DrawArc(invisible, true, (int)margin2, (int)margin1, (int)(radius2 * 2), (int)(radius2 * 2), 0, FULL_CIRCLE); } break; } } else if (iconified is IconTemplate) { color.DrawRectangle(colorGC, true, new Rectangle(0, 0, (int)size, (int)size)); mask.DrawRectangle(invisible, true, new Rectangle(0, 0, (int)size, (int)size)); switch ((IconTemplate)iconified) { case IconTemplate.LeftArrow: mask.DrawPolygon(visible, true, new Point[] { new Point((int)size, 0), new Point(0, (int)(size / 2)), new Point((int)size, (int)size) }); break; case IconTemplate.RightArrow: mask.DrawPolygon(visible, true, new Point[] { new Point(0, 0), new Point((int)size, (int)(size / 2)), new Point(0, (int)size) }); break; case IconTemplate.X: int close = (int)(size / 6); int far = (int)(size * 5 / 6); int end = (int)size; mask.DrawPolygon(visible, true, new Point[] { new Point(close, 0), new Point(end, far), new Point(far, end), new Point(0, close) }); mask.DrawPolygon(visible, true, new Point[] { new Point(far, 0), new Point(0, far), new Point(close, end), new Point(end, close) }); break; } } /* * double radius = 0.55 * size; * double d = radius * 2; * double eyeballRadius = radius * 0.45; * double pupilRadius = eyeballRadius * 0.45; * Vector2 upCenter = new Vector2(size / 2, size / 2 - radius / 2); * Vector2 downCenter = new Vector2(size / 2, size / 2 + radius / 2); * Vector2 upCorner = upCenter - new Vector2(radius, radius); * Vector2 downCorner = downCenter - new Vector2(radius, radius); * mask.DrawArc(visible, true, (int)upCorner.x, (int)upCorner.y, (int)d, (int)d, -30 * 64, -120 * 64); * mask.DrawArc(visible, true, (int)downCorner.x, (int)downCorner.y, (int)d, (int)d, 30 * 64, 120 * 64); * mask.DrawArc(invisible, true, (int)(size / 2 - eyeballRadius), (int)(size / 2 - eyeballRadius), * (int)(eyeballRadius * 2), (int)(eyeballRadius * 2), 0, FULL_CIRCLE); * mask.DrawArc(visible, true, (int)(size / 2 - pupilRadius), (int)(size / 2 - pupilRadius), * (int)(pupilRadius * 2), (int)(pupilRadius * 2), 0, FULL_CIRCLE); */ Pixmap scaledColor = Scale(color, size, size, 0.1); Pixmap scaledMask = Scale(mask, size, size, 0.1); if (PlatformDetection.os == OS.Linux) { scaledMask = Bitmapize(scaledMask, 75); } iconCache.Add(request, new Icon(scaledColor, scaledMask)); return(new Gtk.Image(scaledColor, scaledMask)); }
public void DrawChart(object obj, SizeAllocatedArgs args) { int width = args.Allocation.Width; int height = args.Allocation.Height; int size = Math.Min(width, height); //If this is true, then we don't need to update. if (size == currentSize) { return; } currentSize = size; currentSize = size; int chartRadius = size; int labelRadius = 0; color = new Pixmap(MainWindow.main.GdkWindow, size, size); mask = new Pixmap(MainWindow.main.GdkWindow, size, size); Gdk.GC visible = new Gdk.GC(mask) { RgbFgColor = new Color(255, 255, 255) }; Gdk.GC invisible = new Gdk.GC(mask) { RgbFgColor = new Color(0, 0, 0) }; Gdk.GC white = new Gdk.GC(color) { RgbFgColor = new Color(255, 255, 255) }; // for marking the mask. Gdk.GC lightGrey = new Gdk.GC(color) { RgbFgColor = new Color(200, 200, 200) }; // for the axes Gdk.GC grey = new Gdk.GC(color) { RgbFgColor = new Color(125, 125, 125) }; // for the axis markings Gdk.GC darkGrey = new Gdk.GC(color) { RgbFgColor = new Color(100, 100, 100) }; // for the axis labels Gdk.GC[] wrapperColors = { new Gdk.GC(color) { RgbFgColor = new Gdk.Color(170, 140, 0) }, //Regular new Gdk.GC(color) { RgbFgColor = new Color(0, 0, 200) }, //Tinker new Gdk.GC(color) { RgbFgColor = new Color(0, 150, 0) }, //Master new Gdk.GC(color) { RgbFgColor = new Color(0, 0, 0) }, //Breaker }; color.DrawRectangle(white, true, new Rectangle(0, 0, size, size)); mask.DrawRectangle(invisible, true, new Rectangle(0, 0, size, size)); //The eight directions in which vertices lie Vector2[] directions = { new Vector2(0, -1), new Vector2(Math.Sqrt(2) / 2, -Math.Sqrt(2) / 2), new Vector2(1, 0), new Vector2(Math.Sqrt(2) / 2, Math.Sqrt(2) / 2), new Vector2(0, 1), new Vector2(-Math.Sqrt(2) / 2, Math.Sqrt(2) / 2), new Vector2(-1, 0), new Vector2(-Math.Sqrt(2) / 2, -Math.Sqrt(2) / 2) }; IntVector2 center = new IntVector2(size / 2, size / 2); //Compute magnitudes int[] indexMap = { 0, 1, 5, 3, 7, 0, 4, 6, 2 }; //old[0] -> new[1], old[1] -> new[5] etc. int[] reverseIndexMap = { 5, 1, 8, 3, 6, 2, 7, 4 }; //old[0] -> new[1], old[1] -> new[5] etc. float[] magnitudes = new float[8]; //Magnitudes of the positions of the vertices float[,] fractions = new float[8, 3]; //Fractional contribution of each wrapper of each rating classification for (int i = 1; i <= 8; i++) { int j = indexMap[i]; magnitudes[j] = values[4, i] > 0 ? values[4, i] : 0; if (o_vals[4, i] != 0) { fractions[j, 0] = (float)o_vals[0, i] / o_vals[4, i]; fractions[j, 1] = (float)(o_vals[0, i] + o_vals[1, i]) / o_vals[4, i]; fractions[j, 2] = (float)(o_vals[0, i] + o_vals[1, i] + o_vals[2, i]) / o_vals[4, i]; } } float greatestMagnitude = 0; for (int i = 0; i < 8; i++) { if (magnitudes[i] > greatestMagnitude) { greatestMagnitude = magnitudes[i]; } } if (greatestMagnitude < 0.01) { return; } //Determing text radius and preload labels; Pango.Layout[] labels = new Pango.Layout[8]; IntVector2[] labelSizes = new IntVector2[8]; for (int i = 0; i < 8; i++) { //Label labels[i] = new Pango.Layout(PangoContext) { Alignment = Pango.Alignment.Center }; if (multipliers == null) { labels[i].SetText(Ratings.symbols[reverseIndexMap[i]]); } else { labels[i].SetMarkup(Ratings.symbols[reverseIndexMap[i]] + "\n<small>×" + multipliers[reverseIndexMap[i]].ToString("0.0") + "</small>"); } labels[i].GetSize(out int labelWidth, out int labelHeight); labelSizes[i] = new IntVector2(labelWidth, labelHeight) / Pango.Scale.PangoScale; int thisLabelRadius = Math.Max(labelSizes[i].x, labelSizes[i].y); if (thisLabelRadius > labelRadius) { labelRadius = thisLabelRadius; chartRadius = size / 2 - labelRadius * 2; } } for (int i = 0; i < 8; i++) { IntVector2 textPoint = directions[i] * (chartRadius + labelRadius) + (Vector2)center - (Vector2)labelSizes[i] / 2; color.DrawLayout(darkGrey, textPoint.x, textPoint.y, labels[i]); mask.DrawLayout(visible, textPoint.x, textPoint.y, labels[i]); //Line IntVector2 endPoint = (directions[i] * chartRadius) + (Vector2)center; color.DrawLine(lightGrey, center.x, center.y, endPoint.x, endPoint.y); mask.DrawLine(visible, center.x, center.y, endPoint.x, endPoint.y); } //Draw circles and axis markings float theoreticalPtInterval = (size / 6 + 20) / 2; float theoreticalRatingInterval = theoreticalPtInterval / chartRadius * greatestMagnitude; //(between 20pt markings) int ratingInterval = (int)Math.Round(theoreticalRatingInterval); //Round it off for neatness float ptInterval = ratingInterval / greatestMagnitude * chartRadius; //Now what's the pt interval for that? for (int i = 1; ptInterval * i < chartRadius; i++) { //Circle int radius = (int)(ptInterval * i); color.DrawArc(lightGrey, false, center.x - radius, center.y - radius, radius * 2, radius * 2, 0, 23040); //Angles are in 1/64th degrees, 23040 = 360*64 = full circle. mask.DrawArc(visible, false, center.x - radius, center.y - radius, radius * 2, radius * 2, 0, 23040); //Axis marking Pango.Layout mark = new Pango.Layout(PangoContext); mark.SetText("" + ratingInterval * i); mark.GetSize(out int markWidth, out int markHeight); IntVector2 markSize = new IntVector2(markWidth, markHeight) / Pango.Scale.PangoScale; IntVector2 markCenter = (Vector2)center + directions[2] * ptInterval * i; mask.DrawArc(invisible, true, markCenter.x - markSize.x / 2, markCenter.y - markSize.y / 2, markSize.x, markSize.y, 0, 23040); //Clears a circular space for the mark color.DrawLayout(grey, markCenter.x - markSize.x / 2, markCenter.y - markSize.y / 2, mark); //Actually mask.DrawLayout(visible, markCenter.x - markSize.x / 2, markCenter.y - markSize.y / 2, mark); //draw the mark. } //Compute vertices IntVector2[,] vertices = new IntVector2[4, 8]; for (int i = 0; i < 8; i++) { for (int j = 0; j < 3; j++) { vertices[j, i] = directions[i] * (chartRadius / greatestMagnitude) * magnitudes[i] * fractions[i, j] + (Vector2)center; } vertices[3, i] = directions[i] * (chartRadius / greatestMagnitude) * magnitudes[i] + (Vector2)center; } //Bump vertices by a pixel if they overlap. bool changed = true; while (changed) { changed = false; for (int i = 3; i > 1; i--) { for (int j = 0; j < 8; j++) { if (vertices[i, j] == vertices[i - 1, j]) { vertices[i, j] += (IntVector2)directions[j]; changed = true; } } } } //Draw polygons for (int i = 0; i < 4; i++) { for (int j = 0; j < 7; j++) //j=7 is excluded as we need to connect it to vertex 0 manually. { color.DrawLine(wrapperColors[i], vertices[i, j].x, vertices[i, j].y, //This point vertices[i, j + 1].x, vertices[i, j + 1].y); //Next point mask.DrawLine(visible, vertices[i, j].x, vertices[i, j].y, //This point vertices[i, j + 1].x, vertices[i, j + 1].y); //Next point } color.DrawLine(wrapperColors[i], vertices[i, 7].x, vertices[i, 7].y, //Point 7 vertices[i, 0].x, vertices[i, 0].y); //Point 0 mask.DrawLine(visible, vertices[i, 7].x, vertices[i, 7].y, //Point 7 vertices[i, 0].x, vertices[i, 0].y); //Point 0 } if (metamultipliers != null) { int currentY = size - 5; for (int i = 3; i >= 0; i--) { Pango.Layout label = new Pango.Layout(PangoContext) { Alignment = Pango.Alignment.Center }; label.SetMarkup("<small>x" + metamultipliers[i].ToString("0.0") + "</small>"); label.GetSize(out int labelWidth, out int labelHeight); labelWidth = (int)(labelWidth / Pango.Scale.PangoScale); labelHeight = (int)(labelHeight / Pango.Scale.PangoScale); currentY -= labelHeight; color.DrawLayout(wrapperColors[i], size - labelWidth - 5, currentY, label); mask.DrawLayout(visible, size - labelWidth - 5, currentY, label); } } SetFromPixmap(color, mask); }