public static Pixmap Bitmapize(Pixmap pixmap, int threshold) { pixmap.GetSize(out int width, out int height); Gdk.Image image = pixmap.GetImage(0, 0, width, height); Pixmap bitmap = new Pixmap(null, width, height, 1); Gdk.GC bitSetter = new Gdk.GC(bitmap) { Function = Gdk.Function.Set }; Gdk.GC bitClearer = new Gdk.GC(bitmap) { Function = Gdk.Function.Clear }; for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { if (BitConverter.GetBytes(image.GetPixel(x, y))[0] >= threshold) { bitmap.DrawPoint(bitSetter, x, y); } else { bitmap.DrawPoint(bitClearer, x, y); } } } return(bitmap); }
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)); }