(root)/
libredwg-0.13/
examples/
load_dwg.c
       1  /*****************************************************************************/
       2  /*  LibreDWG - free implementation of the DWG file format                    */
       3  /*                                                                           */
       4  /*  Copyright (C) 2009, 2023 Free Software Foundation, Inc.                  */
       5  /*  Copyright (C) 2010 Thien-Thi Nguyen                                      */
       6  /*                                                                           */
       7  /*  This library is free software, licensed under the terms of the GNU       */
       8  /*  General Public License as published by the Free Software Foundation,     */
       9  /*  either version 3 of the License, or (at your option) any later version.  */
      10  /*  You should have received a copy of the GNU General Public License        */
      11  /*  along with this program.  If not, see <http://www.gnu.org/licenses/>.    */
      12  /*****************************************************************************/
      13  
      14  /*
      15   * load_dwg.c: load a DWG, get lines, text and circles
      16   * written by Felipe Castro
      17   * modified by Felipe CorrĂȘa da Silva Sances
      18   * modified by Thien-Thi Nguyen
      19   * modified by Reini Urban
      20   */
      21  
      22  #include "config.h"
      23  #ifdef __STDC_ALLOC_LIB__          /* for strdup */
      24  #  define __STDC_WANT_LIB_EXT2__ 1 /* for strdup */
      25  #else
      26  #  define _USE_BSD 1
      27  #endif
      28  #ifndef _XOPEN_SOURCE /* for strdup, snprintf */
      29  #  define _XOPEN_SOURCE 700
      30  #endif
      31  
      32  #include <stdio.h>
      33  #include <time.h>
      34  #ifndef DISABLE_WRITE
      35  #  include <sys/stat.h>
      36  #  include <unistd.h>
      37  #endif
      38  #include "dwg.h"
      39  #include "dwg_api.h"
      40  #include "../src/bits.h"
      41  
      42  #include "../programs/suffix.inc"
      43  static int help (void);
      44  int verbosity (int argc, char **argv, int i, unsigned int *opts);
      45  #include "../programs/common.inc"
      46  
      47  static int
      48  usage (void)
      49  {
      50    printf ("\nUsage: load_dwg [-v[0-9]] DWGFILE\n");
      51    return 1;
      52  }
      53  static int
      54  opt_version (void)
      55  {
      56    printf ("load_dwg %s\n", PACKAGE_VERSION);
      57    return 0;
      58  }
      59  static int
      60  help (void)
      61  {
      62    printf ("\nUsage: load_dwg [OPTION]... DWGFILE\n");
      63    printf ("Example to add fingerprint elements to a DWG.\n"
      64            "\n");
      65    printf ("  -v[0-9], --verbose [0-9]  verbosity\n");
      66    printf ("           --help           display this help and exit\n");
      67    printf ("           --version        output version information and exit\n"
      68            "\n");
      69    printf ("GNU LibreDWG online manual: "
      70            "<https://www.gnu.org/software/libredwg/>\n");
      71    return 0;
      72  }
      73  
      74  static int
      75  add_fingerprint (Dwg_Data *dwg, dwg_point_3d *pt)
      76  {
      77    int error = 0;
      78    char text[128];
      79    double height = dwg->header_vars.TEXTSIZE;
      80    time_t t = time (NULL);
      81    Dwg_Object_BLOCK_HEADER *hdr = dwg_get_block_header (dwg, &error);
      82    Dwg_Entity_TEXT *ent;
      83    if (error)
      84      return 1;
      85  
      86  #ifdef HAVE_WFORMAT_Y2K
      87    GCC46_DIAG_IGNORE (-Wformat-y2k)
      88  #endif
      89    strftime (text, sizeof (text), "Last updated: %c", localtime (&t));
      90  #ifdef HAVE_WFORMAT_Y2K
      91    GCC46_DIAG_RESTORE
      92  #endif
      93  
      94  #ifdef USE_WRITE
      95    if ((ent = dwg_add_TEXT (hdr, text, pt, height)))
      96      {
      97        ent->horiz_alignment = HORIZ_ALIGNMENT_RIGHT;
      98        return 0;
      99      }
     100    else
     101  #endif
     102      return 1;
     103  }
     104  
     105  static int
     106  change_fingerprint (Dwg_Data *dwg, Dwg_Entity_TEXT *_obj)
     107  {
     108    char text[128];
     109    double height = dwg->header_vars.TEXTSIZE;
     110    time_t t = time (NULL);
     111  
     112  #ifdef HAVE_WFORMAT_Y2K
     113    GCC46_DIAG_IGNORE (-Wformat-y2k)
     114  #endif
     115    strftime (text, sizeof (text), "Last updated: %c", localtime (&t));
     116  #ifdef HAVE_WFORMAT_Y2K
     117    GCC46_DIAG_RESTORE
     118  #endif
     119  
     120    if (dwg->header.version < R_2007)
     121      {
     122        if (strlen (text) < strlen (_obj->text_value))
     123          strcpy (_obj->text_value, text);
     124        else
     125          {
     126            free (_obj->text_value);
     127            _obj->text_value = strdup (text);
     128          }
     129      }
     130    else
     131      {
     132        free (_obj->text_value);
     133        _obj->text_value = (BITCODE_TV)bit_utf8_to_TU (text, 0);
     134      }
     135    return 0;
     136  }
     137  
     138  static int
     139  load_dwg (char *filename, unsigned int opts)
     140  {
     141    BITCODE_BL i;
     142    int success, found = 0;
     143    Dwg_Data dwg;
     144    dwg_point_3d pt;
     145  
     146  #ifdef USE_WRITE
     147    char *new_filename = (char *)malloc (strlen (filename) + 4);
     148    char *fn = strdup (filename);
     149    char *base = basename (fn);
     150    char *p;
     151    struct stat st;
     152  
     153    if ((p = strrchr (base, '.')))
     154      *p = '\0';
     155    sprintf (new_filename, "%s_new.dwg", base);
     156    free (fn);
     157  #endif
     158  
     159    memset (&dwg, 0, sizeof (Dwg_Data));
     160    dwg.opts = opts;
     161    success = dwg_read_file (filename, &dwg);
     162    // get the insertion point for our fingerprint
     163    pt.x = dwg.header_vars.LIMMAX.x;
     164    pt.y = dwg.header_vars.LIMMAX.y;
     165    pt.z = 0.0;
     166  
     167    // check if a fingerprint already exists there.
     168    // if so update it. if not add it
     169    for (i = 0; i < dwg.num_objects; i++)
     170      {
     171        if (dwg.object[i].fixedtype == DWG_TYPE_TEXT)
     172          {
     173            Dwg_Entity_TEXT *_obj = dwg.object[i].tio.entity->tio.TEXT;
     174            if (pt.x == _obj->ins_pt.x && pt.y == _obj->ins_pt.y
     175                && _obj->horiz_alignment == HORIZ_ALIGNMENT_RIGHT)
     176              {
     177                found++;
     178                change_fingerprint (&dwg, _obj);
     179                fprintf (stderr, "fingerprint updated at (%f, %f)\n", pt.x,
     180                         pt.y);
     181              }
     182          }
     183      }
     184  
     185    if (!found)
     186      {
     187        add_fingerprint (&dwg, &pt);
     188        fprintf (stderr, "fingerprint added at (%f, %f)\n", pt.x, pt.y);
     189      }
     190  
     191  #ifdef USE_WRITE
     192    if (0 == stat (new_filename, &st))
     193      unlink (new_filename);
     194    if (dwg.header.version > R_2000)
     195      dwg.header.version = R_2000;
     196    success = dwg_write_file (new_filename, &dwg);
     197    free (new_filename);
     198  #endif
     199  
     200    dwg_free (&dwg);
     201    return success;
     202  }
     203  
     204  int
     205  main (int argc, char *argv[])
     206  {
     207    int i = 1;
     208    unsigned int opts = 0;
     209  
     210    if (argc < 2)
     211      return usage ();
     212  #if defined(USE_TRACING) && defined(HAVE_SETENV)
     213    setenv ("LIBREDWG_TRACE", "1", 0);
     214  #endif
     215    if (argc > 2
     216        && (!strcmp (argv[i], "--verbose") || !strncmp (argv[i], "-v", 2)))
     217      {
     218        int num_args = verbosity (argc, argv, i, &opts);
     219        argc -= num_args;
     220        i += num_args;
     221      }
     222    if (argc > 1 && !strcmp (argv[i], "--help"))
     223      return help ();
     224    if (argc > 1 && !strcmp (argv[i], "--version"))
     225      return opt_version ();
     226  
     227    REQUIRE_INPUT_FILE_ARG (argc);
     228    load_dwg (argv[i], opts);
     229    return 0;
     230  }