libDXF 0.0.1
A library with DXF related functions written in C.

text.c

Go to the documentation of this file.
00001 
00038 #include "text.h"
00039 
00040 
00052 DxfText *
00053 dxf_text_new ()
00054 {
00055 #if DEBUG
00056         DXF_DEBUG_BEGIN
00057 #endif
00058         DxfText *text = NULL;
00059         size_t size;
00060 
00061         size = sizeof (DxfText);
00062         /* avoid malloc of 0 bytes */
00063         if (size == 0) size = 1;
00064         if ((text = malloc (size)) == NULL)
00065         {
00066                 fprintf (stderr,
00067                   (_("Error in %s () could not allocate memory for a DxfText struct.\n")),
00068                   __FUNCTION__);
00069                 text = NULL;
00070         }
00071         else
00072         {
00073                 memset (text, 0, size);
00074         }
00075 #if DEBUG
00076         DXF_DEBUG_END
00077 #endif
00078         return (text);
00079 }
00080 
00081 
00094 DxfText *
00095 dxf_text_init
00096 (
00097         DxfText *text
00099 )
00100 {
00101 #if DEBUG
00102         DXF_DEBUG_BEGIN
00103 #endif
00104         /* Do some basic checks. */
00105         if (text == NULL)
00106         {
00107                 fprintf (stderr,
00108                   (_("Warning in %s () a NULL pointer was passed.\n")),
00109                   __FUNCTION__);
00110                 text = dxf_text_new ();
00111         }
00112         if (text == NULL)
00113         {
00114               fprintf (stderr,
00115                 (_("Error in %s () could not allocate memory for a DxfText struct.\n")),
00116                 __FUNCTION__);
00117               return (NULL);
00118         }
00119         text->id_code = 0;
00120         text->text_value = strdup ("");
00121         text->linetype = strdup (DXF_DEFAULT_LINETYPE);
00122         text->text_style = strdup ("");
00123         text->layer = strdup (DXF_DEFAULT_LAYER);
00124         text->x0 = 0.0;
00125         text->y0 = 0.0;
00126         text->z0 = 0.0;
00127         text->x1 = 0.0;
00128         text->y1 = 0.0;
00129         text->z1 = 0.0;
00130         text->elevation = 0.0;
00131         text->thickness = 0.0;
00132         text->linetype_scale = DXF_DEFAULT_LINETYPE_SCALE;
00133         text->height = 0.0;
00134         text->rel_x_scale = 0.0;
00135         text->rot_angle = 0.0;
00136         text->obl_angle = 0.0;
00137         text->visibility = DXF_DEFAULT_VISIBILITY;
00138         text->color = DXF_COLOR_BYLAYER;
00139         text->paperspace = DXF_MODELSPACE;
00140         text->text_flags = 0;
00141         text->hor_align = 0;
00142         text->vert_align = 0;
00143         text->extr_x0 = 0.0;
00144         text->extr_y0 = 0.0;
00145         text->extr_z0 = 0.0;
00146         text->dictionary_owner_soft = strdup ("");
00147         text->dictionary_owner_hard = strdup ("");
00148         text->next = NULL;
00149 #if DEBUG
00150         DXF_DEBUG_END
00151 #endif
00152         return (text);
00153 }
00154 
00155 
00174 DxfText *
00175 dxf_text_read
00176 (
00177         DxfFile *fp,
00179         DxfText *text
00181 )
00182 {
00183 #if DEBUG
00184         DXF_DEBUG_BEGIN
00185 #endif
00186         char *dxf_entity_name = strdup ("TEXT");
00187         char *temp_string = NULL;
00188 
00189         /* Do some basic checks. */
00190         if (fp == NULL)
00191         {
00192                 fprintf (stderr,
00193                   (_("Error in %s () a NULL file pointer was passed.\n")),
00194                   __FUNCTION__);
00195                 /* Clean up. */
00196                 free (temp_string);
00197                 return (NULL);
00198         }
00199         if (text == NULL)
00200         {
00201                 fprintf (stderr,
00202                   (_("Warning in %s () a NULL pointer was passed.\n")),
00203                   __FUNCTION__);
00204                 text = dxf_text_new ();
00205                 text = dxf_text_init (text);
00206         }
00207         (fp->line_number)++;
00208         fscanf (fp->fp, "%[^\n]", temp_string);
00209         while (strcmp (temp_string, "0") != 0)
00210         {
00211                 if (ferror (fp->fp))
00212                 {
00213                         fprintf (stderr,
00214                           (_("Error in %s () while reading from: %s in line: %d.\n")),
00215                           __FUNCTION__, fp->filename, fp->line_number);
00216                         fclose (fp->fp);
00217                         /* Clean up. */
00218                         free (temp_string);
00219                         return (NULL);
00220                 }
00221                 if (strcmp (temp_string, "1") == 0)
00222                 {
00223                         /* Now follows a string containing a text value. */
00224                         (fp->line_number)++;
00225                         fscanf (fp->fp, "%s\n", text->text_value);
00226                 }
00227                 else if (strcmp (temp_string, "5") == 0)
00228                 {
00229                         /* Now follows a string containing a sequential
00230                          * id number. */
00231                         (fp->line_number)++;
00232                         fscanf (fp->fp, "%x\n", &text->id_code);
00233                 }
00234                 else if (strcmp (temp_string, "6") == 0)
00235                 {
00236                         /* Now follows a string containing a linetype
00237                          * name. */
00238                         (fp->line_number)++;
00239                         fscanf (fp->fp, "%s\n", text->linetype);
00240                 }
00241                 else if (strcmp (temp_string, "7") == 0)
00242                 {
00243                         /* Now follows a string containing a text style
00244                          * name. */
00245                         (fp->line_number)++;
00246                         fscanf (fp->fp, "%s\n", text->text_style);
00247                 }
00248                 else if (strcmp (temp_string, "8") == 0)
00249                 {
00250                         /* Now follows a string containing a layer name. */
00251                         (fp->line_number)++;
00252                         fscanf (fp->fp, "%s\n", text->layer);
00253                 }
00254                 else if (strcmp (temp_string, "10") == 0)
00255                 {
00256                         /* Now follows a string containing the
00257                          * X-coordinate of the insertion point. */
00258                         (fp->line_number)++;
00259                         fscanf (fp->fp, "%lf\n", &text->x0);
00260                 }
00261                 else if (strcmp (temp_string, "20") == 0)
00262                 {
00263                         /* Now follows a string containing the
00264                          * Y-coordinate of the insertion point. */
00265                         (fp->line_number)++;
00266                         fscanf (fp->fp, "%lf\n", &text->y0);
00267                 }
00268                 else if (strcmp (temp_string, "30") == 0)
00269                 {
00270                         /* Now follows a string containing the
00271                          * Z-coordinate of the insertion point. */
00272                         (fp->line_number)++;
00273                         fscanf (fp->fp, "%lf\n", &text->z0);
00274                 }
00275                 else if ((fp->acad_version_number <= AutoCAD_11)
00276                         && (strcmp (temp_string, "38") == 0)
00277                         && (text->elevation != 0.0))
00278                 {
00279                         /* Now follows a string containing the
00280                          * elevation. */
00281                         (fp->line_number)++;
00282                         fscanf (fp->fp, "%lf\n", &text->elevation);
00283                 }
00284                 else if (strcmp (temp_string, "39") == 0)
00285                 {
00286                         /* Now follows a string containing the
00287                          * thickness. */
00288                         (fp->line_number)++;
00289                         fscanf (fp->fp, "%lf\n", &text->thickness);
00290                 }
00291                 else if (strcmp (temp_string, "40") == 0)
00292                 {
00293                         /* Now follows a string containing the
00294                          * height. */
00295                         (fp->line_number)++;
00296                         fscanf (fp->fp, "%lf\n", &text->height);
00297                 }
00298                 else if (strcmp (temp_string, "41") == 0)
00299                 {
00300                         /* Now follows a string containing the
00301                          * relative X-scale. */
00302                         (fp->line_number)++;
00303                         fscanf (fp->fp, "%lf\n", &text->rel_x_scale);
00304                 }
00305                 else if (strcmp (temp_string, "48") == 0)
00306                 {
00307                         /* Now follows a string containing the linetype
00308                          * scale. */
00309                         (fp->line_number)++;
00310                         fscanf (fp->fp, "%lf\n", &text->linetype_scale);
00311                 }
00312                 else if (strcmp (temp_string, "50") == 0)
00313                 {
00314                         /* Now follows a string containing the
00315                          * rotation angle. */
00316                         (fp->line_number)++;
00317                         fscanf (fp->fp, "%lf\n", &text->rot_angle);
00318                 }
00319                 else if (strcmp (temp_string, "51") == 0)
00320                 {
00321                         /* Now follows a string containing the
00322                          * oblique angle. */
00323                         (fp->line_number)++;
00324                         fscanf (fp->fp, "%lf\n", &text->obl_angle);
00325                 }
00326                 else if (strcmp (temp_string, "60") == 0)
00327                 {
00328                         /* Now follows a string containing the
00329                          * visibility value. */
00330                         (fp->line_number)++;
00331                         fscanf (fp->fp, "%hd\n", &text->visibility);
00332                 }
00333                 else if (strcmp (temp_string, "62") == 0)
00334                 {
00335                         /* Now follows a string containing the
00336                          * color value. */
00337                         (fp->line_number)++;
00338                         fscanf (fp->fp, "%d\n", &text->color);
00339                 }
00340                 else if (strcmp (temp_string, "67") == 0)
00341                 {
00342                         /* Now follows a string containing the
00343                          * paperspace value. */
00344                         (fp->line_number)++;
00345                         fscanf (fp->fp, "%d\n", &text->paperspace);
00346                 }
00347                 else if (strcmp (temp_string, "71") == 0)
00348                 {
00349                         /* Now follows a string containing the
00350                          * text flags value. */
00351                         (fp->line_number)++;
00352                         fscanf (fp->fp, "%d\n", &text->text_flags);
00353                 }
00354                 else if (strcmp (temp_string, "72") == 0)
00355                 {
00356                         /* Now follows a string containing the
00357                          * horizontal alignment flag value. */
00358                         (fp->line_number)++;
00359                         fscanf (fp->fp, "%d\n", &text->hor_align);
00360                 }
00361                 else if (strcmp (temp_string, "73") == 0)
00362                 {
00363                         /* Now follows a string containing the
00364                          * vertical alignment flag value. */
00365                         (fp->line_number)++;
00366                         fscanf (fp->fp, "%d\n", &text->vert_align);
00367                 }
00368                 else if ((fp->acad_version_number >= AutoCAD_13)
00369                         && (strcmp (temp_string, "100") == 0))
00370                 {
00371                         /* Now follows a string containing the
00372                          * subclass marker value. */
00373                         (fp->line_number)++;
00374                         fscanf (fp->fp, "%s\n", temp_string);
00375                         if ((strcmp (temp_string, "AcDbEntity") != 0)
00376                         && ((strcmp (temp_string, "AcDbText") != 0)))
00377                         {
00378                                 fprintf (stderr,
00379                                   (_("Warning in %s () found a bad subclass marker in: %s in line: %d.\n")),
00380                                   __FUNCTION__, fp->filename, fp->line_number);
00381                         }
00382                 }
00383                 else if (strcmp (temp_string, "210") == 0)
00384                 {
00385                         /* Now follows a string containing the
00386                          * X-value of the extrusion vector. */
00387                         (fp->line_number)++;
00388                         fscanf (fp->fp, "%lf\n", &text->extr_x0);
00389                 }
00390                 else if (strcmp (temp_string, "220") == 0)
00391                 {
00392                         /* Now follows a string containing the
00393                          * Y-value of the extrusion vector. */
00394                         (fp->line_number)++;
00395                         fscanf (fp->fp, "%lf\n", &text->extr_y0);
00396                 }
00397                 else if (strcmp (temp_string, "230") == 0)
00398                 {
00399                         /* Now follows a string containing the
00400                          * Z-value of the extrusion vector. */
00401                         (fp->line_number)++;
00402                         fscanf (fp->fp, "%lf\n", &text->extr_z0);
00403                 }
00404                 else if (strcmp (temp_string, "330") == 0)
00405                 {
00406                         /* Now follows a string containing Soft-pointer
00407                          * ID/handle to owner dictionary. */
00408                         (fp->line_number)++;
00409                         fscanf (fp->fp, "%s\n", text->dictionary_owner_soft);
00410                 }
00411                 else if (strcmp (temp_string, "360") == 0)
00412                 {
00413                         /* Now follows a string containing Hard owner
00414                          * ID/handle to owner dictionary. */
00415                         (fp->line_number)++;
00416                         fscanf (fp->fp, "%s\n", text->dictionary_owner_hard);
00417                 }
00418                 else if (strcmp (temp_string, "999") == 0)
00419                 {
00420                         /* Now follows a string containing a comment. */
00421                         (fp->line_number)++;
00422                         fscanf (fp->fp, "%s\n", temp_string);
00423                         fprintf (stdout, "DXF comment: %s\n", temp_string);
00424                 }
00425                 else
00426                 {
00427                         fprintf (stderr,
00428                           (_("Warning: in %s () unknown string tag found while reading from: %s in line: %d.\n")),
00429                           __FUNCTION__, fp->filename, fp->line_number);
00430                 }
00431         }
00432         /* Handle omitted members and/or illegal values. */
00433         if (strcmp (text->text_value, "") == 0)
00434         {
00435                 fprintf (stderr,
00436                   (_("Error in %s () text value string is empty for the %s entity with id-code: %x\n")),
00437                   __FUNCTION__, dxf_entity_name, text->id_code);
00438                 dxf_entity_skip (dxf_entity_name);
00439                 return (NULL);
00440         }
00441         if (strcmp (text->linetype, "") == 0)
00442         {
00443                 text->linetype = strdup (DXF_DEFAULT_LINETYPE);
00444         }
00445         if (strcmp (text->layer, "") == 0)
00446         {
00447                 text->layer = strdup (DXF_DEFAULT_LAYER);
00448         }
00449         /* Clean up. */
00450         free (temp_string);
00451 #if DEBUG
00452         DXF_DEBUG_END
00453 #endif
00454         return (text);
00455 }
00456 
00457 
00467 int
00468 dxf_text_write
00469 (
00470         DxfFile *fp,
00472         DxfText *text
00474 )
00475 {
00476 #if DEBUG
00477         DXF_DEBUG_BEGIN
00478 #endif
00479         char *dxf_entity_name = strdup ("TEXT");
00480 
00481         /* Do some basic checks. */
00482         if (fp == NULL)
00483         {
00484                 fprintf (stderr,
00485                   (_("Error in %s () a NULL file pointer was passed.\n")),
00486                   __FUNCTION__);
00487                 /* Clean up. */
00488                 free (dxf_entity_name);
00489                 return (EXIT_FAILURE);
00490         }
00491         if (text == NULL)
00492         {
00493                 fprintf (stderr,
00494                   (_("Error in %s () a NULL pointer was passed.\n")),
00495                   __FUNCTION__);
00496                 /* Clean up. */
00497                 free (dxf_entity_name);
00498                 return (EXIT_FAILURE);
00499         }
00500         if (strcmp (text->text_value, "") == 0)
00501         {
00502                 fprintf (stderr,
00503                   (_("Error in %s () text value string is empty for the %s entity with id-code: %x\n")),
00504                   __FUNCTION__, dxf_entity_name, text->id_code);
00505                 dxf_entity_skip (dxf_entity_name);
00506                 /* Clean up. */
00507                 free (dxf_entity_name);
00508                 return (EXIT_FAILURE);
00509         }
00510         if (strcmp (text->text_style, "") == 0)
00511         {
00512                 fprintf (stderr,
00513                   (_("Warning in %s () text style string is empty for the %s entity with id-code: %x\n")),
00514                   __FUNCTION__, dxf_entity_name, text->id_code);
00515                 text->text_style = strdup (DXF_DEFAULT_TEXTSTYLE);        }
00516         if (strcmp (text->layer, "") == 0)
00517         {
00518                 fprintf (stderr,
00519                   (_("Warning in %s () empty layer string for the %s entity with id-code: %x\n")),
00520                   __FUNCTION__, dxf_entity_name, text->id_code);
00521                 fprintf (stderr,
00522                   (_("\t%s entity is relocated to layer 0")),
00523                   dxf_entity_name);
00524                 text->layer = strdup (DXF_DEFAULT_LAYER);
00525         }
00526         if (text->height == 0.0)
00527         {
00528                 fprintf (stderr,
00529                   (_("Warning in %s () height has a value of 0.0 for the %s entity with id-code: %x\n")),
00530                   __FUNCTION__, dxf_entity_name, text->id_code);
00531         }
00532         if (text->rel_x_scale == 0.0)
00533         {
00534                 fprintf (stderr,
00535                   (_("Warning in %s () relative X-scale factor has a value of 0.0 for the %s entity with id-code: %x\n")),
00536                   __FUNCTION__, dxf_entity_name, text->id_code);
00537         }
00538         /* Start writing output. */
00539         fprintf (fp->fp, "  0\n%s\n", dxf_entity_name);
00540         if (text->id_code != -1)
00541         {
00542                 fprintf (fp->fp, "  5\n%x\n", text->id_code);
00543         }
00554         if ((strcmp (text->dictionary_owner_soft, "") != 0)
00555           && (fp->acad_version_number >= AutoCAD_14))
00556         {
00557                 fprintf (fp->fp, "102\n{ACAD_REACTORS\n");
00558                 fprintf (fp->fp, "330\n%s\n", text->dictionary_owner_soft);
00559                 fprintf (fp->fp, "102\n}\n");
00560         }
00561         if ((strcmp (text->dictionary_owner_hard, "") != 0)
00562           && (fp->acad_version_number >= AutoCAD_14))
00563         {
00564                 fprintf (fp->fp, "102\n{ACAD_XDICTIONARY\n");
00565                 fprintf (fp->fp, "360\n%s\n", text->dictionary_owner_hard);
00566                 fprintf (fp->fp, "102\n}\n");
00567         }
00568         if (fp->acad_version_number >= AutoCAD_13)
00569         {
00570                 fprintf (fp->fp, "100\nAcDbEntity\n");
00571         }
00572         if (text->paperspace == 1)
00573         {
00574                 fprintf (fp->fp, " 67\n%d\n", text->paperspace);
00575         }
00576         fprintf (fp->fp, "  8\n%s\n", text->layer);
00577         if (strcmp (text->linetype, DXF_DEFAULT_LINETYPE) != 0)
00578         {
00579                 fprintf (fp->fp, "  6\n%s\n", text->linetype);
00580         }
00581         if ((fp->acad_version_number <= AutoCAD_11)
00582           && DXF_FLATLAND
00583           && (text->elevation != 0.0))
00584         {
00585                 fprintf (fp->fp, " 38\n%f\n", text->elevation);
00586         }
00587         if (text->color != DXF_COLOR_BYLAYER)
00588         {
00589                 fprintf (fp->fp, " 62\n%d\n", text->color);
00590         }
00591         if (text->linetype_scale != 1.0)
00592         {
00593                 fprintf (fp->fp, " 48\n%f\n", text->linetype_scale);
00594         }
00595         if (text->visibility != 0)
00596         {
00597                 fprintf (fp->fp, " 60\n%d\n", text->visibility);
00598         }
00599         if (fp->acad_version_number >= AutoCAD_13)
00600         {
00601                 fprintf (fp->fp, "100\nAcDbText\n");
00602         }
00603         if (text->thickness != 0.0)
00604         {
00605                 fprintf (fp->fp, " 39\n%f\n", text->thickness);
00606         }
00607         fprintf (fp->fp, " 10\n%f\n", text->x0);
00608         fprintf (fp->fp, " 20\n%f\n", text->y0);
00609         fprintf (fp->fp, " 30\n%f\n", text->z0);
00610         fprintf (fp->fp, " 40\n%f\n", text->height);
00611         fprintf (fp->fp, "  1\n%s\n", text->text_value);
00612         if (text->rot_angle != 0.0)
00613         {
00614                 fprintf (fp->fp, " 50\n%f\n", text->rot_angle);
00615         }
00616         if (text->rel_x_scale != 1.0)
00617         {
00618                 fprintf (fp->fp, " 41\n%f\n", text->rel_x_scale);
00619         }
00620         if (text->obl_angle != 0.0)
00621         {
00622                 fprintf (fp->fp, " 51\n%f\n", text->obl_angle);
00623         }
00624         if (strcmp (text->text_style, DXF_DEFAULT_TEXTSTYLE) != 0)
00625         {
00626                 fprintf (fp->fp, "  7\n%s\n", text->text_style);
00627         }
00628         if (text->text_flags != 0)
00629         {
00630                 fprintf (fp->fp, " 71\n%d\n", text->text_flags);
00631         }
00632         if (text->hor_align != 0)
00633         {
00634                 fprintf (fp->fp, " 72\n%d\n", text->hor_align);
00635         }
00636         if ((text->hor_align != 0) || (text->vert_align != 0))
00637         {
00638                 if ((text->x0 == text->x1) && (text->y0 == text->y1) && (text->z0 == text->z1))
00639                 {
00640                         fprintf (stderr,
00641                           (_("Warning in %s () insertion point and alignment point are identical for the %s entity with id-code: %x\n")),
00642                           __FUNCTION__, dxf_entity_name, text->id_code);
00643                         fprintf (stderr,
00644                           (_("\tdefault justification applied to %s entity\n")),
00645                           dxf_entity_name);
00646                         text->hor_align = 0;
00647                         text->vert_align = 0;
00648                 }
00649                 else
00650                 {
00651                         fprintf (fp->fp, " 11\n%f\n", text->x1);
00652                         fprintf (fp->fp, " 21\n%f\n", text->y1);
00653                         fprintf (fp->fp, " 31\n%f\n", text->z1);
00654                 }
00655         }
00656         if ((fp->acad_version_number >= AutoCAD_12)
00657                 && (text->extr_x0 != 0.0)
00658                 && (text->extr_y0 != 0.0)
00659                 && (text->extr_z0 != 1.0))
00660         {
00661                 fprintf (fp->fp, "210\n%f\n", text->extr_x0);
00662                 fprintf (fp->fp, "220\n%f\n", text->extr_y0);
00663                 fprintf (fp->fp, "230\n%f\n", text->extr_z0);
00664         }
00665         if (fp->acad_version_number >= AutoCAD_13)
00666         {
00667                 fprintf (fp->fp, "100\nAcDbText\n");
00668         }
00669         if (text->vert_align != 0)
00670         {
00671                 fprintf (fp->fp, " 73\n%d\n", text->vert_align);
00672         }
00673         /* Clean up. */
00674         free (dxf_entity_name);
00675 #if DEBUG
00676         DXF_DEBUG_END
00677 #endif
00678         return (EXIT_SUCCESS);
00679 }
00680 
00681 
00695 int
00696 dxf_text_free
00697 (
00698         DxfText *text
00701 )
00702 {
00703 #if DEBUG
00704         DXF_DEBUG_BEGIN
00705 #endif
00706         if (text == NULL)
00707         {
00708                 fprintf (stderr,
00709                   (_("Error in %s () a NULL pointer was passed.\n")),
00710                   __FUNCTION__);
00711                 return (EXIT_FAILURE);
00712         }
00713         free (text->linetype);
00714         free (text->layer);
00715         free (text->text_value);
00716         free (text->text_style);
00717         free (text->dictionary_owner_soft);
00718         free (text->dictionary_owner_hard);
00719         free (text);
00720         text = NULL;
00721 #if DEBUG
00722         DXF_DEBUG_END
00723 #endif
00724         return (EXIT_SUCCESS);
00725 }
00726 
00727 
00738 void
00739 dxf_text_free_chain
00740 (
00741         DxfText *texts
00743 )
00744 {
00745 #ifdef DEBUG
00746         DXF_DEBUG_BEGIN
00747 #endif
00748         if (texts == NULL)
00749         {
00750                 fprintf (stderr,
00751                   (_("Warning in %s () a NULL pointer was passed.\n")),
00752                   __FUNCTION__);
00753         }
00754         while (texts != NULL)
00755         {
00756                 struct DxfText *iter = texts->next;
00757                 dxf_text_free (texts);
00758                 texts = (DxfText *) iter;
00759         }
00760 #if DEBUG
00761         DXF_DEBUG_END
00762 #endif
00763 }
00764 
00765 
00766 /* EOF */