231 lines
6.2 KiB
C
231 lines
6.2 KiB
C
/*****************************************************************************/
|
|
/* LibreDWG - free implementation of the DWG file format */
|
|
/* */
|
|
/* Copyright (C) 2009, 2023 Free Software Foundation, Inc. */
|
|
/* Copyright (C) 2010 Thien-Thi Nguyen */
|
|
/* */
|
|
/* This library is free software, licensed under the terms of the GNU */
|
|
/* General Public License as published by the Free Software Foundation, */
|
|
/* either version 3 of the License, or (at your option) any later version. */
|
|
/* You should have received a copy of the GNU General Public License */
|
|
/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
|
/*****************************************************************************/
|
|
|
|
/*
|
|
* load_dwg.c: load a DWG, get lines, text and circles
|
|
* written by Felipe Castro
|
|
* modified by Felipe Corrêa da Silva Sances
|
|
* modified by Thien-Thi Nguyen
|
|
* modified by Reini Urban
|
|
*/
|
|
|
|
#include "config.h"
|
|
#ifdef __STDC_ALLOC_LIB__ /* for strdup */
|
|
# define __STDC_WANT_LIB_EXT2__ 1 /* for strdup */
|
|
#else
|
|
# define _USE_BSD 1
|
|
#endif
|
|
#ifndef _XOPEN_SOURCE /* for strdup, snprintf */
|
|
# define _XOPEN_SOURCE 700
|
|
#endif
|
|
|
|
#include <stdio.h>
|
|
#include <time.h>
|
|
#ifndef DISABLE_WRITE
|
|
# include <sys/stat.h>
|
|
# include <unistd.h>
|
|
#endif
|
|
#include "dwg.h"
|
|
#include "dwg_api.h"
|
|
#include "../src/bits.h"
|
|
|
|
#include "../programs/suffix.inc"
|
|
static int help (void);
|
|
int verbosity (int argc, char **argv, int i, unsigned int *opts);
|
|
#include "../programs/common.inc"
|
|
|
|
static int
|
|
usage (void)
|
|
{
|
|
printf ("\nUsage: load_dwg [-v[0-9]] DWGFILE\n");
|
|
return 1;
|
|
}
|
|
static int
|
|
opt_version (void)
|
|
{
|
|
printf ("load_dwg %s\n", PACKAGE_VERSION);
|
|
return 0;
|
|
}
|
|
static int
|
|
help (void)
|
|
{
|
|
printf ("\nUsage: load_dwg [OPTION]... DWGFILE\n");
|
|
printf ("Example to add fingerprint elements to a DWG.\n"
|
|
"\n");
|
|
printf (" -v[0-9], --verbose [0-9] verbosity\n");
|
|
printf (" --help display this help and exit\n");
|
|
printf (" --version output version information and exit\n"
|
|
"\n");
|
|
printf ("GNU LibreDWG online manual: "
|
|
"<https://www.gnu.org/software/libredwg/>\n");
|
|
return 0;
|
|
}
|
|
|
|
static int
|
|
add_fingerprint (Dwg_Data *dwg, dwg_point_3d *pt)
|
|
{
|
|
int error = 0;
|
|
char text[128];
|
|
double height = dwg->header_vars.TEXTSIZE;
|
|
time_t t = time (NULL);
|
|
Dwg_Object_BLOCK_HEADER *hdr = dwg_get_block_header (dwg, &error);
|
|
Dwg_Entity_TEXT *ent;
|
|
if (error)
|
|
return 1;
|
|
|
|
#ifdef HAVE_WFORMAT_Y2K
|
|
GCC46_DIAG_IGNORE (-Wformat-y2k)
|
|
#endif
|
|
strftime (text, sizeof (text), "Last updated: %c", localtime (&t));
|
|
#ifdef HAVE_WFORMAT_Y2K
|
|
GCC46_DIAG_RESTORE
|
|
#endif
|
|
|
|
#ifdef USE_WRITE
|
|
if ((ent = dwg_add_TEXT (hdr, text, pt, height)))
|
|
{
|
|
ent->horiz_alignment = HORIZ_ALIGNMENT_RIGHT;
|
|
return 0;
|
|
}
|
|
else
|
|
#endif
|
|
return 1;
|
|
}
|
|
|
|
static int
|
|
change_fingerprint (Dwg_Data *dwg, Dwg_Entity_TEXT *_obj)
|
|
{
|
|
char text[128];
|
|
double height = dwg->header_vars.TEXTSIZE;
|
|
time_t t = time (NULL);
|
|
|
|
#ifdef HAVE_WFORMAT_Y2K
|
|
GCC46_DIAG_IGNORE (-Wformat-y2k)
|
|
#endif
|
|
strftime (text, sizeof (text), "Last updated: %c", localtime (&t));
|
|
#ifdef HAVE_WFORMAT_Y2K
|
|
GCC46_DIAG_RESTORE
|
|
#endif
|
|
|
|
if (dwg->header.version < R_2007)
|
|
{
|
|
if (strlen (text) < strlen (_obj->text_value))
|
|
strcpy (_obj->text_value, text);
|
|
else
|
|
{
|
|
free (_obj->text_value);
|
|
_obj->text_value = strdup (text);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
free (_obj->text_value);
|
|
_obj->text_value = (BITCODE_TV)bit_utf8_to_TU (text, 0);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
static int
|
|
load_dwg (char *filename, unsigned int opts)
|
|
{
|
|
BITCODE_BL i;
|
|
int success, found = 0;
|
|
Dwg_Data dwg;
|
|
dwg_point_3d pt;
|
|
|
|
#ifdef USE_WRITE
|
|
char *new_filename = (char *)malloc (strlen (filename) + 4);
|
|
char *fn = strdup (filename);
|
|
char *base = basename (fn);
|
|
char *p;
|
|
struct stat st;
|
|
|
|
if ((p = strrchr (base, '.')))
|
|
*p = '\0';
|
|
sprintf (new_filename, "%s_new.dwg", base);
|
|
free (fn);
|
|
#endif
|
|
|
|
memset (&dwg, 0, sizeof (Dwg_Data));
|
|
dwg.opts = opts;
|
|
success = dwg_read_file (filename, &dwg);
|
|
// get the insertion point for our fingerprint
|
|
pt.x = dwg.header_vars.LIMMAX.x;
|
|
pt.y = dwg.header_vars.LIMMAX.y;
|
|
pt.z = 0.0;
|
|
|
|
// check if a fingerprint already exists there.
|
|
// if so update it. if not add it
|
|
for (i = 0; i < dwg.num_objects; i++)
|
|
{
|
|
if (dwg.object[i].fixedtype == DWG_TYPE_TEXT)
|
|
{
|
|
Dwg_Entity_TEXT *_obj = dwg.object[i].tio.entity->tio.TEXT;
|
|
if (pt.x == _obj->ins_pt.x && pt.y == _obj->ins_pt.y
|
|
&& _obj->horiz_alignment == HORIZ_ALIGNMENT_RIGHT)
|
|
{
|
|
found++;
|
|
change_fingerprint (&dwg, _obj);
|
|
fprintf (stderr, "fingerprint updated at (%f, %f)\n", pt.x,
|
|
pt.y);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!found)
|
|
{
|
|
add_fingerprint (&dwg, &pt);
|
|
fprintf (stderr, "fingerprint added at (%f, %f)\n", pt.x, pt.y);
|
|
}
|
|
|
|
#ifdef USE_WRITE
|
|
if (0 == stat (new_filename, &st))
|
|
unlink (new_filename);
|
|
if (dwg.header.version > R_2000)
|
|
dwg.header.version = R_2000;
|
|
success = dwg_write_file (new_filename, &dwg);
|
|
free (new_filename);
|
|
#endif
|
|
|
|
dwg_free (&dwg);
|
|
return success;
|
|
}
|
|
|
|
int
|
|
main (int argc, char *argv[])
|
|
{
|
|
int i = 1;
|
|
unsigned int opts = 0;
|
|
|
|
if (argc < 2)
|
|
return usage ();
|
|
#if defined(USE_TRACING) && defined(HAVE_SETENV)
|
|
setenv ("LIBREDWG_TRACE", "1", 0);
|
|
#endif
|
|
if (argc > 2
|
|
&& (!strcmp (argv[i], "--verbose") || !strncmp (argv[i], "-v", 2)))
|
|
{
|
|
int num_args = verbosity (argc, argv, i, &opts);
|
|
argc -= num_args;
|
|
i += num_args;
|
|
}
|
|
if (argc > 1 && !strcmp (argv[i], "--help"))
|
|
return help ();
|
|
if (argc > 1 && !strcmp (argv[i], "--version"))
|
|
return opt_version ();
|
|
|
|
REQUIRE_INPUT_FILE_ARG (argc);
|
|
load_dwg (argv[i], opts);
|
|
return 0;
|
|
}
|