(root)/
libredwg-0.13/
src/
in_dxf.h
       1  /*****************************************************************************/
       2  /*  LibreDWG - free implementation of the DWG file format                    */
       3  /*                                                                           */
       4  /*  Copyright (C) 2018-2020 Free Software Foundation, Inc.                   */
       5  /*                                                                           */
       6  /*  This library is free software, licensed under the terms of the GNU       */
       7  /*  General Public License as published by the Free Software Foundation,     */
       8  /*  either version 3 of the License, or (at your option) any later version.  */
       9  /*  You should have received a copy of the GNU General Public License        */
      10  /*  along with this program.  If not, see <http://www.gnu.org/licenses/>.    */
      11  /*****************************************************************************/
      12  
      13  /*
      14   * in_dxf.h: read ASCII DXF to dwg
      15   * written by Reini Urban
      16   */
      17  
      18  #ifndef IN_DXF_H
      19  #define IN_DXF_H
      20  
      21  #include "dwg.h"
      22  #include "bits.h"
      23  #include "decode.h"
      24  #include "dynapi.h"
      25  
      26  // from dwg_api
      27  #ifndef _DWG_API_H_
      28  BITCODE_T dwg_add_u8_input (Dwg_Data *restrict dwg,
      29                              const char *restrict u8str) __nonnull_all;
      30  #endif
      31  
      32  EXPORT int dwg_read_dxf (Bit_Chain *restrict dat,
      33                           Dwg_Data *restrict dwg) __nonnull_all;
      34  EXPORT int dwg_read_dxfb (Bit_Chain *restrict dat,
      35                            Dwg_Data *restrict dwg) __nonnull_all;
      36  
      37  // global array of [obj -> [fields], ...]
      38  typedef struct _dxf_field
      39  {
      40    char *name;
      41    char *type;
      42    int dxf;
      43  } Dxf_Field;
      44  
      45  // to search obj ptr in array
      46  /*
      47  typedef struct _dxf_objs
      48  {
      49    Dwg_Object *obj;
      50    int num_fields;
      51    int size_fields;
      52    Dxf_Field *fields;
      53  } Dxf_Objs;
      54  */
      55  
      56  typedef struct _dxf_pair
      57  {
      58    short code;
      59    enum RESBUF_VALUE_TYPE type;
      60    union // must be big enough for setting BD
      61    {
      62      unsigned int u;
      63      int i;
      64      char *s;
      65      long l;
      66      uint64_t rll;
      67      double d;
      68    } value;
      69  } Dxf_Pair;
      70  
      71  /* We need to postpone the HEADER handles from names,
      72     when we didn't read the TABLES yet, which sets the handle values.
      73     Also for EED appid handles, and some object names => handle.
      74     Store all handle fieldnames and string values into this array,
      75     which is prefixed with the number of stored items.
      76   */
      77  struct array_hdl
      78  {
      79    char *field;
      80    char *name;
      81    int code; // or objid
      82  };
      83  typedef struct _array_hdls
      84  {
      85    uint32_t nitems;
      86    uint32_t size;            // in chunks of 16
      87    struct array_hdl items[]; // Flexible array grows
      88  } array_hdls;
      89  
      90  array_hdls *array_push (array_hdls *restrict hdls, const char *restrict field,
      91                          const char *restrict name, const int code);
      92  array_hdls *new_array_hdls (uint32_t size);
      93  void free_array_hdls (array_hdls *hdls);
      94  
      95  void dxf_add_field (Dwg_Object *restrict obj, const char *restrict name,
      96                      const char *restrict type, int dxf);
      97  Dxf_Field *dxf_search_field (Dwg_Object *restrict obj,
      98                               const char *restrict name,
      99                               const char *restrict type, int dxf);
     100  const Dwg_DYNAPI_field *find_numfield (const Dwg_DYNAPI_field *restrict fields,
     101                                         const char *restrict key);
     102  BITCODE_H find_tablehandle (Dwg_Data *restrict dwg, Dxf_Pair *restrict pair);
     103  int is_table_name (const char *restrict name) __nonnull_all;
     104  int is_textlike (Dwg_Object *restrict obj) __nonnull_all;
     105  
     106  BITCODE_RC dxf_find_lweight (const int lw);
     107  
     108  // for sscanf with BD we need to use %lf not %g
     109  #undef FORMAT_BD
     110  #define FORMAT_BD "%lf"
     111  
     112  #define DWG_OBJECT(token)
     113  #define DWG_ENTITY(token)
     114  
     115  #define NEW_OBJECT(dwg, obj)                                                  \
     116    {                                                                           \
     117      BITCODE_BL idx = dwg->num_objects;                                        \
     118      (void)dwg_add_object (dwg);                                               \
     119      obj = &dwg->object[idx];                                                  \
     120      obj->supertype = DWG_SUPERTYPE_OBJECT;                                    \
     121      obj->tio.object                                                           \
     122          = (Dwg_Object_Object *)calloc (1, sizeof (Dwg_Object_Object));        \
     123      obj->tio.object->objid = obj->index;                                      \
     124      obj->tio.object->dwg = dwg;                                               \
     125    }
     126  
     127  #define NEW_ENTITY(dwg, obj)                                                  \
     128    {                                                                           \
     129      BITCODE_BL idx = dwg->num_objects;                                        \
     130      (void)dwg_add_object (dwg);                                               \
     131      obj = &dwg->object[idx];                                                  \
     132      obj->supertype = DWG_SUPERTYPE_ENTITY;                                    \
     133      obj->tio.entity                                                           \
     134          = (Dwg_Object_Entity *)calloc (1, sizeof (Dwg_Object_Entity));        \
     135      obj->tio.entity->objid = obj->index;                                      \
     136      obj->tio.entity->dwg = dwg;                                               \
     137    }
     138  
     139  #ifndef __cplusplus
     140  
     141  #  define ADD_OBJECT(token)                                                   \
     142      obj->type = obj->fixedtype = DWG_TYPE_##token;                            \
     143      obj->name = (char *)#token;                                               \
     144      obj->dxfname = dxfname;                                                   \
     145      if (obj->type >= DWG_TYPE_GROUP)                                          \
     146        (void)dwg_encode_get_class (obj->parent, obj);                          \
     147      LOG_TRACE ("  ADD_OBJECT %s [%d]\n", obj->name, obj->index)               \
     148      _obj = calloc (1, sizeof (Dwg_Object_##token));                           \
     149      obj->tio.object->tio.token = (Dwg_Object_##token *)_obj;                  \
     150      obj->tio.object->tio.token->parent = obj->tio.object;                     \
     151      obj->tio.object->objid = obj->index
     152  
     153  #  define ADD_OBJECT1(token, tgt) ADD_OBJECT (token)
     154  
     155  #  define ADD_ENTITY(token)                                                   \
     156      obj->type = obj->fixedtype = DWG_TYPE_##token;                            \
     157      if (strlen (#token) > 3 && !memcmp (#token, "_3D", 3))                    \
     158        obj->name = (char *)&#token[1];                                         \
     159      else                                                                      \
     160        obj->name = (char *)#token;                                             \
     161      obj->dxfname = dxfname;                                                   \
     162      if (obj->type >= DWG_TYPE_GROUP)                                          \
     163        (void)dwg_encode_get_class (obj->parent, obj);                          \
     164      LOG_TRACE ("  ADD_ENTITY %s [%d]\n", obj->name, obj->index)               \
     165      GCC14_DIAG_IGNORE (-Wanalyzer-allocation-size)                          \
     166      _obj = calloc (1, sizeof (Dwg_Entity_##token));                           \
     167      GCC14_DIAG_RESTORE                                                        \
     168      obj->tio.entity->tio.token = (Dwg_Entity_##token *)_obj;                  \
     169      obj->tio.entity->tio.token->parent = obj->tio.entity;                     \
     170      obj->tio.entity->objid = obj->index
     171  
     172  #else // __cplusplus
     173  
     174  #  define ADD_OBJECT(token)                                                   \
     175      obj->type = obj->fixedtype = DWG_TYPE_##token;                            \
     176      obj->name = (char *)#token;                                               \
     177      obj->dxfname = dxfname;                                                   \
     178      if (obj->type >= DWG_TYPE_GROUP)                                          \
     179        (void)dwg_encode_get_class (obj->parent, obj);                          \
     180      LOG_TRACE ("  ADD_OBJECT %s [%d]\n", obj->name, obj->index)               \
     181      _obj = reinterpret_cast<Dwg_Object_APPID *> (                             \
     182          calloc (1, sizeof (Dwg_Object_##token)));                             \
     183      obj->tio.object->tio.token = (Dwg_Object_##token *)_obj;                  \
     184      obj->tio.object->tio.token->parent = obj->tio.object;                     \
     185      obj->tio.object->objid = obj->index
     186  
     187  #  define ADD_OBJECT1(token, tgt)                                             \
     188      obj->type = obj->fixedtype = DWG_TYPE_##token;                            \
     189      obj->name = (char *)#token;                                               \
     190      obj->dxfname = dxfname;                                                   \
     191      if (obj->type >= DWG_TYPE_GROUP)                                          \
     192        (void)dwg_encode_get_class (obj->parent, obj);                          \
     193      LOG_TRACE ("  ADD_OBJECT %s [%d]\n", obj->name, obj->index)               \
     194      _obj = reinterpret_cast<Dwg_Object_##tgt *> (                             \
     195          calloc (1, sizeof (Dwg_Object_##token)));                             \
     196      obj->tio.object->tio.token = (Dwg_Object_##token *)_obj;                  \
     197      obj->tio.object->tio.token->parent = obj->tio.object;                     \
     198      obj->tio.object->objid = obj->index
     199  
     200  #  define ADD_ENTITY(token)                                                   \
     201      obj->type = obj->fixedtype = DWG_TYPE_##token;                            \
     202      if (strlen (#token) > 3 && !memcmp (#token, "_3D", 3))                    \
     203        obj->name = (char *)&#token[1];                                         \
     204      else                                                                      \
     205        obj->name = (char *)#token;                                             \
     206      obj->dxfname = dxfname;                                                   \
     207      if (obj->type >= DWG_TYPE_GROUP)                                          \
     208        (void)dwg_encode_get_class (obj->parent, obj);                          \
     209      LOG_TRACE ("  ADD_ENTITY %s [%d]\n", obj->name, obj->index)               \
     210      _obj = reinterpret_cast<Dwg_Object_APPID *> (                             \
     211          (char *)calloc (1, sizeof (Dwg_Entity_##token)));                     \
     212      obj->tio.entity->tio.token = (Dwg_Entity_##token *)_obj;                  \
     213      obj->tio.entity->tio.token->parent = obj->tio.entity;                     \
     214      obj->tio.entity->objid = obj->index
     215  
     216  #endif // __cplusplus
     217  
     218  #define ADD_TABLE_IF(nam, token)                                              \
     219    if (strEQc (name, #nam))                                                    \
     220      {                                                                         \
     221        ADD_OBJECT (token);                                                     \
     222      }
     223  #define ADD_TABLE_IF1(nam, token)                                             \
     224    if (strEQc (name, #nam))                                                    \
     225      {                                                                         \
     226        ADD_OBJECT1 (token, LTYPE_CONTROL);                                     \
     227      }
     228  
     229  #define STRADD_TV(field, string)                                              \
     230    if (string)                                                                 \
     231      {                                                                         \
     232        field = (char *)malloc (strlen (string) + 1);                           \
     233        strcpy (field, string);                                                 \
     234      }
     235  #define STRADD_T(field, string)                                               \
     236    if (string)                                                                 \
     237      {                                                                         \
     238        field = dwg_add_u8_input (dwg, string);                                 \
     239      }
     240  
     241  #ifndef __cplusplus
     242  
     243  #  define UPGRADE_ENTITY(FROM, TO)                                            \
     244      obj->type = obj->fixedtype = DWG_TYPE_##TO;                               \
     245      obj->name = (char *)#TO;                                                  \
     246      free (obj->dxfname);                                                      \
     247      obj->dxfname = strdup (obj->name);                                        \
     248      strcpy (name, obj->name);                                                 \
     249      LOG_TRACE ("change type to %s\n", name);                                  \
     250      if (sizeof (Dwg_Entity_##TO) > sizeof (Dwg_Entity_##FROM))                \
     251        {                                                                       \
     252          LOG_TRACE ("realloc to %s\n", name);                                  \
     253          _obj = realloc (_obj, sizeof (Dwg_Entity_##TO));                      \
     254          obj->tio.entity->tio.TO = (Dwg_Entity_##TO *)_obj;                    \
     255        }
     256  
     257  #else
     258  
     259  #  define UPGRADE_ENTITY(FROM, TO)                                            \
     260      obj->type = obj->fixedtype = DWG_TYPE_##TO;                               \
     261      obj->name = (char *)#TO;                                                  \
     262      free (obj->dxfname);                                                      \
     263      obj->dxfname = strdup (obj->name);                                        \
     264      strcpy (name, obj->name);                                                 \
     265      LOG_TRACE ("change type to %s\n", name);                                  \
     266      if (sizeof (Dwg_Entity_##TO) > sizeof (Dwg_Entity_##FROM))                \
     267        {                                                                       \
     268          LOG_TRACE ("realloc to %s\n", name);                                  \
     269          _obj = reinterpret_cast<Dwg_Object_APPID *> (                         \
     270              (char *)realloc (_obj, sizeof (Dwg_Entity_##TO)));                \
     271          obj->tio.entity->tio.TO = (Dwg_Entity_##TO *)_obj;                    \
     272        }
     273  
     274  #endif // cplusplus
     275  
     276  #endif