[dia] Misc - Ngon: new object for regular polygon or star



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]