[dia] Misc - Ngon: new object for regular polygon or star
- From: Hans Breuer <hans src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [dia] Misc - Ngon: new object for regular polygon or star
- Date: Sun, 8 Jun 2014 09:00:08 +0000 (UTC)
commit 20a0ad5b37a85d980cb450cb52081073df2d152c
Author: Hans Breuer <hans breuer org>
Date: Sat May 24 13:21:08 2014 +0200
Misc - Ngon: new object for regular polygon or star
A basic object to draw a regular polygon. Based on the given number of 'rays'
three different interpretations are possible: a regular polygon, a star
with the same number of edges but crossing; a concave polygon doubling the
total number of points.
objects/Misc/Makefile.am | 3 +-
objects/Misc/libmisc.c | 2 +
objects/Misc/n_gon.c | 531 ++++++++++++++++++++++++++++++++++++++++
objects/Misc/pixmaps/n_gon.xpm | 84 +++++++
objects/makefile.msc | 1 +
sheets/Misc.sheet.in | 3 +
6 files changed, 623 insertions(+), 1 deletions(-)
---
diff --git a/objects/Misc/Makefile.am b/objects/Misc/Makefile.am
index d303f22..a820b15 100644
--- a/objects/Misc/Makefile.am
+++ b/objects/Misc/Makefile.am
@@ -7,6 +7,7 @@ libmisc_objects_la_SOURCES = \
diagram_as_object.c \
grid_object.c \
measure.c \
+ n_gon.c \
tree.c
@@ -22,7 +23,7 @@ EXTRA_DIST = \
pixmaps/diagram_as_element.xpm \
pixmaps/grid_object.xpm \
pixmaps/measure.xpm \
- pixmaps/newgroup.xpm \
+ pixmaps/n_gon.xpm \
pixmaps/tree.xpm
diff --git a/objects/Misc/libmisc.c b/objects/Misc/libmisc.c
index e72ea9a..09049f0 100644
--- a/objects/Misc/libmisc.c
+++ b/objects/Misc/libmisc.c
@@ -33,6 +33,7 @@ extern DiaObjectType grid_object_type;
extern DiaObjectType tree_type;
extern DiaObjectType measure_type;
extern DiaObjectType diagram_as_element_type;
+extern DiaObjectType _ngon_type;
DIA_PLUGIN_CHECK_INIT
@@ -48,6 +49,7 @@ dia_plugin_init(PluginInfo *info)
object_register_type(&tree_type);
object_register_type(&measure_type);
object_register_type(&diagram_as_element_type);
+ object_register_type(&_ngon_type);
return DIA_PLUGIN_INIT_OK;
}
diff --git a/objects/Misc/n_gon.c b/objects/Misc/n_gon.c
new file mode 100644
index 0000000..85a0b06
--- /dev/null
+++ b/objects/Misc/n_gon.c
@@ -0,0 +1,531 @@
+/* Dia -- an diagram creation/manipulation program
+ * Copyright (C) 1998 Alexander Larsson
+ *
+ * n_gon.c -- an equilateral polygon or star (polygram?)
+ * Copyright (C) 2014 Hans Breuer <hans breuer org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#include <config.h>
+
+#include "object.h"
+#include "diarenderer.h"
+#include "attributes.h"
+#include "properties.h"
+#include "boundingbox.h"
+#include "element.h"
+#include "pattern.h"
+#include "intl.h"
+
+#include "pixmaps/n_gon.xpm"
+
+typedef enum {
+ NGON_CONVEX = 0, /*!< triangle, square, hexagon, ... */
+ NGON_CONCAVE, /*!< concave aka. a star (num_rays >= 5) */
+ NGON_CROSSING /*!< concave with crossing rays */
+} NgonKind;
+
+#define NUM_HANDLES 9
+#define NUM_CONNECTIONS 1
+
+typedef struct _Ngon Ngon;
+
+/*!
+ * \brief Equilateral Polygon
+ * \extends _Element
+ */
+struct _Ngon {
+ /*! \protected _Element must be first because this is a 'subclass' of it. */
+ Element element;
+
+ ConnectionPoint connections[NUM_CONNECTIONS];
+ Handle center_handle;
+
+ int num_rays;
+ NgonKind kind;
+ LineStyle line_style;
+ LineJoin line_join;
+ real dashlength;
+ real line_width;
+ Color stroke;
+ Color fill;
+ gboolean show_background;
+ DiaPattern *pattern;
+
+ /*! To recalculate the points, it's also the object.position */
+ Point center;
+ /*! The radius of the circumscribed circle */
+ real ray_len;
+ /*! \private Calculated points cache */
+ GArray *points;
+ /*! A generated name */
+ char *name;
+};
+
+static DiaObject *
+_ngon_create (Point *startpoint,
+ void *user_data,
+ Handle **handle1,
+ Handle **handle2);
+static DiaObject *
+_ngon_load (ObjectNode obj_node, int version, DiaContext *ctx);
+static void
+_ngon_save (DiaObject *obj, ObjectNode obj_node, DiaContext *ctx);
+
+static ObjectTypeOps _ngon_type_ops =
+{
+ (CreateFunc) _ngon_create,
+ (LoadFunc) _ngon_load, /* can't use object_load_using_properties, signature mismatch */
+ (SaveFunc) _ngon_save, /* overwrite for filename normalization */
+ (GetDefaultsFunc) NULL,
+ (ApplyDefaultsFunc) NULL
+};
+
+static void _ngon_update_data (Ngon *ng);
+
+static PropEnumData _ngon_type_data[] = {
+ { N_("Convex"), NGON_CONVEX },
+ { N_("Concave"), NGON_CONCAVE },
+ { N_("Crossing"), NGON_CROSSING },
+ { NULL, }
+};
+static PropNumData _num_rays_range_data = { 3, 360, 1 };
+
+static PropDescription _ngon_props[] = {
+ ELEMENT_COMMON_PROPERTIES,
+ { "ngon_kind", PROP_TYPE_ENUM, PROP_FLAG_VISIBLE,
+ N_("N-gon kind"), NULL, &_ngon_type_data },
+ { "num_rays", PROP_TYPE_INT, PROP_FLAG_VISIBLE,
+ N_("Number of rays"), NULL, &_num_rays_range_data },
+ { "center", PROP_TYPE_POINT, PROP_FLAG_NO_DEFAULTS, /* no property widget, but still to be serialized */
+ N_("Center position"), NULL, NULL },
+ { "ray_len", PROP_TYPE_REAL, PROP_FLAG_NO_DEFAULTS, /* no property widget, but still to be serialized */
+ N_("Ray length"), NULL, NULL },
+ PROP_STD_LINE_WIDTH,
+ PROP_STD_LINE_STYLE_OPTIONAL,
+ PROP_STD_LINE_JOIN_OPTIONAL,
+ PROP_STD_LINE_COLOUR,
+ PROP_STD_FILL_COLOUR,
+ PROP_STD_SHOW_BACKGROUND,
+ { "pattern", PROP_TYPE_PATTERN, PROP_FLAG_VISIBLE|PROP_FLAG_OPTIONAL,
+ N_("Pattern"), NULL },
+ { "name", PROP_TYPE_STRING, PROP_FLAG_DONT_SAVE| PROP_FLAG_OPTIONAL | PROP_FLAG_NO_DEFAULTS,
+ N_("Name"), NULL, NULL },
+ PROP_DESC_END
+};
+static PropDescription *
+_ngon_describe_props(Ngon *ng)
+{
+ if (_ngon_props[0].quark == 0)
+ prop_desc_list_calculate_quarks(_ngon_props);
+ return _ngon_props;
+}
+static PropOffset _ngon_offsets[] = {
+ ELEMENT_COMMON_PROPERTIES_OFFSETS,
+ { "ngon_kind", PROP_TYPE_ENUM, offsetof(Ngon, kind) },
+ { "num_rays", PROP_TYPE_INT, offsetof(Ngon, num_rays) },
+ { "center", PROP_TYPE_POINT, offsetof(Ngon, center) },
+ { "ray_len", PROP_TYPE_REAL, offsetof(Ngon, ray_len) },
+ { PROP_STDNAME_LINE_WIDTH, PROP_STDTYPE_LINE_WIDTH, offsetof(Ngon, line_width) },
+ { "line_style", PROP_TYPE_LINESTYLE, offsetof(Ngon, line_style), offsetof(Ngon, dashlength) },
+ { "line_join", PROP_TYPE_ENUM, offsetof(Ngon, line_join) },
+ { "line_colour", PROP_TYPE_COLOUR, offsetof(Ngon, stroke) },
+ { "fill_colour", PROP_TYPE_COLOUR, offsetof(Ngon, fill) },
+ { "show_background", PROP_TYPE_BOOL,offsetof(Ngon, show_background) },
+ { "pattern", PROP_TYPE_PATTERN, offsetof(Ngon, pattern) },
+ { "name", PROP_TYPE_STRING, offsetof(Ngon, name) },
+ { NULL }
+};
+static void
+_ngon_get_props(Ngon *ng, GPtrArray *props)
+{
+ object_get_props_from_offsets(&ng->element.object, _ngon_offsets, props);
+}
+static void
+_ngon_set_props(Ngon *ng, GPtrArray *props)
+{
+ object_set_props_from_offsets(&ng->element.object, _ngon_offsets, props);
+ _ngon_update_data(ng);
+}
+static real
+_ngon_distance_from (Ngon *ng, Point *point)
+{
+ g_return_val_if_fail (ng->points->len >= 3, 1.0);
+ return distance_polygon_point(&g_array_index (ng->points, Point, 0), ng->points->len,
+ ng->line_width, point);
+}
+static void
+_ngon_select(Ngon *ng, Point *clicked_point, DiaRenderer *interactive_renderer)
+{
+ element_update_handles(&ng->element);
+}
+static ObjectChange*
+_ngon_move_handle (Ngon *ng, Handle *handle,
+ Point *to, ConnectionPoint *cp,
+ HandleMoveReason reason, ModifierKeys modifiers)
+{
+ Element *elem = &ng->element;
+ ObjectChange *change = NULL; /* stays NULL for fully reversible move handle */
+
+ g_return_val_if_fail (handle!=NULL, NULL);
+ g_return_val_if_fail (to!=NULL, NULL);
+
+ /* resize or moving center handle? */
+ if (handle->id == HANDLE_CUSTOM1) {
+ ng->center = *to;
+ } else {
+ /* handle is not moved yet(?), so we can use that to scale towards to */
+ real d0 = distance_point_point (&handle->pos, &ng->center);
+ real d1 = distance_point_point (to, &ng->center);
+ ng->ray_len *= (d1 / d0);
+ /* not sure if this is useful at all, but we must not do it with our center_handle */
+ change = element_move_handle(&ng->element, handle->id, to, cp, reason, modifiers);
+ }
+
+ _ngon_update_data(ng);
+
+ return change;
+}
+/*!
+ * \brief Move the object, to is relative to former object position
+ */
+static ObjectChange*
+_ngon_move(Ngon *ng, Point *to)
+{
+ ng->center = *to;
+ _ngon_update_data(ng);
+
+ return NULL;
+}
+static void
+_ngon_draw(Ngon *ng, DiaRenderer *renderer)
+{
+ DiaRendererClass *renderer_ops = DIA_RENDERER_GET_CLASS (renderer);
+ gboolean pattern_fill = ng->show_background
+ && ng->pattern != NULL
+ && renderer_ops->is_capable_to(renderer, RENDER_PATTERN);
+ Color fill;
+
+ g_return_if_fail (ng->points->len);
+
+ renderer_ops->set_linewidth(renderer, ng->line_width);
+ renderer_ops->set_linestyle(renderer, ng->line_style);
+ renderer_ops->set_linejoin(renderer, ng->line_join);
+ renderer_ops->set_dashlength(renderer, ng->dashlength);
+ renderer_ops->set_linecaps(renderer, LINECAPS_BUTT);
+ if (ng->pattern)
+ dia_pattern_get_fallback_color (ng->pattern, &fill);
+ else
+ fill = ng->fill;
+ if (pattern_fill)
+ renderer_ops->set_pattern (renderer, ng->pattern);
+ renderer_ops->draw_polygon(renderer,
+ &g_array_index (ng->points, Point, 0),
+ ng->points->len,
+ ng->show_background ? &fill : NULL,
+ &ng->stroke);
+ if (pattern_fill)
+ renderer_ops->set_pattern (renderer, NULL);
+}
+
+/* greatest common divider */
+static int
+_gcd (int a, int b)
+{
+ while (b != 0) {
+ real t = b;
+ b = a % b;
+ a = t;
+ }
+ return a;
+}
+static int
+_calc_step (int a, int b)
+{
+ while (_gcd (a, b) != 1)
+ --b;
+ return b;
+}
+
+static void
+_ngon_make_name (Ngon *ng)
+{
+ static struct {
+ int v;
+ const char *n[3];
+ } _keys[] = {
+ { 3, N_("Triangle"), },
+ { 4, N_("Square"), },
+ { 5, N_("Pentagon"), N_("Pentagram") },
+ { 6, N_("Hexagon"), N_("Hexagram") },
+ { 7, N_("Heptagon"), N_("Heptagram") },
+ { 8, N_("Octagon"), N_("Octagram") },
+ { 9, N_("Enneagon"), N_("Enneagram") },
+ { 10, N_("Decagon"), N_("Decagram") },
+ { 11, N_("Hendecagon"), N_("Hendecagram") },
+ { 12, N_("Dodecagon"), N_("Dodecagram") },
+ { 13, N_("Tridecagon"), N_("Tridecagram") },
+ { 14, N_("Tetradecagon"), N_("Tetradecagram") },
+ { 15, N_("Pentadecagon"), N_("Pentadecagram") },
+ { 16, N_("Hexadecagon"), N_("Hexadecagram") },
+ { 17, N_("Heptadecagon"), N_("Heptadecagram") },
+ { 18, N_("Octadecagon"), N_("Octadecagram") },
+ { 19, N_("Enneadecagon"), N_("Enneadecagram") },
+ { 20, N_("Icosagon"), N_("Icosagram") },
+ };
+ const char *name = NULL;
+ int i = 0;
+
+ g_free (ng->name);
+ for (i = 0; i < G_N_ELEMENTS(_keys); ++i) {
+ if (_keys[i].v == ng->num_rays) {
+ if (ng->kind == NGON_CONVEX)
+ name = _keys[i].n[0];
+ else if (ng->kind == NGON_CROSSING)
+ name = _keys[i].n[1];
+ }
+ }
+ if (!name) {
+ if (ng->kind == NGON_CONVEX)
+ name = _("N-gon");
+ else if (ng->kind == NGON_CROSSING)
+ name = _("N-gram");
+ else
+ name = _("Star");
+ }
+
+ if (ng->kind == NGON_CONVEX)
+ ng->name = g_strdup_printf ("%s {%d}", name, ng->num_rays);
+ else
+ ng->name = g_strdup_printf ("%s {%d/%d}", name, ng->num_rays,
+ _calc_step (ng->num_rays, ng->num_rays / 2));
+}
+
+/*!
+ * \brief Sort points to produce a star with crossing edges
+ *
+ * We could support the different possibilities explained by
+ * http://en.wikipedia.org/wiki/Star_polygon
+ * but first need a good user interface to select between this
+ * number of point dependent selection.
+ */
+static void
+_ngon_adjust_for_crossing (Ngon *ng)
+{
+ int n = ng->points->len, i, step = _calc_step (ng->points->len, ng->points->len / 2);
+ GArray *points = g_array_new (FALSE /* zero_terminated */,
+ FALSE /* clear_ */, sizeof(Point));
+
+ /* copy already preset points */
+ g_array_insert_vals (points, 0,
+ &g_array_index (ng->points, Point, 0),
+ ng->points->len);
+ for (i = 1; i < n; ++i) {
+ int j = (i * step) % n;
+ g_array_index (ng->points, Point, i).x = g_array_index (points, Point, j).x;
+ g_array_index (ng->points, Point, i).y = g_array_index (points, Point, j).y;
+ }
+ g_array_free (points, TRUE);
+}
+static void
+_ngon_update_data (Ngon *ng)
+{
+ Element *elem;
+ int n, i;
+ real r;
+
+ elem = &ng->element;
+ if (ng->ray_len < 0.01) /* ensure minimum size ... */
+ ng->ray_len = 0.01; /* otherwise we can't scale it anymore */
+ r = ng->ray_len;
+
+ if (ng->kind != NGON_CONCAVE)
+ n = ng->num_rays;
+ else
+ n = ng->num_rays * 2;
+
+ _ngon_make_name (ng);
+ if (1 || n != ng->points->len) {
+ /* recalculate all points */
+ Point ct = ng->center;
+ real da = 2 * M_PI / ng->num_rays;
+
+ g_array_set_size (ng->points, n);
+
+ if (ng->kind != NGON_CONCAVE) {
+ for (i = 0; i < ng->num_rays; ++i) {
+ real a = i * da;
+ g_array_index (ng->points, Point, i).x = sin(a) * r + ct.x;
+ g_array_index (ng->points, Point, i).y = -cos(a) * r + ct.y;
+ }
+ /* sort/extend points for other form */
+ if (ng->kind == NGON_CROSSING)
+ _ngon_adjust_for_crossing (ng);
+ } else {
+ da /= 2.0; /* we are doing bigger steps here */
+ for (i = 0; i < n; i+=2) {
+ real a = i * da;
+ g_array_index (ng->points, Point, i).x = sin(a) * r + ct.x;
+ g_array_index (ng->points, Point, i).y = -cos(a) * r + ct.y;
+ g_array_index (ng->points, Point, i+1).x = sin(a+da) * r * .4 + ct.x;
+ g_array_index (ng->points, Point, i+1).y = -cos(a+da) * r * .4 + ct.y;
+ }
+ }
+ }
+ /* update bounding box */
+ {
+ PolyBBExtras extra;
+ extra.start_trans = extra.end_trans = 0;
+ extra.middle_trans = ng->line_width / 2.0;
+ extra.start_long = extra.end_long = 0;
+ polyline_bbox (&g_array_index (ng->points, Point, 0),
+ ng->points->len,
+ &extra, TRUE,
+ &elem->object.bounding_box);
+ }
+ elem->object.position = ng->center;
+ ng->center_handle.pos = ng->center;
+ ng->connections[NUM_CONNECTIONS-1].pos = ng->center;
+ /* update element members based on circumscribed circle */
+ elem->corner.x = ng->center.x - ng->ray_len;
+ elem->corner.y = ng->center.y - ng->ray_len;
+ elem->width = elem->height = 2 * ng->ray_len;
+ element_update_handles(elem);
+
+}
+static void
+_ngon_destroy(Ngon *ng)
+{
+ g_array_free (ng->points, TRUE);
+ if (ng->pattern)
+ g_object_unref (ng->pattern);
+ g_free (ng->name);
+ element_destroy(&ng->element);
+}
+static DiaObject *
+_ngon_copy(Ngon *from)
+{
+ DiaObject *newobj = object_copy_using_properties (&from->element.object);
+ Ngon *ng = (Ngon *)newobj;
+ int i;
+ /* setup our extra handle */
+ newobj->handles[NUM_HANDLES-1] = &ng->center_handle;
+ /* and connections */
+ for (i=0; i<NUM_CONNECTIONS; i++) {
+ newobj->connections[i] = &ng->connections[i];
+ ng->connections[i].object = newobj;
+ ng->connections[i].connected = NULL;
+ }
+ ng->connections[NUM_CONNECTIONS-1].flags = CP_FLAGS_MAIN;
+
+ return newobj;
+}
+
+static ObjectOps _ngon_ops = {
+ (DestroyFunc) _ngon_destroy,
+ (DrawFunc) _ngon_draw,
+ (DistanceFunc) _ngon_distance_from,
+ (SelectFunc) _ngon_select,
+ (CopyFunc) _ngon_copy,
+ (MoveFunc) _ngon_move,
+ (MoveHandleFunc) _ngon_move_handle,
+ (GetPropertiesFunc) object_create_props_dialog,
+ (ApplyPropertiesDialogFunc) object_apply_props_from_dialog,
+ (ObjectMenuFunc) NULL,
+ (DescribePropsFunc) _ngon_describe_props,
+ (GetPropsFunc) _ngon_get_props,
+ (SetPropsFunc) _ngon_set_props,
+ (TextEditFunc) 0,
+ (ApplyPropertiesListFunc) object_apply_props,
+};
+
+DiaObjectType _ngon_type =
+{
+ "Misc - Ngon", /* name */
+ 0, /* version */
+ n_gon_xpm, /* pixmap */
+ &_ngon_type_ops, /* ops */
+ NULL, /* pixmap_file */
+ 0 /* default_uder_data */
+};
+
+/*! factory function */
+static DiaObject *
+_ngon_create (Point *startpoint,
+ void *user_data,
+ Handle **handle1,
+ Handle **handle2)
+{
+ /* XXX: think about user_data handling for alias e.g. of some Assorted */
+ Ngon *ng;
+ Element *elem;
+ DiaObject *obj;
+ int i;
+
+ ng = g_new0 (Ngon, 1);
+ obj = &ng->element.object;
+ obj->type = &_ngon_type;
+ obj->ops = &_ngon_ops;
+ elem = &ng->element;
+
+ element_init (elem, NUM_HANDLES, NUM_CONNECTIONS);
+ obj->handles[NUM_HANDLES-1] = &ng->center_handle;
+ obj->handles[NUM_HANDLES-1]->id = HANDLE_CUSTOM1;
+ obj->handles[NUM_HANDLES-1]->type = HANDLE_MAJOR_CONTROL;
+ obj->handles[NUM_HANDLES-1]->connected_to = NULL;
+ obj->handles[NUM_HANDLES-1]->connect_type = HANDLE_NONCONNECTABLE;
+
+ for (i=0; i<NUM_CONNECTIONS; i++) {
+ obj->connections[i] = &ng->connections[i];
+ ng->connections[i].object = obj;
+ ng->connections[i].connected = NULL;
+ }
+ ng->connections[NUM_CONNECTIONS-1].flags = CP_FLAGS_MAIN;
+
+ ng->points = g_array_new (FALSE /* zero_terminated */,
+ FALSE /* clear_ */, sizeof(Point));
+ ng->kind = NGON_CONVEX;
+ ng->num_rays = 5;
+ ng->ray_len = 1.0; /* for intial object size */
+ ng->center = *startpoint;
+
+ ng->line_width = attributes_get_default_linewidth();
+ ng->stroke = attributes_get_foreground();
+ ng->fill = attributes_get_background();
+ attributes_get_default_line_style(&ng->line_style, &ng->dashlength);
+
+ _ngon_update_data(ng);
+
+ *handle1 = obj->handles[NUM_HANDLES-1]; /* center point */
+ *handle2 = obj->handles[NUM_HANDLES-2]; /* lower right corner */
+ return &ng->element.object;
+}
+
+static DiaObject *
+_ngon_load (ObjectNode obj_node, int version, DiaContext *ctx)
+{
+ DiaObject *obj;
+ Ngon *ng;
+
+ obj = object_load_using_properties (&_ngon_type, obj_node, version, ctx);
+ /* XXX: do some sanity check? */
+ return obj;
+}
+
+static void
+_ngon_save (DiaObject *obj, ObjectNode obj_node, DiaContext *ctx)
+{
+ object_save_using_properties (obj, obj_node, ctx);
+}
diff --git a/objects/Misc/pixmaps/n_gon.xpm b/objects/Misc/pixmaps/n_gon.xpm
new file mode 100644
index 0000000..3d6b1ad
--- /dev/null
+++ b/objects/Misc/pixmaps/n_gon.xpm
@@ -0,0 +1,84 @@
+/* XPM */
+static char * n_gon_xpm[] = {
+"22 22 60 1",
+" c None",
+"+ c #000000",
+"@ c #6B6B6B",
+"# c #747474",
+"$ c #929292",
+"% c #BCBCBC",
+"& c #E3E3E3",
+"* c #EBEBEB",
+"= c #FFFFFF",
+"- c #222222",
+"; c #393939",
+"> c #ABABAB",
+", c #D1D1D1",
+"' c #EAEAEA",
+") c #121212",
+"! c #151515",
+"~ c #141414",
+"{ c #2F2F2F",
+"] c #080808",
+"^ c #F6F6F6",
+"/ c #3A3A3A",
+"( c #8C8C8C",
+"_ c #FEFEFE",
+": c #EFEFEF",
+"< c #070707",
+"[ c #B1B1B1",
+"} c #C9C9C9",
+"| c #555555",
+"1 c #9D9D9D",
+"2 c #1E1E1E",
+"3 c #777777",
+"4 c #0A0A0A",
+"5 c #0D0D0D",
+"6 c #333333",
+"7 c #727272",
+"8 c #0E0E0E",
+"9 c #D8D8D8",
+"0 c #040404",
+"a c #C8C8C8",
+"b c #292929",
+"c c #3C3C3C",
+"d c #FAFAFA",
+"e c #464646",
+"f c #5B5B5B",
+"g c #626262",
+"h c #919191",
+"i c #0C0C0C",
+"j c #959595",
+"k c #CCCCCC",
+"l c #E9E9E9",
+"m c #F7F7F7",
+"n c #363636",
+"o c #272727",
+"p c #474747",
+"q c #ECECEC",
+"r c #9B9B9B",
+"s c #7C7C7C",
+"t c #111111",
+"u c #1A1A1A",
+" + ",
+" ++ ",
+" +@ ",
+" #$ ",
+" +%&+ ",
+" +*=- ",
+" ;==> ",
+" ,=='+ ",
+"+++++++++)!!~+++++++++",
+" +{=====] ]^====/+ ",
+" +(=_:< [==}) ",
+" +|=1+ +2=3+ ",
+" 45+ +4+ ",
+" +6+ +7+ ",
+" 8=90 +a=b ",
+" c=_de2&__f+ ",
+" +g_=hi+j==k+ ",
+" +lmn+ ++l=o ",
+" pq++ +rs ",
+" t< +u+ ",
+" ++ ++ ",
+" "};
diff --git a/objects/makefile.msc b/objects/makefile.msc
index 6238aab..0ac96bf 100644
--- a/objects/makefile.msc
+++ b/objects/makefile.msc
@@ -205,6 +205,7 @@ OBJECTS = \
analog_clock.obj \
grid_object.obj \
measure.obj \
+ n_gon.obj \
tree.obj \
diagram_as_object.obj \
libmisc.obj
diff --git a/sheets/Misc.sheet.in b/sheets/Misc.sheet.in
index 92485cb..0ff656e 100644
--- a/sheets/Misc.sheet.in
+++ b/sheets/Misc.sheet.in
@@ -30,6 +30,9 @@
<object name="Misc - Diagram">
<_description>Diagram object</_description>
</object>
+ <object name="Misc - Ngon">
+ <_description>N-gon or Star object</_description>
+ </object>
</contents>
</sheet>
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]