LCOV - code coverage report
Current view: top level - ogr/ogrsf_frmts/dxf - ogr_autocad_services.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 203 213 95.3 %
Date: 2024-05-03 15:49:35 Functions: 6 6 100.0 %

          Line data    Source code
       1             : /******************************************************************************
       2             :  *
       3             :  * Project:  DXF and DWG Translators
       4             :  * Purpose:  Implements various generic services shared between autocad related
       5             :  *           drivers.
       6             :  * Author:   Frank Warmerdam, warmerdam@pobox.com
       7             :  *
       8             :  ******************************************************************************
       9             :  * Copyright (c) 2011, Frank Warmerdam <warmerdam@pobox.com>
      10             :  *
      11             :  * Permission is hereby granted, free of charge, to any person obtaining a
      12             :  * copy of this software and associated documentation files (the "Software"),
      13             :  * to deal in the Software without restriction, including without limitation
      14             :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      15             :  * and/or sell copies of the Software, and to permit persons to whom the
      16             :  * Software is furnished to do so, subject to the following conditions:
      17             :  *
      18             :  * The above copyright notice and this permission notice shall be included
      19             :  * in all copies or substantial portions of the Software.
      20             :  *
      21             :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
      22             :  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      23             :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
      24             :  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      25             :  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
      26             :  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
      27             :  * DEALINGS IN THE SOFTWARE.
      28             :  ****************************************************************************/
      29             : 
      30             : #include "ogr_autocad_services.h"
      31             : #include "cpl_conv.h"
      32             : 
      33             : /************************************************************************/
      34             : /*                           ACTextUnescape()                           */
      35             : /*                                                                      */
      36             : /*      Unexcape DXF/DWG style escape sequences such as %%d for the     */
      37             : /*      degree sign, and do the recoding to UTF8.  Set bIsMText to      */
      38             : /*      true to translate MTEXT-specific sequences like \P and \~.      */
      39             : /************************************************************************/
      40             : 
      41         147 : CPLString ACTextUnescape(const char *pszRawInput, const char *pszEncoding,
      42             :                          bool bIsMText)
      43             : 
      44             : {
      45         294 :     CPLString osResult;
      46         294 :     CPLString osInput = pszRawInput;
      47             : 
      48             :     /* -------------------------------------------------------------------- */
      49             :     /*      Translate text from Win-1252 to UTF8.  We approximate this      */
      50             :     /*      by treating Win-1252 as Latin-1.  Note that we likely ought     */
      51             :     /*      to be consulting the $DWGCODEPAGE header variable which         */
      52             :     /*      defaults to ANSI_1252 if not set.                               */
      53             :     /* -------------------------------------------------------------------- */
      54         147 :     osInput.Recode(pszEncoding, CPL_ENC_UTF8);
      55             : 
      56         147 :     const char *pszInput = osInput.c_str();
      57             : 
      58             :     /* -------------------------------------------------------------------- */
      59             :     /*      Now translate low-level escape sequences.  They are all plain   */
      60             :     /*      ASCII characters and won't have been affected by the UTF8       */
      61             :     /*      recoding.                                                       */
      62             :     /* -------------------------------------------------------------------- */
      63        3060 :     while (*pszInput != '\0')
      64             :     {
      65        2913 :         if (pszInput[0] == '^' && pszInput[1] != '\0')
      66             :         {
      67           5 :             if (pszInput[1] == ' ')
      68           3 :                 osResult += '^';
      69             :             else
      70           4 :                 osResult += static_cast<char>(CPLToupper(
      71           2 :                                 static_cast<unsigned char>(pszInput[1]))) ^
      72           2 :                             0x40;
      73           5 :             pszInput++;
      74             :         }
      75        2908 :         else if (STARTS_WITH_CI(pszInput, "%%c") ||
      76        2908 :                  STARTS_WITH_CI(pszInput, "%%d") ||
      77        2908 :                  STARTS_WITH_CI(pszInput, "%%p"))
      78             :         {
      79             :             wchar_t anWCharString[2];
      80             : 
      81           6 :             anWCharString[1] = 0;
      82             : 
      83             :             // These are special symbol representations for AutoCAD.
      84           6 :             if (STARTS_WITH_CI(pszInput, "%%c"))
      85           0 :                 anWCharString[0] =
      86             :                     0x2300;  // diameter (0x00F8 is a good approx)
      87           6 :             else if (STARTS_WITH_CI(pszInput, "%%d"))
      88           0 :                 anWCharString[0] = 0x00B0;  // degree
      89           6 :             else if (STARTS_WITH_CI(pszInput, "%%p"))
      90           6 :                 anWCharString[0] = 0x00B1;  // plus/minus
      91             : 
      92             :             char *pszUTF8Char =
      93           6 :                 CPLRecodeFromWChar(anWCharString, CPL_ENC_UCS2, CPL_ENC_UTF8);
      94             : 
      95           6 :             osResult += pszUTF8Char;
      96           6 :             CPLFree(pszUTF8Char);
      97             : 
      98           6 :             pszInput += 2;
      99             :         }
     100        2902 :         else if (!bIsMText && (STARTS_WITH_CI(pszInput, "%%u") ||
     101         512 :                                STARTS_WITH_CI(pszInput, "%%o") ||
     102         512 :                                STARTS_WITH_CI(pszInput, "%%k")))
     103             :         {
     104             :             // Underline, overline, and strikethrough markers.
     105             :             // These have no effect in MTEXT
     106           7 :             pszInput += 2;
     107             :         }
     108             :         else
     109             :         {
     110        2895 :             osResult += pszInput[0];
     111             :         }
     112             : 
     113        2913 :         pszInput++;
     114             :     }
     115             : 
     116         147 :     if (!bIsMText)
     117          62 :         return osResult;
     118             : 
     119             :     /* -------------------------------------------------------------------- */
     120             :     /*      If this is MTEXT, or something similar (e.g. DIMENSION text),   */
     121             :     /*      do a second pass to strip additional MTEXT format codes.        */
     122             :     /* -------------------------------------------------------------------- */
     123          85 :     pszInput = osResult.c_str();
     124         170 :     CPLString osMtextResult;
     125             : 
     126        2336 :     while (*pszInput != '\0')
     127             :     {
     128        2251 :         if (pszInput[0] == '\\' && pszInput[1] == 'P')
     129             :         {
     130          19 :             osMtextResult += '\n';
     131          19 :             pszInput++;
     132             :         }
     133        2232 :         else if (pszInput[0] == '\\' && pszInput[1] == '~')
     134             :         {
     135          16 :             osMtextResult += ' ';
     136          16 :             pszInput++;
     137             :         }
     138          23 :         else if (pszInput[0] == '\\' && pszInput[1] == 'U' &&
     139        2239 :                  pszInput[2] == '+' && CPLStrnlen(pszInput, 7) >= 7)
     140             :         {
     141          10 :             CPLString osHex;
     142          10 :             unsigned int iChar = 0;
     143             : 
     144          10 :             osHex.assign(pszInput + 3, 4);
     145          10 :             sscanf(osHex.c_str(), "%x", &iChar);
     146             : 
     147             :             wchar_t anWCharString[2];
     148          10 :             anWCharString[0] = (wchar_t)iChar;
     149          10 :             anWCharString[1] = 0;
     150             : 
     151             :             char *pszUTF8Char =
     152          10 :                 CPLRecodeFromWChar(anWCharString, CPL_ENC_UCS2, CPL_ENC_UTF8);
     153             : 
     154          10 :             osMtextResult += pszUTF8Char;
     155          10 :             CPLFree(pszUTF8Char);
     156             : 
     157          10 :             pszInput += 6;
     158             :         }
     159        2206 :         else if (pszInput[0] == '{' || pszInput[0] == '}')
     160             :         {
     161             :             // Skip braces, which are used for grouping
     162             :         }
     163        2203 :         else if (pszInput[0] == '\\' &&
     164          13 :                  strchr("WTAHFfCcQp", pszInput[1]) != nullptr)
     165             :         {
     166             :             // eg. \W1.073172x;\T1.099;Bonneuil de Verrines
     167             :             // See data/dwg/EP/42002.dwg
     168             :             // These are all inline formatting codes which take an argument
     169             :             // up to the first semicolon (\W for width, \f for font, etc)
     170             : 
     171          30 :             while (*pszInput != ';' && *pszInput != '\0')
     172          24 :                 pszInput++;
     173           6 :             if (*pszInput == '\0')
     174           0 :                 break;
     175             :         }
     176        2197 :         else if (pszInput[0] == '\\' &&
     177           7 :                  strchr("KkLlOo", pszInput[1]) != nullptr)
     178             :         {
     179             :             // Inline formatting codes that don't take an argument
     180             : 
     181           3 :             pszInput++;
     182             :         }
     183        2194 :         else if (pszInput[0] == '\\' && pszInput[1] == 'S')
     184             :         {
     185             :             // Stacked text. Normal escapes don't work inside a stack
     186             : 
     187           1 :             pszInput += 2;
     188          18 :             while (*pszInput != ';' && *pszInput != '\0')
     189             :             {
     190          17 :                 if (pszInput[0] == '\\' &&
     191           4 :                     strchr("^/#~", pszInput[1]) != nullptr)
     192             :                 {
     193           4 :                     osMtextResult += pszInput[1];
     194           4 :                     pszInput++;
     195           4 :                     if (pszInput[0] == '\0')
     196           0 :                         break;
     197             :                 }
     198          13 :                 else if (strchr("^/#~", pszInput[0]) == nullptr)
     199             :                 {
     200          12 :                     osMtextResult += pszInput[0];
     201             :                 }
     202          17 :                 pszInput++;
     203             :             }
     204           1 :             if (pszInput[0] == ';')
     205           1 :                 pszInput++;
     206           1 :             if (pszInput[0] == '\0')
     207           0 :                 break;
     208             :         }
     209        2193 :         else if (pszInput[0] == '\\' && strchr("\\{}", pszInput[1]) != nullptr)
     210             :         {
     211             :             // MTEXT character escapes
     212             : 
     213           3 :             osMtextResult += pszInput[1];
     214           3 :             pszInput++;
     215           3 :             if (pszInput[0] == '\0')
     216           0 :                 break;
     217             :         }
     218             :         else
     219             :         {
     220        2190 :             osMtextResult += *pszInput;
     221             :         }
     222             : 
     223        2251 :         pszInput++;
     224             :     }
     225             : 
     226          85 :     return osMtextResult;
     227             : }
     228             : 
     229             : /************************************************************************/
     230             : /*                          ACGetColorTable()                           */
     231             : /************************************************************************/
     232             : 
     233        1226 : const unsigned char *ACGetColorTable()
     234             : 
     235             : {
     236             :     static const unsigned char abyDXFColors[768] = {
     237             :         0,   0,   0,    // 0
     238             :         255, 0,   0,    // 1
     239             :         255, 255, 0,    // 2
     240             :         0,   255, 0,    // 3
     241             :         0,   255, 255,  // 4
     242             :         0,   0,   255,  // 5
     243             :         255, 0,   255,  // 6
     244             :         0,   0,   0,    // 7 - it should be white, but that plots poorly
     245             :         127, 127, 127,  // 8
     246             :         191, 191, 191,  // 9
     247             :         255, 0,   0,    // 10
     248             :         255, 127, 127,  // 11
     249             :         165, 0,   0,    // 12
     250             :         165, 82,  82,   // 13
     251             :         127, 0,   0,    // 14
     252             :         127, 63,  63,   // 15
     253             :         76,  0,   0,    // 16
     254             :         76,  38,  38,   // 17
     255             :         38,  0,   0,    // 18
     256             :         38,  19,  19,   // 19
     257             :         255, 63,  0,    // 20
     258             :         255, 159, 127,  // 21
     259             :         165, 41,  0,    // 22
     260             :         165, 103, 82,   // 23
     261             :         127, 31,  0,    // 24
     262             :         127, 79,  63,   // 25
     263             :         76,  19,  0,    // 26
     264             :         76,  47,  38,   // 27
     265             :         38,  9,   0,    // 28
     266             :         38,  23,  19,   // 29
     267             :         255, 127, 0,    // 30
     268             :         255, 191, 127,  // 31
     269             :         165, 82,  0,    // 32
     270             :         165, 124, 82,   // 33
     271             :         127, 63,  0,    // 34
     272             :         127, 95,  63,   // 35
     273             :         76,  38,  0,    // 36
     274             :         76,  57,  38,   // 37
     275             :         38,  19,  0,    // 38
     276             :         38,  28,  19,   // 39
     277             :         255, 191, 0,    // 40
     278             :         255, 223, 127,  // 41
     279             :         165, 124, 0,    // 42
     280             :         165, 145, 82,   // 43
     281             :         127, 95,  0,    // 44
     282             :         127, 111, 63,   // 45
     283             :         76,  57,  0,    // 46
     284             :         76,  66,  38,   // 47
     285             :         38,  28,  0,    // 48
     286             :         38,  33,  19,   // 49
     287             :         255, 255, 0,    // 50
     288             :         255, 255, 127,  // 51
     289             :         165, 165, 0,    // 52
     290             :         165, 165, 82,   // 53
     291             :         127, 127, 0,    // 54
     292             :         127, 127, 63,   // 55
     293             :         76,  76,  0,    // 56
     294             :         76,  76,  38,   // 57
     295             :         38,  38,  0,    // 58
     296             :         38,  38,  19,   // 59
     297             :         191, 255, 0,    // 60
     298             :         223, 255, 127,  // 61
     299             :         124, 165, 0,    // 62
     300             :         145, 165, 82,   // 63
     301             :         95,  127, 0,    // 64
     302             :         111, 127, 63,   // 65
     303             :         57,  76,  0,    // 66
     304             :         66,  76,  38,   // 67
     305             :         28,  38,  0,    // 68
     306             :         33,  38,  19,   // 69
     307             :         127, 255, 0,    // 70
     308             :         191, 255, 127,  // 71
     309             :         82,  165, 0,    // 72
     310             :         124, 165, 82,   // 73
     311             :         63,  127, 0,    // 74
     312             :         95,  127, 63,   // 75
     313             :         38,  76,  0,    // 76
     314             :         57,  76,  38,   // 77
     315             :         19,  38,  0,    // 78
     316             :         28,  38,  19,   // 79
     317             :         63,  255, 0,    // 80
     318             :         159, 255, 127,  // 81
     319             :         41,  165, 0,    // 82
     320             :         103, 165, 82,   // 83
     321             :         31,  127, 0,    // 84
     322             :         79,  127, 63,   // 85
     323             :         19,  76,  0,    // 86
     324             :         47,  76,  38,   // 87
     325             :         9,   38,  0,    // 88
     326             :         23,  38,  19,   // 89
     327             :         0,   255, 0,    // 90
     328             :         127, 255, 127,  // 91
     329             :         0,   165, 0,    // 92
     330             :         82,  165, 82,   // 93
     331             :         0,   127, 0,    // 94
     332             :         63,  127, 63,   // 95
     333             :         0,   76,  0,    // 96
     334             :         38,  76,  38,   // 97
     335             :         0,   38,  0,    // 98
     336             :         19,  38,  19,   // 99
     337             :         0,   255, 63,   // 100
     338             :         127, 255, 159,  // 101
     339             :         0,   165, 41,   // 102
     340             :         82,  165, 103,  // 103
     341             :         0,   127, 31,   // 104
     342             :         63,  127, 79,   // 105
     343             :         0,   76,  19,   // 106
     344             :         38,  76,  47,   // 107
     345             :         0,   38,  9,    // 108
     346             :         19,  38,  23,   // 109
     347             :         0,   255, 127,  // 110
     348             :         127, 255, 191,  // 111
     349             :         0,   165, 82,   // 112
     350             :         82,  165, 124,  // 113
     351             :         0,   127, 63,   // 114
     352             :         63,  127, 95,   // 115
     353             :         0,   76,  38,   // 116
     354             :         38,  76,  57,   // 117
     355             :         0,   38,  19,   // 118
     356             :         19,  38,  28,   // 119
     357             :         0,   255, 191,  // 120
     358             :         127, 255, 223,  // 121
     359             :         0,   165, 124,  // 122
     360             :         82,  165, 145,  // 123
     361             :         0,   127, 95,   // 124
     362             :         63,  127, 111,  // 125
     363             :         0,   76,  57,   // 126
     364             :         38,  76,  66,   // 127
     365             :         0,   38,  28,   // 128
     366             :         19,  38,  33,   // 129
     367             :         0,   255, 255,  // 130
     368             :         127, 255, 255,  // 131
     369             :         0,   165, 165,  // 132
     370             :         82,  165, 165,  // 133
     371             :         0,   127, 127,  // 134
     372             :         63,  127, 127,  // 135
     373             :         0,   76,  76,   // 136
     374             :         38,  76,  76,   // 137
     375             :         0,   38,  38,   // 138
     376             :         19,  38,  38,   // 139
     377             :         0,   191, 255,  // 140
     378             :         127, 223, 255,  // 141
     379             :         0,   124, 165,  // 142
     380             :         82,  145, 165,  // 143
     381             :         0,   95,  127,  // 144
     382             :         63,  111, 127,  // 145
     383             :         0,   57,  76,   // 146
     384             :         38,  66,  76,   // 147
     385             :         0,   28,  38,   // 148
     386             :         19,  33,  38,   // 149
     387             :         0,   127, 255,  // 150
     388             :         127, 191, 255,  // 151
     389             :         0,   82,  165,  // 152
     390             :         82,  124, 165,  // 153
     391             :         0,   63,  127,  // 154
     392             :         63,  95,  127,  // 155
     393             :         0,   38,  76,   // 156
     394             :         38,  57,  76,   // 157
     395             :         0,   19,  38,   // 158
     396             :         19,  28,  38,   // 159
     397             :         0,   63,  255,  // 160
     398             :         127, 159, 255,  // 161
     399             :         0,   41,  165,  // 162
     400             :         82,  103, 165,  // 163
     401             :         0,   31,  127,  // 164
     402             :         63,  79,  127,  // 165
     403             :         0,   19,  76,   // 166
     404             :         38,  47,  76,   // 167
     405             :         0,   9,   38,   // 168
     406             :         19,  23,  38,   // 169
     407             :         0,   0,   255,  // 170
     408             :         127, 127, 255,  // 171
     409             :         0,   0,   165,  // 172
     410             :         82,  82,  165,  // 173
     411             :         0,   0,   127,  // 174
     412             :         63,  63,  127,  // 175
     413             :         0,   0,   76,   // 176
     414             :         38,  38,  76,   // 177
     415             :         0,   0,   38,   // 178
     416             :         19,  19,  38,   // 179
     417             :         63,  0,   255,  // 180
     418             :         159, 127, 255,  // 181
     419             :         41,  0,   165,  // 182
     420             :         103, 82,  165,  // 183
     421             :         31,  0,   127,  // 184
     422             :         79,  63,  127,  // 185
     423             :         19,  0,   76,   // 186
     424             :         47,  38,  76,   // 187
     425             :         9,   0,   38,   // 188
     426             :         23,  19,  38,   // 189
     427             :         127, 0,   255,  // 190
     428             :         191, 127, 255,  // 191
     429             :         82,  0,   165,  // 192
     430             :         124, 82,  165,  // 193
     431             :         63,  0,   127,  // 194
     432             :         95,  63,  127,  // 195
     433             :         38,  0,   76,   // 196
     434             :         57,  38,  76,   // 197
     435             :         19,  0,   38,   // 198
     436             :         28,  19,  38,   // 199
     437             :         191, 0,   255,  // 200
     438             :         223, 127, 255,  // 201
     439             :         124, 0,   165,  // 202
     440             :         145, 82,  165,  // 203
     441             :         95,  0,   127,  // 204
     442             :         111, 63,  127,  // 205
     443             :         57,  0,   76,   // 206
     444             :         66,  38,  76,   // 207
     445             :         28,  0,   38,   // 208
     446             :         33,  19,  38,   // 209
     447             :         255, 0,   255,  // 210
     448             :         255, 127, 255,  // 211
     449             :         165, 0,   165,  // 212
     450             :         165, 82,  165,  // 213
     451             :         127, 0,   127,  // 214
     452             :         127, 63,  127,  // 215
     453             :         76,  0,   76,   // 216
     454             :         76,  38,  76,   // 217
     455             :         38,  0,   38,   // 218
     456             :         38,  19,  38,   // 219
     457             :         255, 0,   191,  // 220
     458             :         255, 127, 223,  // 221
     459             :         165, 0,   124,  // 222
     460             :         165, 82,  145,  // 223
     461             :         127, 0,   95,   // 224
     462             :         127, 63,  111,  // 225
     463             :         76,  0,   57,   // 226
     464             :         76,  38,  66,   // 227
     465             :         38,  0,   28,   // 228
     466             :         38,  19,  33,   // 229
     467             :         255, 0,   127,  // 230
     468             :         255, 127, 191,  // 231
     469             :         165, 0,   82,   // 232
     470             :         165, 82,  124,  // 233
     471             :         127, 0,   63,   // 234
     472             :         127, 63,  95,   // 235
     473             :         76,  0,   38,   // 236
     474             :         76,  38,  57,   // 237
     475             :         38,  0,   19,   // 238
     476             :         38,  19,  28,   // 239
     477             :         255, 0,   63,   // 240
     478             :         255, 127, 159,  // 241
     479             :         165, 0,   41,   // 242
     480             :         165, 82,  103,  // 243
     481             :         127, 0,   31,   // 244
     482             :         127, 63,  79,   // 245
     483             :         76,  0,   19,   // 246
     484             :         76,  38,  47,   // 247
     485             :         38,  0,   9,    // 248
     486             :         38,  19,  23,   // 249
     487             :         84,  84,  84,   // 250
     488             :         118, 118, 118,  // 251
     489             :         152, 152, 152,  // 252
     490             :         186, 186, 186,  // 253
     491             :         220, 220, 220,  // 254
     492             :         255, 255, 255   // 255
     493             :     };
     494             : 
     495        1226 :     return abyDXFColors;
     496             : }
     497             : 
     498             : /************************************************************************/
     499             : /*                       ACGetKnownDimStyleCodes()                      */
     500             : /*                                                                      */
     501             : /*      Gets a list of the DIMSTYLE codes that we care about. Array     */
     502             : /*      terminates with a zero value.                                   */
     503             : /************************************************************************/
     504             : 
     505         182 : const int *ACGetKnownDimStyleCodes()
     506             : {
     507             :     static const int aiKnownCodes[] = {40,  41,  42,  44,  75,  76,  77,
     508             :                                        140, 147, 176, 178, 271, 341, 0};
     509             : 
     510         182 :     return aiKnownCodes;
     511             : }
     512             : 
     513             : /************************************************************************/
     514             : /*                      ACGetDimStylePropertyName()                     */
     515             : /************************************************************************/
     516             : 
     517        3751 : const char *ACGetDimStylePropertyName(const int iDimStyleCode)
     518             : 
     519             : {
     520             :     // We are only interested in properties required by the DIMENSION
     521             :     // and LEADER code. Return NULL for other properties.
     522        3751 :     switch (iDimStyleCode)
     523             :     {
     524         207 :         case 40:
     525         207 :             return "DIMSCALE";
     526         222 :         case 41:
     527         222 :             return "DIMASZ";
     528         203 :         case 42:
     529         203 :             return "DIMEXO";
     530         203 :         case 44:
     531         203 :             return "DIMEXE";
     532         188 :         case 75:
     533         188 :             return "DIMSE1";
     534         188 :         case 76:
     535         188 :             return "DIMSE2";
     536         205 :         case 77:
     537         205 :             return "DIMTAD";
     538         216 :         case 140:
     539         216 :             return "DIMTXT";
     540         201 :         case 147:
     541         201 :             return "DIMGAP";
     542         204 :         case 176:
     543         204 :             return "DIMCLRD";
     544         188 :         case 178:
     545         188 :             return "DIMCLRT";
     546         210 :         case 271:
     547         210 :             return "DIMDEC";
     548         190 :         case 341:
     549         190 :             return "DIMLDRBLK";
     550        1126 :         default:
     551        1126 :             return nullptr;
     552             :     }
     553             : }
     554             : 
     555             : /************************************************************************/
     556             : /*                    ACGetDimStylePropertyDefault()                    */
     557             : /************************************************************************/
     558             : 
     559        2366 : const char *ACGetDimStylePropertyDefault(const int iDimStyleCode)
     560             : 
     561             : {
     562             :     // We are only interested in properties required by the DIMENSION
     563             :     // and LEADER code. Return "0" for other, unknown properties.
     564             :     // These defaults were obtained from the Express\defaults.scr file
     565             :     // in an AutoCAD installation.
     566        2366 :     switch (iDimStyleCode)
     567             :     {
     568         182 :         case 40:
     569         182 :             return "1.0";
     570         182 :         case 41:
     571         182 :             return "0.18";
     572         182 :         case 42:
     573         182 :             return "0.0625";
     574         182 :         case 44:
     575         182 :             return "0.18";
     576         182 :         case 75:
     577         182 :             return "0";
     578         182 :         case 76:
     579         182 :             return "0";
     580         182 :         case 77:
     581         182 :             return "0";
     582         182 :         case 140:
     583         182 :             return "0.18";
     584         182 :         case 147:
     585         182 :             return "0.09";
     586         182 :         case 176:
     587         182 :             return "0";
     588         182 :         case 178:
     589         182 :             return "0";
     590         182 :         case 271:
     591         182 :             return "4";
     592         182 :         case 341:
     593         182 :             return "";
     594           0 :         default:
     595           0 :             return "0";
     596             :     }
     597             : }
     598             : 
     599             : /************************************************************************/
     600             : /*                            ACAdjustText()                            */
     601             : /*                                                                      */
     602             : /*      Rotate and scale text features by the designated amount by      */
     603             : /*      adjusting the style string.                                     */
     604             : /************************************************************************/
     605             : 
     606         538 : void ACAdjustText(const double dfAngle, const double dfScaleX,
     607             :                   const double dfScaleY, OGRFeature *const poFeature)
     608             : 
     609             : {
     610             :     /* -------------------------------------------------------------------- */
     611             :     /*      We only try to alter text elements (LABEL styles).              */
     612             :     /* -------------------------------------------------------------------- */
     613         538 :     if (poFeature->GetStyleString() == nullptr)
     614         474 :         return;
     615             : 
     616         538 :     CPLString osOldStyle = poFeature->GetStyleString();
     617             : 
     618         538 :     if (!STARTS_WITH(osOldStyle, "LABEL("))
     619         474 :         return;
     620             : 
     621             :     // Split the style string up into its parts
     622          64 :     osOldStyle.erase(0, 6);
     623          64 :     osOldStyle.erase(osOldStyle.size() - 1);
     624          64 :     char **papszTokens = CSLTokenizeString2(
     625             :         osOldStyle, ",",
     626             :         CSLT_HONOURSTRINGS | CSLT_PRESERVEQUOTES | CSLT_PRESERVEESCAPES);
     627             : 
     628             :     /* -------------------------------------------------------------------- */
     629             :     /*      Update the text angle.                                          */
     630             :     /* -------------------------------------------------------------------- */
     631             :     char szBuffer[64];
     632             : 
     633          64 :     if (dfAngle != 0.0)
     634             :     {
     635           4 :         double dfOldAngle = 0.0;
     636             : 
     637           4 :         const char *pszAngle = CSLFetchNameValue(papszTokens, "a");
     638           4 :         if (pszAngle)
     639           0 :             dfOldAngle = CPLAtof(pszAngle);
     640             : 
     641           4 :         CPLsnprintf(szBuffer, sizeof(szBuffer), "%.3g", dfOldAngle + dfAngle);
     642           4 :         papszTokens = CSLSetNameValue(papszTokens, "a", szBuffer);
     643             :     }
     644             : 
     645             :     /* -------------------------------------------------------------------- */
     646             :     /*      Update the text width and height.                               */
     647             :     /* -------------------------------------------------------------------- */
     648             : 
     649          64 :     if (dfScaleY != 1.0)
     650             :     {
     651           4 :         const char *pszHeight = CSLFetchNameValue(papszTokens, "s");
     652           4 :         if (pszHeight)
     653             :         {
     654           4 :             const double dfOldHeight = CPLAtof(pszHeight);
     655             : 
     656           4 :             CPLsnprintf(szBuffer, sizeof(szBuffer), "%.3gg",
     657             :                         dfOldHeight * dfScaleY);
     658           4 :             papszTokens = CSLSetNameValue(papszTokens, "s", szBuffer);
     659             :         }
     660             :     }
     661             : 
     662          64 :     if (dfScaleX != dfScaleY && dfScaleY != 0.0)
     663             :     {
     664           4 :         const double dfWidthFactor = dfScaleX / dfScaleY;
     665           4 :         double dfOldWidth = 100.0;
     666             : 
     667           4 :         const char *pszWidth = CSLFetchNameValue(papszTokens, "w");
     668           4 :         if (pszWidth)
     669           3 :             dfOldWidth = CPLAtof(pszWidth);
     670             : 
     671           4 :         CPLsnprintf(szBuffer, sizeof(szBuffer), "%.4g",
     672             :                     dfOldWidth * dfWidthFactor);
     673           4 :         papszTokens = CSLSetNameValue(papszTokens, "w", szBuffer);
     674             :     }
     675             : 
     676             :     /* -------------------------------------------------------------------- */
     677             :     /*      Update the text offsets.                                        */
     678             :     /* -------------------------------------------------------------------- */
     679             : 
     680          64 :     if (dfScaleX != 1.0 || dfScaleY != 1.0 || dfAngle != 0.0)
     681             :     {
     682           6 :         double dfOldDx = 0.0;
     683           6 :         double dfOldDy = 0.0;
     684             : 
     685           6 :         const char *pszDx = CSLFetchNameValue(papszTokens, "dx");
     686           6 :         if (pszDx)
     687           2 :             dfOldDx = CPLAtof(pszDx);
     688           6 :         const char *pszDy = CSLFetchNameValue(papszTokens, "dy");
     689           6 :         if (pszDy)
     690           0 :             dfOldDy = CPLAtof(pszDy);
     691             : 
     692           6 :         if (dfOldDx != 0.0 || dfOldDy != 0.0)
     693             :         {
     694           2 :             const double dfAngleRadians = dfAngle * M_PI / 180.0;
     695             : 
     696           2 :             CPLsnprintf(szBuffer, sizeof(szBuffer), "%.6gg",
     697           2 :                         dfScaleX * dfOldDx * cos(dfAngleRadians) +
     698           2 :                             dfScaleY * dfOldDy * -sin(dfAngleRadians));
     699           2 :             papszTokens = CSLSetNameValue(papszTokens, "dx", szBuffer);
     700             : 
     701           2 :             CPLsnprintf(szBuffer, sizeof(szBuffer), "%.6gg",
     702           2 :                         dfScaleX * dfOldDx * sin(dfAngleRadians) +
     703           2 :                             dfScaleY * dfOldDy * cos(dfAngleRadians));
     704           2 :             papszTokens = CSLSetNameValue(papszTokens, "dy", szBuffer);
     705             :         }
     706             :     }
     707             : 
     708          64 :     CSLSetNameValueSeparator(papszTokens, ":");
     709             : 
     710         128 :     CPLString osNewStyle = "LABEL(";
     711          64 :     int iIndex = 0;
     712         497 :     while (papszTokens[iIndex])
     713             :     {
     714         433 :         if (iIndex > 0)
     715         369 :             osNewStyle += ",";
     716         433 :         osNewStyle += papszTokens[iIndex++];
     717             :     }
     718          64 :     osNewStyle += ")";
     719             : 
     720          64 :     poFeature->SetStyleString(osNewStyle);
     721             : 
     722          64 :     CSLDestroy(papszTokens);
     723             : }

Generated by: LCOV version 1.14