LCOV - code coverage report
Current view: top level - ogr - ogrfeaturestyle.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 618 991 62.4 %
Date: 2025-10-01 17:07:58 Functions: 99 125 79.2 %

          Line data    Source code
       1             : /******************************************************************************
       2             :  *
       3             :  * Project:  OpenGIS Simple Features Reference Implementation
       4             :  * Purpose:  Feature Representation string API
       5             :  * Author:   Stephane Villeneuve, stephane.v@videotron.ca
       6             :  *
       7             :  ******************************************************************************
       8             :  * Copyright (c) 2000-2001, Stephane Villeneuve
       9             :  * Copyright (c) 2008-2010, Even Rouault <even dot rouault at spatialys.com>
      10             :  *
      11             :  * SPDX-License-Identifier: MIT
      12             :  ****************************************************************************/
      13             : 
      14             : #include "cpl_port.h"
      15             : #include "ogr_featurestyle.h"
      16             : 
      17             : #include <cstddef>
      18             : #include <cstdio>
      19             : #include <cstdlib>
      20             : #include <cstring>
      21             : 
      22             : #include <string>
      23             : 
      24             : #include "cpl_conv.h"
      25             : #include "cpl_error.h"
      26             : #include "cpl_string.h"
      27             : #include "cpl_vsi.h"
      28             : #include "ogr_api.h"
      29             : #include "ogr_core.h"
      30             : #include "ogr_feature.h"
      31             : 
      32             : /****************************************************************************/
      33             : /*                Class Parameter (used in the String)                      */
      34             : /*                                                                          */
      35             : /*      The order of all parameter MUST be the same than in the definition. */
      36             : /****************************************************************************/
      37             : static const OGRStyleParamId asStylePen[] = {
      38             :     {OGRSTPenColor, "c", FALSE, OGRSTypeString},
      39             :     {OGRSTPenWidth, "w", TRUE, OGRSTypeDouble},
      40             :     // Georefed, but multiple times.
      41             :     {OGRSTPenPattern, "p", FALSE, OGRSTypeString},
      42             :     {OGRSTPenId, "id", FALSE, OGRSTypeString},
      43             :     {OGRSTPenPerOffset, "dp", TRUE, OGRSTypeDouble},
      44             :     {OGRSTPenCap, "cap", FALSE, OGRSTypeString},
      45             :     {OGRSTPenJoin, "j", FALSE, OGRSTypeString},
      46             :     {OGRSTPenPriority, "l", FALSE, OGRSTypeInteger}};
      47             : 
      48             : static const OGRStyleParamId asStyleBrush[] = {
      49             :     {OGRSTBrushFColor, "fc", FALSE, OGRSTypeString},
      50             :     {OGRSTBrushBColor, "bc", FALSE, OGRSTypeString},
      51             :     {OGRSTBrushId, "id", FALSE, OGRSTypeString},
      52             :     {OGRSTBrushAngle, "a", FALSE, OGRSTypeDouble},
      53             :     {OGRSTBrushSize, "s", TRUE, OGRSTypeDouble},
      54             :     {OGRSTBrushDx, "dx", TRUE, OGRSTypeDouble},
      55             :     {OGRSTBrushDy, "dy", TRUE, OGRSTypeDouble},
      56             :     {OGRSTBrushPriority, "l", FALSE, OGRSTypeInteger}};
      57             : 
      58             : static const OGRStyleParamId asStyleSymbol[] = {
      59             :     {OGRSTSymbolId, "id", FALSE, OGRSTypeString},
      60             :     {OGRSTSymbolAngle, "a", FALSE, OGRSTypeDouble},
      61             :     {OGRSTSymbolColor, "c", FALSE, OGRSTypeString},
      62             :     {OGRSTSymbolSize, "s", TRUE, OGRSTypeDouble},
      63             :     {OGRSTSymbolDx, "dx", TRUE, OGRSTypeDouble},
      64             :     {OGRSTSymbolDy, "dy", TRUE, OGRSTypeDouble},
      65             :     {OGRSTSymbolStep, "ds", TRUE, OGRSTypeDouble},
      66             :     {OGRSTSymbolPerp, "dp", TRUE, OGRSTypeDouble},
      67             :     {OGRSTSymbolOffset, "di", TRUE, OGRSTypeDouble},
      68             :     {OGRSTSymbolPriority, "l", FALSE, OGRSTypeInteger},
      69             :     {OGRSTSymbolFontName, "f", FALSE, OGRSTypeString},
      70             :     {OGRSTSymbolOColor, "o", FALSE, OGRSTypeString}};
      71             : 
      72             : static const OGRStyleParamId asStyleLabel[] = {
      73             :     {OGRSTLabelFontName, "f", FALSE, OGRSTypeString},
      74             :     {OGRSTLabelSize, "s", TRUE, OGRSTypeDouble},
      75             :     {OGRSTLabelTextString, "t", FALSE, OGRSTypeString},
      76             :     {OGRSTLabelAngle, "a", FALSE, OGRSTypeDouble},
      77             :     {OGRSTLabelFColor, "c", FALSE, OGRSTypeString},
      78             :     {OGRSTLabelBColor, "b", FALSE, OGRSTypeString},
      79             :     {OGRSTLabelPlacement, "m", FALSE, OGRSTypeString},
      80             :     {OGRSTLabelAnchor, "p", FALSE, OGRSTypeInteger},
      81             :     {OGRSTLabelDx, "dx", TRUE, OGRSTypeDouble},
      82             :     {OGRSTLabelDy, "dy", TRUE, OGRSTypeDouble},
      83             :     {OGRSTLabelPerp, "dp", TRUE, OGRSTypeDouble},
      84             :     {OGRSTLabelBold, "bo", FALSE, OGRSTypeBoolean},
      85             :     {OGRSTLabelItalic, "it", FALSE, OGRSTypeBoolean},
      86             :     {OGRSTLabelUnderline, "un", FALSE, OGRSTypeBoolean},
      87             :     {OGRSTLabelPriority, "l", FALSE, OGRSTypeInteger},
      88             :     {OGRSTLabelStrikeout, "st", FALSE, OGRSTypeBoolean},
      89             :     {OGRSTLabelStretch, "w", FALSE, OGRSTypeDouble},
      90             :     {-1, nullptr, FALSE, OGRSTypeUnused},  // was OGRSTLabelAdjHor
      91             :     {-1, nullptr, FALSE, OGRSTypeUnused},  // was OGRSTLabelAdjVert
      92             :     {OGRSTLabelHColor, "h", FALSE, OGRSTypeString},
      93             :     {OGRSTLabelOColor, "o", FALSE, OGRSTypeString}};
      94             : 
      95             : /* ======================================================================== */
      96             : /* OGRStyleMgr                                                              */
      97             : /* ======================================================================== */
      98             : 
      99             : /****************************************************************************/
     100             : /*             OGRStyleMgr::OGRStyleMgr(OGRStyleTable *poDataSetStyleTable) */
     101             : /*                                                                          */
     102             : /****************************************************************************/
     103             : /**
     104             :  * \brief Constructor.
     105             :  *
     106             :  * This method is the same as the C function OGR_SM_Create()
     107             :  *
     108             :  * @param poDataSetStyleTable (currently unused, reserved for future use),
     109             :  * pointer to OGRStyleTable. Pass NULL for now.
     110             :  */
     111         971 : OGRStyleMgr::OGRStyleMgr(OGRStyleTable *poDataSetStyleTable)
     112         971 :     : m_poDataSetStyleTable(poDataSetStyleTable)
     113             : {
     114         971 : }
     115             : 
     116             : /************************************************************************/
     117             : /*                            OGR_SM_Create()                           */
     118             : /************************************************************************/
     119             : /**
     120             :  * \brief OGRStyleMgr factory.
     121             :  *
     122             :  * This function is the same as the C++ method OGRStyleMgr::OGRStyleMgr().
     123             :  *
     124             :  * @param hStyleTable pointer to OGRStyleTable or NULL if not working with
     125             :  *  a style table.
     126             :  *
     127             :  * @return a handle to the new style manager object.
     128             :  */
     129             : 
     130         127 : OGRStyleMgrH OGR_SM_Create(OGRStyleTableH hStyleTable)
     131             : 
     132             : {
     133             :     return reinterpret_cast<OGRStyleMgrH>(
     134         127 :         new OGRStyleMgr(reinterpret_cast<OGRStyleTable *>(hStyleTable)));
     135             : }
     136             : 
     137             : /****************************************************************************/
     138             : /*             OGRStyleMgr::~OGRStyleMgr()                                  */
     139             : /*                                                                          */
     140             : /****************************************************************************/
     141             : /**
     142             :  * \brief Destructor.
     143             :  *
     144             :  * This method is the same as the C function OGR_SM_Destroy()
     145             :  */
     146        1942 : OGRStyleMgr::~OGRStyleMgr()
     147             : {
     148         971 :     CPLFree(m_pszStyleString);
     149         971 : }
     150             : 
     151             : /************************************************************************/
     152             : /*                           OGR_SM_Destroy()                            */
     153             : /************************************************************************/
     154             : /**
     155             :  * \brief Destroy Style Manager
     156             :  *
     157             :  * This function is the same as the C++ method OGRStyleMgr::~OGRStyleMgr().
     158             :  *
     159             :  * @param hSM handle to the style manager to destroy.
     160             :  */
     161             : 
     162         127 : void OGR_SM_Destroy(OGRStyleMgrH hSM)
     163             : 
     164             : {
     165         127 :     delete reinterpret_cast<OGRStyleMgr *>(hSM);
     166         127 : }
     167             : 
     168             : /****************************************************************************/
     169             : /*      GBool OGRStyleMgr::SetFeatureStyleString(OGRFeature *poFeature,     */
     170             : /*                                       char *pszStyleString,              */
     171             : /*                                       GBool bNoMatching)                 */
     172             : /*      Set the given representation to the feature,                        */
     173             : /*      if bNoMatching == TRUE, don't try to find it in the styletable      */
     174             : /*      otherwise, we will use the name defined in the styletable.          */
     175             : /****************************************************************************/
     176             : 
     177             : /**
     178             :  * \brief Set a style in a feature
     179             :  *
     180             :  * @param poFeature       the feature object to store the style in
     181             :  * @param pszStyleString  the style to store
     182             :  * @param bNoMatching     TRUE to lookup the style in the style table and
     183             :  *  add the name to the feature
     184             :  *
     185             :  * @return TRUE on success, FALSE on error.
     186             :  */
     187             : 
     188           0 : GBool OGRStyleMgr::SetFeatureStyleString(OGRFeature *poFeature,
     189             :                                          const char *pszStyleString,
     190             :                                          GBool bNoMatching)
     191             : {
     192           0 :     if (poFeature == nullptr)
     193           0 :         return FALSE;
     194             : 
     195           0 :     const char *pszName = nullptr;
     196             : 
     197           0 :     if (pszStyleString == nullptr)
     198           0 :         poFeature->SetStyleString("");
     199           0 :     else if (bNoMatching == TRUE)
     200           0 :         poFeature->SetStyleString(pszStyleString);
     201           0 :     else if ((pszName = GetStyleName(pszStyleString)) != nullptr)
     202           0 :         poFeature->SetStyleString(pszName);
     203             :     else
     204           0 :         poFeature->SetStyleString(pszStyleString);
     205             : 
     206           0 :     return TRUE;
     207             : }
     208             : 
     209             : /****************************************************************************/
     210             : /*            const char *OGRStyleMgr::InitFromFeature(OGRFeature *)        */
     211             : /*                                                                          */
     212             : /****************************************************************************/
     213             : 
     214             : /**
     215             :  * \brief Initialize style manager from the style string of a feature.
     216             :  *
     217             :  * This method is the same as the C function OGR_SM_InitFromFeature().
     218             :  *
     219             :  * @param poFeature feature object from which to read the style.
     220             :  *
     221             :  * @return a reference to the style string read from the feature, or NULL
     222             :  * in case of error..
     223             :  */
     224             : 
     225         147 : const char *OGRStyleMgr::InitFromFeature(OGRFeature *poFeature)
     226             : {
     227         147 :     CPLFree(m_pszStyleString);
     228         147 :     m_pszStyleString = nullptr;
     229             : 
     230         147 :     if (poFeature)
     231         147 :         InitStyleString(poFeature->GetStyleString());
     232             :     else
     233           0 :         m_pszStyleString = nullptr;
     234             : 
     235         147 :     return m_pszStyleString;
     236             : }
     237             : 
     238             : /************************************************************************/
     239             : /*                     OGR_SM_InitFromFeature()                         */
     240             : /************************************************************************/
     241             : 
     242             : /**
     243             :  * \brief Initialize style manager from the style string of a feature.
     244             :  *
     245             :  * This function is the same as the C++ method
     246             :  * OGRStyleMgr::InitFromFeature().
     247             :  *
     248             :  * @param hSM handle to the style manager.
     249             :  * @param hFeat handle to the new feature from which to read the style.
     250             :  *
     251             :  * @return a reference to the style string read from the feature, or NULL
     252             :  * in case of error.
     253             :  */
     254             : 
     255         125 : const char *OGR_SM_InitFromFeature(OGRStyleMgrH hSM, OGRFeatureH hFeat)
     256             : 
     257             : {
     258         125 :     VALIDATE_POINTER1(hSM, "OGR_SM_InitFromFeature", nullptr);
     259         125 :     VALIDATE_POINTER1(hFeat, "OGR_SM_InitFromFeature", nullptr);
     260             : 
     261         125 :     return reinterpret_cast<OGRStyleMgr *>(hSM)->InitFromFeature(
     262         125 :         reinterpret_cast<OGRFeature *>(hFeat));
     263             : }
     264             : 
     265             : /****************************************************************************/
     266             : /*            GBool OGRStyleMgr::InitStyleString(char *pszStyleString)      */
     267             : /*                                                                          */
     268             : /****************************************************************************/
     269             : 
     270             : /**
     271             :  * \brief Initialize style manager from the style string.
     272             :  *
     273             :  * Style string can be an expanded style string (e.g. "PEN(c:#FF0000,w:5px)"),
     274             :  * or (starting with GDAL 3.5.1), a reference to a style name starting with @
     275             :  * (e.g. "@my_style") registered in the associated style table.
     276             :  *
     277             :  * This method is the same as the C function OGR_SM_InitStyleString().
     278             :  *
     279             :  * @param pszStyleString the style string to use (can be NULL).
     280             :  *
     281             :  * @return TRUE on success, FALSE on errors.
     282             :  */
     283        1076 : GBool OGRStyleMgr::InitStyleString(const char *pszStyleString)
     284             : {
     285        1076 :     CPLFree(m_pszStyleString);
     286        1076 :     m_pszStyleString = nullptr;
     287             : 
     288        1076 :     if (pszStyleString && pszStyleString[0] == '@')
     289             :     {
     290           2 :         const char *pszStyleStringFromName = GetStyleByName(pszStyleString + 1);
     291           2 :         if (pszStyleStringFromName == nullptr)
     292           1 :             return FALSE;
     293           1 :         m_pszStyleString = CPLStrdup(pszStyleStringFromName);
     294             :     }
     295        1074 :     else if (pszStyleString)
     296         608 :         m_pszStyleString = CPLStrdup(pszStyleString);
     297             : 
     298        1075 :     return TRUE;
     299             : }
     300             : 
     301             : /************************************************************************/
     302             : /*                     OGR_SM_InitStyleString()                         */
     303             : /************************************************************************/
     304             : 
     305             : /**
     306             :  * \brief Initialize style manager from the style string.
     307             :  *
     308             :  * Style string can be an expanded style string (e.g. "PEN(c:#FF0000,w:5px)"),
     309             :  * or (starting with GDAL 3.5.1), a reference to a style name starting with @
     310             :  * (e.g. "@my_style") registered in the associated style table.
     311             :  *
     312             :  * This function is the same as the C++ method OGRStyleMgr::InitStyleString().
     313             :  *
     314             :  * @param hSM handle to the style manager.
     315             :  * @param pszStyleString the style string to use (can be NULL).
     316             :  *
     317             :  * @return TRUE on success, FALSE on errors.
     318             :  */
     319             : 
     320           3 : int OGR_SM_InitStyleString(OGRStyleMgrH hSM, const char *pszStyleString)
     321             : 
     322             : {
     323           3 :     VALIDATE_POINTER1(hSM, "OGR_SM_InitStyleString", FALSE);
     324             : 
     325           3 :     return reinterpret_cast<OGRStyleMgr *>(hSM)->InitStyleString(
     326           3 :         pszStyleString);
     327             : }
     328             : 
     329             : /****************************************************************************/
     330             : /*      const char *OGRStyleMgr::GetStyleName(const char *pszStyleString)   */
     331             : /****************************************************************************/
     332             : 
     333             : /**
     334             :  * \brief Get the name of a style from the style table.
     335             :  *
     336             :  * @param pszStyleString the style to search for, or NULL to use the style
     337             :  *   currently stored in the manager.
     338             :  *
     339             :  * @return The name if found, or NULL on error.
     340             :  */
     341             : 
     342           0 : const char *OGRStyleMgr::GetStyleName(const char *pszStyleString)
     343             : {
     344             :     // SECURITY: The unit and the value for all parameter should be the same,
     345             :     // a text comparison is executed.
     346             : 
     347           0 :     const char *pszStyle = pszStyleString ? pszStyleString : m_pszStyleString;
     348             : 
     349           0 :     if (pszStyle)
     350             :     {
     351           0 :         if (m_poDataSetStyleTable)
     352           0 :             return m_poDataSetStyleTable->GetStyleName(pszStyle);
     353             :     }
     354           0 :     return nullptr;
     355             : }
     356             : 
     357             : /****************************************************************************/
     358             : /*      const char *OGRStyleMgr::GetStyleByName(const char *pszStyleName)   */
     359             : /*                                                                          */
     360             : /****************************************************************************/
     361             : 
     362             : /**
     363             :  * \brief find a style in the current style table.
     364             :  *
     365             :  *
     366             :  * @param pszStyleName the name of the style to add.
     367             :  *
     368             :  * @return the style string matching the name or NULL if not found or error.
     369             :  */
     370           2 : const char *OGRStyleMgr::GetStyleByName(const char *pszStyleName)
     371             : {
     372           2 :     if (m_poDataSetStyleTable)
     373             :     {
     374           2 :         return m_poDataSetStyleTable->Find(pszStyleName);
     375             :     }
     376           0 :     return nullptr;
     377             : }
     378             : 
     379             : /****************************************************************************/
     380             : /*            GBool OGRStyleMgr::AddStyle(char *pszStyleName,               */
     381             : /*                                   char *pszStyleString)                  */
     382             : /*                                                                          */
     383             : /****************************************************************************/
     384             : 
     385             : /**
     386             :  * \brief Add a style to the current style table.
     387             :  *
     388             :  * This method is the same as the C function OGR_SM_AddStyle().
     389             :  *
     390             :  * @param pszStyleName the name of the style to add.
     391             :  * @param pszStyleString the style string to use, or NULL to use the style
     392             :  *                       stored in the manager.
     393             :  *
     394             :  * @return TRUE on success, FALSE on errors.
     395             :  */
     396             : 
     397         155 : GBool OGRStyleMgr::AddStyle(const char *pszStyleName,
     398             :                             const char *pszStyleString)
     399             : {
     400         155 :     const char *pszStyle = pszStyleString ? pszStyleString : m_pszStyleString;
     401             : 
     402         155 :     if (m_poDataSetStyleTable)
     403             :     {
     404         155 :         return m_poDataSetStyleTable->AddStyle(pszStyleName, pszStyle);
     405             :     }
     406           0 :     return FALSE;
     407             : }
     408             : 
     409             : /************************************************************************/
     410             : /*                     OGR_SM_AddStyle()                         */
     411             : /************************************************************************/
     412             : 
     413             : /**
     414             :  * \brief Add a style to the current style table.
     415             :  *
     416             :  * This function is the same as the C++ method OGRStyleMgr::AddStyle().
     417             :  *
     418             :  * @param hSM handle to the style manager.
     419             :  * @param pszStyleName the name of the style to add.
     420             :  * @param pszStyleString the style string to use, or NULL to use the style
     421             :  *                       stored in the manager.
     422             :  *
     423             :  * @return TRUE on success, FALSE on errors.
     424             :  */
     425             : 
     426           0 : int OGR_SM_AddStyle(OGRStyleMgrH hSM, const char *pszStyleName,
     427             :                     const char *pszStyleString)
     428             : {
     429           0 :     VALIDATE_POINTER1(hSM, "OGR_SM_AddStyle", FALSE);
     430           0 :     VALIDATE_POINTER1(pszStyleName, "OGR_SM_AddStyle", FALSE);
     431             : 
     432           0 :     return reinterpret_cast<OGRStyleMgr *>(hSM)->AddStyle(pszStyleName,
     433           0 :                                                           pszStyleString);
     434             : }
     435             : 
     436             : /****************************************************************************/
     437             : /*            const char *OGRStyleMgr::GetStyleString(OGRFeature *)         */
     438             : /*                                                                          */
     439             : /****************************************************************************/
     440             : 
     441             : /**
     442             :  * \brief Get the style string from the style manager.
     443             :  *
     444             :  * @param poFeature feature object from which to read the style or NULL to
     445             :  *                  get the style string stored in the manager.
     446             :  *
     447             :  * @return the style string stored in the feature or the style string stored
     448             :  *          in the style manager if poFeature is NULL
     449             :  *
     450             :  * NOTE: this method will call OGRStyleMgr::InitFromFeature() if poFeature is
     451             :  *       not NULL and replace the style string stored in the style manager
     452             :  */
     453             : 
     454         244 : const char *OGRStyleMgr::GetStyleString(OGRFeature *poFeature)
     455             : {
     456         244 :     if (poFeature == nullptr)
     457         244 :         return m_pszStyleString;
     458             : 
     459           0 :     return InitFromFeature(poFeature);
     460             : }
     461             : 
     462             : /****************************************************************************/
     463             : /*            GBool OGRStyleMgr::AddPart(const char *pszPart)               */
     464             : /*            Add a new part in the current style                           */
     465             : /****************************************************************************/
     466             : 
     467             : /**
     468             :  * \brief Add a part (style string) to the current style.
     469             :  *
     470             :  * @param pszPart the style string defining the part to add.
     471             :  *
     472             :  * @return TRUE on success, FALSE on errors.
     473             :  */
     474             : 
     475           0 : GBool OGRStyleMgr::AddPart(const char *pszPart)
     476             : {
     477           0 :     if (pszPart == nullptr)
     478           0 :         return FALSE;
     479             : 
     480           0 :     if (m_pszStyleString)
     481             :     {
     482             :         char *pszTmp =
     483           0 :             CPLStrdup(CPLString().Printf("%s;%s", m_pszStyleString, pszPart));
     484           0 :         CPLFree(m_pszStyleString);
     485           0 :         m_pszStyleString = pszTmp;
     486             :     }
     487             :     else
     488             :     {
     489           0 :         char *pszTmp = CPLStrdup(CPLString().Printf("%s", pszPart));
     490           0 :         CPLFree(m_pszStyleString);
     491           0 :         m_pszStyleString = pszTmp;
     492             :     }
     493           0 :     return TRUE;
     494             : }
     495             : 
     496             : /****************************************************************************/
     497             : /*            GBool OGRStyleMgr::AddPart(OGRStyleTool *)                    */
     498             : /*            Add a new part in the current style                           */
     499             : /****************************************************************************/
     500             : 
     501             : /**
     502             :  * \brief Add a part (style tool) to the current style.
     503             :  *
     504             :  * This method is the same as the C function OGR_SM_AddPart().
     505             :  *
     506             :  * @param poStyleTool the style tool defining the part to add.
     507             :  *
     508             :  * @return TRUE on success, FALSE on errors.
     509             :  */
     510             : 
     511         343 : GBool OGRStyleMgr::AddPart(OGRStyleTool *poStyleTool)
     512             : {
     513         343 :     if (poStyleTool == nullptr || !poStyleTool->GetStyleString())
     514           0 :         return FALSE;
     515             : 
     516         343 :     if (m_pszStyleString)
     517             :     {
     518         200 :         char *pszTmp = CPLStrdup(CPLString().Printf(
     519         100 :             "%s;%s", m_pszStyleString, poStyleTool->GetStyleString()));
     520         100 :         CPLFree(m_pszStyleString);
     521         100 :         m_pszStyleString = pszTmp;
     522             :     }
     523             :     else
     524             :     {
     525             :         char *pszTmp =
     526         243 :             CPLStrdup(CPLString().Printf("%s", poStyleTool->GetStyleString()));
     527         243 :         CPLFree(m_pszStyleString);
     528         243 :         m_pszStyleString = pszTmp;
     529             :     }
     530         343 :     return TRUE;
     531             : }
     532             : 
     533             : /************************************************************************/
     534             : /*                     OGR_SM_AddPart()                                 */
     535             : /************************************************************************/
     536             : 
     537             : /**
     538             :  * \brief Add a part (style tool) to the current style.
     539             :  *
     540             :  * This function is the same as the C++ method OGRStyleMgr::AddPart().
     541             :  *
     542             :  * @param hSM handle to the style manager.
     543             :  * @param hST the style tool defining the part to add.
     544             :  *
     545             :  * @return TRUE on success, FALSE on errors.
     546             :  */
     547             : 
     548           0 : int OGR_SM_AddPart(OGRStyleMgrH hSM, OGRStyleToolH hST)
     549             : 
     550             : {
     551           0 :     VALIDATE_POINTER1(hSM, "OGR_SM_InitStyleString", FALSE);
     552           0 :     VALIDATE_POINTER1(hST, "OGR_SM_InitStyleString", FALSE);
     553             : 
     554           0 :     return reinterpret_cast<OGRStyleMgr *>(hSM)->AddPart(
     555           0 :         reinterpret_cast<OGRStyleTool *>(hST));
     556             : }
     557             : 
     558             : /****************************************************************************/
     559             : /*            int OGRStyleMgr::GetPartCount(const char *pszStyleString)     */
     560             : /*            return the number of part in the stylestring                  */
     561             : /* FIXME: this function should actually parse style string instead of simple*/
     562             : /*        semicolon counting, we should not count broken and empty parts.   */
     563             : /****************************************************************************/
     564             : 
     565             : /**
     566             :  * \brief Get the number of parts in a style.
     567             :  *
     568             :  * This method is the same as the C function OGR_SM_GetPartCount().
     569             :  *
     570             :  * @param pszStyleString (optional) the style string on which to operate.
     571             :  * If NULL then the current style string stored in the style manager is used.
     572             :  *
     573             :  * @return the number of parts (style tools) in the style.
     574             :  */
     575             : 
     576         796 : int OGRStyleMgr::GetPartCount(const char *pszStyleString)
     577             : {
     578         796 :     const char *pszString =
     579         796 :         pszStyleString != nullptr ? pszStyleString : m_pszStyleString;
     580             : 
     581         796 :     if (pszString == nullptr)
     582         213 :         return 0;
     583             : 
     584         583 :     int nPartCount = 1;
     585         583 :     const char *pszStrTmp = pszString;
     586             :     // Search for parts separated by semicolons not counting the possible
     587             :     // semicolon at the and of string.
     588         583 :     const char *pszPart = nullptr;
     589         668 :     while ((pszPart = strstr(pszStrTmp, ";")) != nullptr && pszPart[1] != '\0')
     590             :     {
     591          85 :         pszStrTmp = &pszPart[1];
     592          85 :         nPartCount++;
     593             :     }
     594         583 :     return nPartCount;
     595             : }
     596             : 
     597             : /************************************************************************/
     598             : /*                     OGR_SM_GetPartCount()                            */
     599             : /************************************************************************/
     600             : 
     601             : /**
     602             :  * \brief Get the number of parts in a style.
     603             :  *
     604             :  * This function is the same as the C++ method OGRStyleMgr::GetPartCount().
     605             :  *
     606             :  * @param hSM handle to the style manager.
     607             :  * @param pszStyleString (optional) the style string on which to operate.
     608             :  * If NULL then the current style string stored in the style manager is used.
     609             :  *
     610             :  * @return the number of parts (style tools) in the style.
     611             :  */
     612             : 
     613         127 : int OGR_SM_GetPartCount(OGRStyleMgrH hSM, const char *pszStyleString)
     614             : 
     615             : {
     616         127 :     VALIDATE_POINTER1(hSM, "OGR_SM_InitStyleString", FALSE);
     617             : 
     618         127 :     return reinterpret_cast<OGRStyleMgr *>(hSM)->GetPartCount(pszStyleString);
     619             : }
     620             : 
     621             : /****************************************************************************/
     622             : /*            OGRStyleTool *OGRStyleMgr::GetPart(int nPartId,               */
     623             : /*                                 const char *pszStyleString)              */
     624             : /*                                                                          */
     625             : /*     Return a StyleTool of the type of the wanted part, could return NULL */
     626             : /****************************************************************************/
     627             : 
     628             : /**
     629             :  * \brief Fetch a part (style tool) from the current style.
     630             :  *
     631             :  * This method is the same as the C function OGR_SM_GetPart().
     632             :  *
     633             :  * This method instantiates a new object that should be freed with
     634             :  * OGR_ST_Destroy().
     635             :  *
     636             :  * @param nPartId the part number (0-based index).
     637             :  * @param pszStyleString (optional) the style string on which to operate.
     638             :  * If NULL then the current style string stored in the style manager is used.
     639             :  *
     640             :  * @return OGRStyleTool of the requested part (style tools) or NULL on error.
     641             :  */
     642             : 
     643         499 : OGRStyleTool *OGRStyleMgr::GetPart(int nPartId, const char *pszStyleString)
     644             : {
     645         499 :     const char *pszStyle = pszStyleString ? pszStyleString : m_pszStyleString;
     646             : 
     647         499 :     if (pszStyle == nullptr)
     648           1 :         return nullptr;
     649             : 
     650         498 :     char **papszStyleString = CSLTokenizeString2(
     651             :         pszStyle, ";",
     652             :         CSLT_HONOURSTRINGS | CSLT_PRESERVEQUOTES | CSLT_PRESERVEESCAPES);
     653             : 
     654         498 :     const char *pszString = CSLGetField(papszStyleString, nPartId);
     655             : 
     656         498 :     OGRStyleTool *poStyleTool = nullptr;
     657         498 :     if (strlen(pszString) > 0)
     658             :     {
     659         497 :         poStyleTool = CreateStyleToolFromStyleString(pszString);
     660         497 :         if (poStyleTool)
     661         497 :             poStyleTool->SetStyleString(pszString);
     662             :     }
     663             : 
     664         498 :     CSLDestroy(papszStyleString);
     665             : 
     666         498 :     return poStyleTool;
     667             : }
     668             : 
     669             : /************************************************************************/
     670             : /*                     OGR_SM_GetPart()                                 */
     671             : /************************************************************************/
     672             : 
     673             : /**
     674             :  * \brief Fetch a part (style tool) from the current style.
     675             :  *
     676             :  * This function is the same as the C++ method OGRStyleMgr::GetPart().
     677             :  *
     678             :  * This function instantiates a new object that should be freed with
     679             :  * OGR_ST_Destroy().
     680             :  *
     681             :  * @param hSM handle to the style manager.
     682             :  * @param nPartId the part number (0-based index).
     683             :  * @param pszStyleString (optional) the style string on which to operate.
     684             :  * If NULL then the current style string stored in the style manager is used.
     685             :  *
     686             :  * @return OGRStyleToolH of the requested part (style tools) or NULL on error.
     687             :  */
     688             : 
     689          66 : OGRStyleToolH OGR_SM_GetPart(OGRStyleMgrH hSM, int nPartId,
     690             :                              const char *pszStyleString)
     691             : 
     692             : {
     693          66 :     VALIDATE_POINTER1(hSM, "OGR_SM_InitStyleString", nullptr);
     694             : 
     695             :     return reinterpret_cast<OGRStyleToolH>(
     696          66 :         reinterpret_cast<OGRStyleMgr *>(hSM)->GetPart(nPartId, pszStyleString));
     697             : }
     698             : 
     699             : /****************************************************************************/
     700             : /* OGRStyleTool *CreateStyleToolFromStyleString(const char *pszStyleString) */
     701             : /*                                                                          */
     702             : /* create a Style tool from the given StyleString, it should contain only a */
     703             : /* part of a StyleString.                                                    */
     704             : /****************************************************************************/
     705             : 
     706             : //! @cond Doxygen_Suppress
     707             : OGRStyleTool *
     708         497 : OGRStyleMgr::CreateStyleToolFromStyleString(const char *pszStyleString)
     709             : {
     710         497 :     char **papszToken = CSLTokenizeString2(
     711             :         pszStyleString, "();",
     712             :         CSLT_HONOURSTRINGS | CSLT_PRESERVEQUOTES | CSLT_PRESERVEESCAPES);
     713         497 :     OGRStyleTool *poStyleTool = nullptr;
     714             : 
     715         497 :     if (CSLCount(papszToken) < 2)
     716           0 :         poStyleTool = nullptr;
     717         497 :     else if (EQUAL(papszToken[0], "PEN"))
     718         142 :         poStyleTool = new OGRStylePen();
     719         355 :     else if (EQUAL(papszToken[0], "BRUSH"))
     720          56 :         poStyleTool = new OGRStyleBrush();
     721         299 :     else if (EQUAL(papszToken[0], "SYMBOL"))
     722         280 :         poStyleTool = new OGRStyleSymbol();
     723          19 :     else if (EQUAL(papszToken[0], "LABEL"))
     724          19 :         poStyleTool = new OGRStyleLabel();
     725             :     else
     726           0 :         poStyleTool = nullptr;
     727             : 
     728         497 :     CSLDestroy(papszToken);
     729             : 
     730         497 :     return poStyleTool;
     731             : }
     732             : 
     733             : //! @endcond
     734             : 
     735             : /* ======================================================================== */
     736             : /*                OGRStyleTable                                             */
     737             : /*     Object Used to manage and store a styletable                         */
     738             : /* ======================================================================== */
     739             : 
     740             : /****************************************************************************/
     741             : /*              OGRStyleTable::OGRStyleTable()                              */
     742             : /*                                                                          */
     743             : /****************************************************************************/
     744          39 : OGRStyleTable::OGRStyleTable()
     745             : {
     746          39 :     m_papszStyleTable = nullptr;
     747          39 :     iNextStyle = 0;
     748          39 : }
     749             : 
     750             : /************************************************************************/
     751             : /*                            OGR_STBL_Create()                           */
     752             : /************************************************************************/
     753             : /**
     754             :  * \brief OGRStyleTable factory.
     755             :  *
     756             :  * This function is the same as the C++ method OGRStyleTable::OGRStyleTable().
     757             :  *
     758             :  *
     759             :  * @return a handle to the new style table object.
     760             :  */
     761             : 
     762           5 : OGRStyleTableH OGR_STBL_Create(void)
     763             : 
     764             : {
     765           5 :     return reinterpret_cast<OGRStyleTableH>(new OGRStyleTable());
     766             : }
     767             : 
     768             : /****************************************************************************/
     769             : /*                void OGRStyleTable::Clear()                               */
     770             : /*                                                                          */
     771             : /****************************************************************************/
     772             : 
     773             : /**
     774             :  * \brief Clear a style table.
     775             :  *
     776             :  */
     777             : 
     778          39 : void OGRStyleTable::Clear()
     779             : {
     780          39 :     if (m_papszStyleTable)
     781          39 :         CSLDestroy(m_papszStyleTable);
     782          39 :     m_papszStyleTable = nullptr;
     783          39 : }
     784             : 
     785             : /****************************************************************************/
     786             : /*          OGRStyleTable::~OGRStyleTable()                                 */
     787             : /*                                                                          */
     788             : /****************************************************************************/
     789          39 : OGRStyleTable::~OGRStyleTable()
     790             : {
     791          39 :     Clear();
     792          39 : }
     793             : 
     794             : /************************************************************************/
     795             : /*                           OGR_STBL_Destroy()                            */
     796             : /************************************************************************/
     797             : /**
     798             :  * \brief Destroy Style Table
     799             :  *
     800             :  * @param hSTBL handle to the style table to destroy.
     801             :  */
     802             : 
     803           5 : void OGR_STBL_Destroy(OGRStyleTableH hSTBL)
     804             : 
     805             : {
     806           5 :     delete reinterpret_cast<OGRStyleTable *>(hSTBL);
     807           5 : }
     808             : 
     809             : /****************************************************************************/
     810             : /*    const char *OGRStyleTable::GetStyleName(const char *pszStyleString)   */
     811             : /*                                                                          */
     812             : /*    return the Name of a given stylestring otherwise NULL.                */
     813             : /****************************************************************************/
     814             : 
     815             : /**
     816             :  * \brief Get style name by style string.
     817             :  *
     818             :  * @param pszStyleString the style string to look up.
     819             :  *
     820             :  * @return the Name of the matching style string or NULL on error.
     821             :  */
     822             : 
     823           0 : const char *OGRStyleTable::GetStyleName(const char *pszStyleString)
     824             : {
     825           0 :     for (int i = 0; i < CSLCount(m_papszStyleTable); i++)
     826             :     {
     827           0 :         const char *pszStyleStringBegin = strstr(m_papszStyleTable[i], ":");
     828             : 
     829           0 :         if (pszStyleStringBegin &&
     830           0 :             EQUAL(&pszStyleStringBegin[1], pszStyleString))
     831             :         {
     832           0 :             osLastRequestedStyleName = m_papszStyleTable[i];
     833           0 :             const size_t nColon = osLastRequestedStyleName.find(':');
     834           0 :             if (nColon != std::string::npos)
     835             :                 osLastRequestedStyleName =
     836           0 :                     osLastRequestedStyleName.substr(0, nColon);
     837             : 
     838           0 :             return osLastRequestedStyleName;
     839             :         }
     840             :     }
     841             : 
     842           0 :     return nullptr;
     843             : }
     844             : 
     845             : /****************************************************************************/
     846             : /*            GBool OGRStyleTable::AddStyle(char *pszName,                  */
     847             : /*                                          char *pszStyleString)           */
     848             : /*                                                                          */
     849             : /*   Add a new style in the table, no comparison will be done on the        */
     850             : /*   Style string, only on the name, TRUE success, FALSE error              */
     851             : /****************************************************************************/
     852             : 
     853             : /**
     854             :  * \brief Add a new style in the table.
     855             :  * No comparison will be done on the
     856             :  * Style string, only on the name.
     857             :  *
     858             :  * @param pszName the name the style to add.
     859             :  * @param pszStyleString the style string to add.
     860             :  *
     861             :  * @return TRUE on success, FALSE on error
     862             :  */
     863             : 
     864         177 : GBool OGRStyleTable::AddStyle(const char *pszName, const char *pszStyleString)
     865             : {
     866         177 :     if (pszName == nullptr || pszStyleString == nullptr)
     867          10 :         return FALSE;
     868             : 
     869         167 :     const int nPos = IsExist(pszName);
     870         167 :     if (nPos != -1)
     871           0 :         return FALSE;
     872             : 
     873         167 :     m_papszStyleTable =
     874         167 :         CSLAddString(m_papszStyleTable,
     875         334 :                      CPLString().Printf("%s:%s", pszName, pszStyleString));
     876         167 :     return TRUE;
     877             : }
     878             : 
     879             : /************************************************************************/
     880             : /*                       OGR_STBL_AddStyle()                            */
     881             : /************************************************************************/
     882             : 
     883             : /**
     884             :  * \brief Add a new style in the table.
     885             :  * No comparison will be done on the
     886             :  * Style string, only on the name.
     887             :  * This function is the same as the C++ method OGRStyleTable::AddStyle().
     888             :  *
     889             :  * @param hStyleTable handle to the style table.
     890             :  * @param pszName the name the style to add.
     891             :  * @param pszStyleString the style string to add.
     892             :  *
     893             :  * @return TRUE on success, FALSE on error
     894             :  */
     895             : 
     896           6 : int OGR_STBL_AddStyle(OGRStyleTableH hStyleTable, const char *pszName,
     897             :                       const char *pszStyleString)
     898             : {
     899           6 :     VALIDATE_POINTER1(hStyleTable, "OGR_STBL_AddStyle", FALSE);
     900             : 
     901             :     return reinterpret_cast<OGRStyleTable *>(hStyleTable)
     902           6 :         ->AddStyle(pszName, pszStyleString);
     903             : }
     904             : 
     905             : /****************************************************************************/
     906             : /*            GBool OGRStyleTable::RemoveStyle(char *pszName)               */
     907             : /*                                                                          */
     908             : /*    Remove the given style in the table based on the name, return TRUE    */
     909             : /*    on success otherwise FALSE.                                           */
     910             : /****************************************************************************/
     911             : 
     912             : /**
     913             :  * \brief Remove a style in the table by its name.
     914             :  *
     915             :  * @param pszName the name of the style to remove.
     916             :  *
     917             :  * @return TRUE on success, FALSE on error
     918             :  */
     919             : 
     920           1 : GBool OGRStyleTable::RemoveStyle(const char *pszName)
     921             : {
     922           1 :     const int nPos = IsExist(pszName);
     923           1 :     if (nPos == -1)
     924           0 :         return FALSE;
     925             : 
     926           1 :     m_papszStyleTable = CSLRemoveStrings(m_papszStyleTable, nPos, 1, nullptr);
     927           1 :     return TRUE;
     928             : }
     929             : 
     930             : /****************************************************************************/
     931             : /*            GBool OGRStyleTable::ModifyStyle(char *pszName,               */
     932             : /*                                             char *pszStyleString)        */
     933             : /*                                                                          */
     934             : /*    Modify the given style, if the style doesn't exist, it will be added  */
     935             : /*    return TRUE on success otherwise return FALSE.                        */
     936             : /****************************************************************************/
     937             : 
     938             : /**
     939             :  * \brief Modify a style in the table by its name
     940             :  * If the style does not exist, it will be added.
     941             :  *
     942             :  * @param pszName the name of the style to modify.
     943             :  * @param pszStyleString the style string.
     944             :  *
     945             :  * @return TRUE on success, FALSE on error
     946             :  */
     947             : 
     948           0 : GBool OGRStyleTable::ModifyStyle(const char *pszName,
     949             :                                  const char *pszStyleString)
     950             : {
     951           0 :     if (pszName == nullptr || pszStyleString == nullptr)
     952           0 :         return FALSE;
     953             : 
     954           0 :     RemoveStyle(pszName);
     955           0 :     return AddStyle(pszName, pszStyleString);
     956             : }
     957             : 
     958             : /****************************************************************************/
     959             : /*            GBool OGRStyleTable::SaveStyleTable(char *)                   */
     960             : /*                                                                          */
     961             : /*    Save the StyleTable in the given file, return TRUE on success         */
     962             : /*    otherwise return FALSE.                                               */
     963             : /****************************************************************************/
     964             : 
     965             : /**
     966             :  * \brief Save a style table to a file.
     967             :  *
     968             :  * @param pszFilename the name of the file to save to.
     969             :  *
     970             :  * @return TRUE on success, FALSE on error
     971             :  */
     972             : 
     973           2 : GBool OGRStyleTable::SaveStyleTable(const char *pszFilename)
     974             : {
     975           2 :     if (pszFilename == nullptr)
     976           0 :         return FALSE;
     977             : 
     978           2 :     if (CSLSave(m_papszStyleTable, pszFilename) == 0)
     979           1 :         return FALSE;
     980             : 
     981           1 :     return TRUE;
     982             : }
     983             : 
     984             : /************************************************************************/
     985             : /*                     OGR_STBL_SaveStyleTable()                        */
     986             : /************************************************************************/
     987             : 
     988             : /**
     989             :  * \brief Save a style table to a file.
     990             :  *
     991             :  * This function is the same as the C++ method OGRStyleTable::SaveStyleTable().
     992             :  *
     993             :  * @param hStyleTable handle to the style table.
     994             :  * @param pszFilename the name of the file to save to.
     995             :  *
     996             :  * @return TRUE on success, FALSE on error
     997             :  */
     998             : 
     999           2 : int OGR_STBL_SaveStyleTable(OGRStyleTableH hStyleTable, const char *pszFilename)
    1000             : {
    1001           2 :     VALIDATE_POINTER1(hStyleTable, "OGR_STBL_SaveStyleTable", FALSE);
    1002           2 :     VALIDATE_POINTER1(pszFilename, "OGR_STBL_SaveStyleTable", FALSE);
    1003             : 
    1004             :     return reinterpret_cast<OGRStyleTable *>(hStyleTable)
    1005           2 :         ->SaveStyleTable(pszFilename);
    1006             : }
    1007             : 
    1008             : /****************************************************************************/
    1009             : /*            GBool OGRStyleTable::LoadStyleTable(char *)                   */
    1010             : /*                                                                          */
    1011             : /*            Read the Style table from a file, return TRUE on success      */
    1012             : /*            otherwise return FALSE                                        */
    1013             : /****************************************************************************/
    1014             : 
    1015             : /**
    1016             :  * \brief Load a style table from a file.
    1017             :  *
    1018             :  * @param pszFilename the name of the file to load from.
    1019             :  *
    1020             :  * @return TRUE on success, FALSE on error
    1021             :  */
    1022             : 
    1023           2 : GBool OGRStyleTable::LoadStyleTable(const char *pszFilename)
    1024             : {
    1025           2 :     if (pszFilename == nullptr)
    1026           0 :         return FALSE;
    1027             : 
    1028           2 :     CSLDestroy(m_papszStyleTable);
    1029             : 
    1030           2 :     m_papszStyleTable = CSLLoad(pszFilename);
    1031             : 
    1032           2 :     return m_papszStyleTable != nullptr;
    1033             : }
    1034             : 
    1035             : /************************************************************************/
    1036             : /*                     OGR_STBL_LoadStyleTable()                        */
    1037             : /************************************************************************/
    1038             : 
    1039             : /**
    1040             :  * \brief Load a style table from a file.
    1041             :  *
    1042             :  * This function is the same as the C++ method OGRStyleTable::LoadStyleTable().
    1043             :  *
    1044             :  * @param hStyleTable handle to the style table.
    1045             :  * @param pszFilename the name of the file to load from.
    1046             :  *
    1047             :  * @return TRUE on success, FALSE on error
    1048             :  */
    1049             : 
    1050           2 : int OGR_STBL_LoadStyleTable(OGRStyleTableH hStyleTable, const char *pszFilename)
    1051             : {
    1052           2 :     VALIDATE_POINTER1(hStyleTable, "OGR_STBL_LoadStyleTable", FALSE);
    1053           2 :     VALIDATE_POINTER1(pszFilename, "OGR_STBL_LoadStyleTable", FALSE);
    1054             : 
    1055             :     return reinterpret_cast<OGRStyleTable *>(hStyleTable)
    1056           2 :         ->LoadStyleTable(pszFilename);
    1057             : }
    1058             : 
    1059             : /****************************************************************************/
    1060             : /*             const char *OGRStyleTable::Find(const char *pszName)         */
    1061             : /*                                                                          */
    1062             : /*             return the StyleString based on the given name,              */
    1063             : /*             otherwise return NULL.                                       */
    1064             : /****************************************************************************/
    1065             : 
    1066             : /**
    1067             :  * \brief Get a style string by name.
    1068             :  *
    1069             :  * @param pszName the name of the style string to find.
    1070             :  *
    1071             :  * @return the style string matching the name, NULL if not found or error.
    1072             :  */
    1073             : 
    1074          68 : const char *OGRStyleTable::Find(const char *pszName)
    1075             : {
    1076          68 :     const int nPos = IsExist(pszName);
    1077          68 :     if (nPos == -1)
    1078           4 :         return nullptr;
    1079             : 
    1080          64 :     const char *pszOutput = CSLGetField(m_papszStyleTable, nPos);
    1081             : 
    1082          64 :     const char *pszDash = strstr(pszOutput, ":");
    1083             : 
    1084          64 :     if (pszDash == nullptr)
    1085           0 :         return nullptr;
    1086             : 
    1087          64 :     return &pszDash[1];
    1088             : }
    1089             : 
    1090             : /************************************************************************/
    1091             : /*                     OGR_STBL_Find()                                  */
    1092             : /************************************************************************/
    1093             : 
    1094             : /**
    1095             :  * \brief Get a style string by name.
    1096             :  *
    1097             :  * This function is the same as the C++ method OGRStyleTable::Find().
    1098             :  *
    1099             :  * @param hStyleTable handle to the style table.
    1100             :  * @param pszName the name of the style string to find.
    1101             :  *
    1102             :  * @return the style string matching the name or NULL if not found or error.
    1103             :  */
    1104             : 
    1105           2 : const char *OGR_STBL_Find(OGRStyleTableH hStyleTable, const char *pszName)
    1106             : {
    1107           2 :     VALIDATE_POINTER1(hStyleTable, "OGR_STBL_Find", nullptr);
    1108           2 :     VALIDATE_POINTER1(pszName, "OGR_STBL_Find", nullptr);
    1109             : 
    1110           2 :     return reinterpret_cast<OGRStyleTable *>(hStyleTable)->Find(pszName);
    1111             : }
    1112             : 
    1113             : /****************************************************************************/
    1114             : /*              OGRStyleTable::Print(FILE *fpOut)                           */
    1115             : /*                                                                          */
    1116             : /****************************************************************************/
    1117             : 
    1118             : /**
    1119             :  * \brief Print a style table to a FILE pointer.
    1120             :  *
    1121             :  * @param fpOut the FILE pointer to print to.
    1122             :  *
    1123             :  */
    1124             : 
    1125           0 : void OGRStyleTable::Print(FILE *fpOut)
    1126             : {
    1127             : 
    1128           0 :     CPL_IGNORE_RET_VAL(VSIFPrintf(fpOut, "#OFS-Version: 1.0\n"));
    1129           0 :     CPL_IGNORE_RET_VAL(VSIFPrintf(fpOut, "#StyleField: style\n"));
    1130           0 :     if (m_papszStyleTable)
    1131             :     {
    1132           0 :         CSLPrint(m_papszStyleTable, fpOut);
    1133             :     }
    1134           0 : }
    1135             : 
    1136             : /****************************************************************************/
    1137             : /*             int OGRStyleTable::IsExist(const char *pszName)              */
    1138             : /*                                                                          */
    1139             : /*   return a index of the style in the table otherwise return -1           */
    1140             : /****************************************************************************/
    1141             : 
    1142             : /**
    1143             :  * \brief Get the index of a style in the table by its name.
    1144             :  *
    1145             :  * @param pszName the name to look for.
    1146             :  *
    1147             :  * @return The index of the style if found, -1 if not found or error.
    1148             :  */
    1149             : 
    1150         236 : int OGRStyleTable::IsExist(const char *pszName)
    1151             : {
    1152         236 :     if (pszName == nullptr)
    1153           0 :         return -1;
    1154             : 
    1155         236 :     const int nCount = CSLCount(m_papszStyleTable);
    1156         236 :     const char *pszNewString = CPLSPrintf("%s:", pszName);
    1157             : 
    1158         948 :     for (int i = 0; i < nCount; i++)
    1159             :     {
    1160         777 :         if (strstr(m_papszStyleTable[i], pszNewString) != nullptr)
    1161             :         {
    1162          65 :             return i;
    1163             :         }
    1164             :     }
    1165             : 
    1166         171 :     return -1;
    1167             : }
    1168             : 
    1169             : /************************************************************************/
    1170             : /*                               Clone()                                */
    1171             : /************************************************************************/
    1172             : 
    1173             : /**
    1174             :  * \brief Duplicate style table.
    1175             :  *
    1176             :  * The newly created style table is owned by the caller, and will have its
    1177             :  * own reference to the OGRStyleTable.
    1178             :  *
    1179             :  * @return new style table, exactly matching this style table.
    1180             :  */
    1181             : 
    1182           6 : OGRStyleTable *OGRStyleTable::Clone()
    1183             : 
    1184             : {
    1185           6 :     OGRStyleTable *poNew = new OGRStyleTable();
    1186             : 
    1187           6 :     poNew->m_papszStyleTable = CSLDuplicate(m_papszStyleTable);
    1188             : 
    1189           6 :     return poNew;
    1190             : }
    1191             : 
    1192             : /************************************************************************/
    1193             : /*                            ResetStyleStringReading()                 */
    1194             : /************************************************************************/
    1195             : 
    1196             : /** Reset the next style pointer to 0 */
    1197           9 : void OGRStyleTable::ResetStyleStringReading()
    1198             : 
    1199             : {
    1200           9 :     iNextStyle = 0;
    1201           9 : }
    1202             : 
    1203             : /************************************************************************/
    1204             : /*                     OGR_STBL_ResetStyleStringReading()               */
    1205             : /************************************************************************/
    1206             : 
    1207             : /**
    1208             :  * \brief Reset the next style pointer to 0
    1209             :  *
    1210             :  * This function is the same as the C++ method
    1211             :  * OGRStyleTable::ResetStyleStringReading().
    1212             :  *
    1213             :  * @param hStyleTable handle to the style table.
    1214             :  *
    1215             :  */
    1216             : 
    1217           1 : void OGR_STBL_ResetStyleStringReading(OGRStyleTableH hStyleTable)
    1218             : {
    1219           1 :     VALIDATE_POINTER0(hStyleTable, "OGR_STBL_ResetStyleStringReading");
    1220             : 
    1221           1 :     reinterpret_cast<OGRStyleTable *>(hStyleTable)->ResetStyleStringReading();
    1222             : }
    1223             : 
    1224             : /************************************************************************/
    1225             : /*                           GetNextStyle()                             */
    1226             : /************************************************************************/
    1227             : 
    1228             : /**
    1229             :  * \brief Get the next style string from the table.
    1230             :  *
    1231             :  * @return the next style string or NULL on error.
    1232             :  */
    1233             : 
    1234          33 : const char *OGRStyleTable::GetNextStyle()
    1235             : {
    1236          33 :     while (iNextStyle < CSLCount(m_papszStyleTable))
    1237             :     {
    1238          24 :         const char *pszOutput = CSLGetField(m_papszStyleTable, iNextStyle++);
    1239          24 :         if (pszOutput == nullptr)
    1240           0 :             continue;
    1241             : 
    1242          24 :         const char *pszDash = strstr(pszOutput, ":");
    1243             : 
    1244          24 :         osLastRequestedStyleName = pszOutput;
    1245          24 :         const size_t nColon = osLastRequestedStyleName.find(':');
    1246          24 :         if (nColon != std::string::npos)
    1247             :             osLastRequestedStyleName =
    1248          24 :                 osLastRequestedStyleName.substr(0, nColon);
    1249             : 
    1250          24 :         if (pszDash)
    1251          24 :             return pszDash + 1;
    1252             :     }
    1253           9 :     return nullptr;
    1254             : }
    1255             : 
    1256             : /************************************************************************/
    1257             : /*                     OGR_STBL_GetNextStyle()                          */
    1258             : /************************************************************************/
    1259             : 
    1260             : /**
    1261             :  * \brief Get the next style string from the table.
    1262             :  *
    1263             :  * This function is the same as the C++ method OGRStyleTable::GetNextStyle().
    1264             :  *
    1265             :  * @param hStyleTable handle to the style table.
    1266             :  *
    1267             :  * @return the next style string or NULL on error.
    1268             :  */
    1269             : 
    1270           5 : const char *OGR_STBL_GetNextStyle(OGRStyleTableH hStyleTable)
    1271             : {
    1272           5 :     VALIDATE_POINTER1(hStyleTable, "OGR_STBL_GetNextStyle", nullptr);
    1273             : 
    1274           5 :     return reinterpret_cast<OGRStyleTable *>(hStyleTable)->GetNextStyle();
    1275             : }
    1276             : 
    1277             : /************************************************************************/
    1278             : /*                           GetLastStyleName()                         */
    1279             : /************************************************************************/
    1280             : 
    1281             : /**
    1282             :  * Get the style name of the last style string fetched with
    1283             :  * OGR_STBL_GetNextStyle.
    1284             :  *
    1285             :  * @return the Name of the last style string or NULL on error.
    1286             :  */
    1287             : 
    1288          21 : const char *OGRStyleTable::GetLastStyleName()
    1289             : {
    1290          21 :     return osLastRequestedStyleName;
    1291             : }
    1292             : 
    1293             : /************************************************************************/
    1294             : /*                     OGR_STBL_GetLastStyleName()                      */
    1295             : /************************************************************************/
    1296             : 
    1297             : /**
    1298             :  * Get the style name of the last style string fetched with
    1299             :  * OGR_STBL_GetNextStyle.
    1300             :  *
    1301             :  * This function is the same as the C++ method OGRStyleTable::GetStyleName().
    1302             :  *
    1303             :  * @param hStyleTable handle to the style table.
    1304             :  *
    1305             :  * @return the Name of the last style string or NULL on error.
    1306             :  */
    1307             : 
    1308           1 : const char *OGR_STBL_GetLastStyleName(OGRStyleTableH hStyleTable)
    1309             : {
    1310           1 :     VALIDATE_POINTER1(hStyleTable, "OGR_STBL_GetLastStyleName", nullptr);
    1311             : 
    1312           1 :     return reinterpret_cast<OGRStyleTable *>(hStyleTable)->GetLastStyleName();
    1313             : }
    1314             : 
    1315             : /****************************************************************************/
    1316             : /*                          OGRStyleTool::OGRStyleTool()                    */
    1317             : /*                                                                          */
    1318             : /****************************************************************************/
    1319             : 
    1320             : /** Constructor */
    1321         750 : OGRStyleTool::OGRStyleTool(OGRSTClassId eClassId) : m_eClassId(eClassId)
    1322             : {
    1323         750 : }
    1324             : 
    1325             : /************************************************************************/
    1326             : /*                            OGR_ST_Create()                           */
    1327             : /************************************************************************/
    1328             : /**
    1329             :  * \brief OGRStyleTool factory.
    1330             :  *
    1331             :  * This function is a constructor for OGRStyleTool derived classes.
    1332             :  *
    1333             :  * @param eClassId subclass of style tool to create. One of OGRSTCPen (1),
    1334             :  * OGRSTCBrush (2), OGRSTCSymbol (3) or OGRSTCLabel (4).
    1335             :  *
    1336             :  * @return a handle to the new style tool object or NULL if the creation
    1337             :  * failed.
    1338             :  */
    1339             : 
    1340           0 : OGRStyleToolH OGR_ST_Create(OGRSTClassId eClassId)
    1341             : 
    1342             : {
    1343           0 :     switch (eClassId)
    1344             :     {
    1345           0 :         case OGRSTCPen:
    1346           0 :             return reinterpret_cast<OGRStyleToolH>(new OGRStylePen());
    1347           0 :         case OGRSTCBrush:
    1348           0 :             return reinterpret_cast<OGRStyleToolH>(new OGRStyleBrush());
    1349           0 :         case OGRSTCSymbol:
    1350           0 :             return reinterpret_cast<OGRStyleToolH>(new OGRStyleSymbol());
    1351           0 :         case OGRSTCLabel:
    1352           0 :             return reinterpret_cast<OGRStyleToolH>(new OGRStyleLabel());
    1353           0 :         default:
    1354           0 :             return nullptr;
    1355             :     }
    1356             : }
    1357             : 
    1358             : /****************************************************************************/
    1359             : /*                       OGRStyleTool::~OGRStyleTool()                      */
    1360             : /*                                                                          */
    1361             : /****************************************************************************/
    1362        1500 : OGRStyleTool::~OGRStyleTool()
    1363             : {
    1364         750 :     CPLFree(m_pszStyleString);
    1365         750 : }
    1366             : 
    1367             : /************************************************************************/
    1368             : /*                           OGR_ST_Destroy()                            */
    1369             : /************************************************************************/
    1370             : /**
    1371             :  * \brief Destroy Style Tool
    1372             :  *
    1373             :  * @param hST handle to the style tool to destroy.
    1374             :  */
    1375             : 
    1376          65 : void OGR_ST_Destroy(OGRStyleToolH hST)
    1377             : 
    1378             : {
    1379          65 :     delete reinterpret_cast<OGRStyleTool *>(hST);
    1380          65 : }
    1381             : 
    1382             : /****************************************************************************/
    1383             : /*      void OGRStyleTool::SetStyleString(const char *pszStyleString)       */
    1384             : /*                                                                          */
    1385             : /****************************************************************************/
    1386             : 
    1387             : /** Undocumented
    1388             :  * @param pszStyleString undocumented.
    1389             :  */
    1390         497 : void OGRStyleTool::SetStyleString(const char *pszStyleString)
    1391             : {
    1392         497 :     m_pszStyleString = CPLStrdup(pszStyleString);
    1393         497 : }
    1394             : 
    1395             : /****************************************************************************/
    1396             : /*const char *OGRStyleTool::GetStyleString( OGRStyleParamId *pasStyleParam, */
    1397             : /*                          OGRStyleValue *pasStyleValue, int nSize)        */
    1398             : /*                                                                          */
    1399             : /****************************************************************************/
    1400             : 
    1401             : /** Undocumented
    1402             :  * @param pasStyleParam undocumented.
    1403             :  * @param pasStyleValue undocumented.
    1404             :  * @param nSize undocumented.
    1405             :  * @return undocumented.
    1406             :  */
    1407         686 : const char *OGRStyleTool::GetStyleString(const OGRStyleParamId *pasStyleParam,
    1408             :                                          OGRStyleValue *pasStyleValue,
    1409             :                                          int nSize)
    1410             : {
    1411         686 :     if (IsStyleModified())
    1412             :     {
    1413         243 :         CPLFree(m_pszStyleString);
    1414             : 
    1415         243 :         const char *pszClass = nullptr;
    1416         243 :         switch (GetType())
    1417             :         {
    1418         103 :             case OGRSTCPen:
    1419         103 :                 pszClass = "PEN(";
    1420         103 :                 break;
    1421          83 :             case OGRSTCBrush:
    1422          83 :                 pszClass = "BRUSH(";
    1423          83 :                 break;
    1424          52 :             case OGRSTCSymbol:
    1425          52 :                 pszClass = "SYMBOL(";
    1426          52 :                 break;
    1427           5 :             case OGRSTCLabel:
    1428           5 :                 pszClass = "LABEL(";
    1429           5 :                 break;
    1430           0 :             default:
    1431           0 :                 pszClass = "UNKNOWN(";
    1432             :         }
    1433             : 
    1434         243 :         CPLString osCurrent = pszClass;
    1435             : 
    1436         243 :         bool bFound = false;
    1437        2460 :         for (int i = 0; i < nSize; i++)
    1438             :         {
    1439        2217 :             if (!pasStyleValue[i].bValid ||
    1440         302 :                 pasStyleParam[i].eType == OGRSTypeUnused)
    1441             :             {
    1442        1915 :                 continue;
    1443             :             }
    1444             : 
    1445         302 :             if (bFound)
    1446          59 :                 osCurrent += ",";
    1447         302 :             bFound = true;
    1448             : 
    1449         302 :             osCurrent += pasStyleParam[i].pszToken;
    1450         302 :             switch (pasStyleParam[i].eType)
    1451             :             {
    1452         204 :                 case OGRSTypeString:
    1453         204 :                     osCurrent += ":";
    1454         204 :                     osCurrent += pasStyleValue[i].pszValue;
    1455         204 :                     break;
    1456          98 :                 case OGRSTypeDouble:
    1457             :                     osCurrent +=
    1458          98 :                         CPLString().Printf(":%f", pasStyleValue[i].dfValue);
    1459          98 :                     break;
    1460           0 :                 case OGRSTypeInteger:
    1461             :                     osCurrent +=
    1462           0 :                         CPLString().Printf(":%d", pasStyleValue[i].nValue);
    1463           0 :                     break;
    1464           0 :                 case OGRSTypeBoolean:
    1465             :                     osCurrent +=
    1466           0 :                         CPLString().Printf(":%d", pasStyleValue[i].nValue != 0);
    1467           0 :                     break;
    1468           0 :                 default:
    1469           0 :                     break;
    1470             :             }
    1471         302 :             if (pasStyleParam[i].bGeoref)
    1472          90 :                 switch (pasStyleValue[i].eUnit)
    1473             :                 {
    1474           0 :                     case OGRSTUGround:
    1475           0 :                         osCurrent += "g";
    1476           0 :                         break;
    1477          83 :                     case OGRSTUPixel:
    1478          83 :                         osCurrent += "px";
    1479          83 :                         break;
    1480           0 :                     case OGRSTUPoints:
    1481           0 :                         osCurrent += "pt";
    1482           0 :                         break;
    1483           0 :                     case OGRSTUCM:
    1484           0 :                         osCurrent += "cm";
    1485           0 :                         break;
    1486           0 :                     case OGRSTUInches:
    1487           0 :                         osCurrent += "in";
    1488           0 :                         break;
    1489           7 :                     case OGRSTUMM:
    1490             :                         // osCurrent += "mm";
    1491             :                     default:
    1492           7 :                         break;  // imp
    1493             :                 }
    1494             :         }
    1495         243 :         osCurrent += ")";
    1496             : 
    1497         243 :         m_pszStyleString = CPLStrdup(osCurrent);
    1498             : 
    1499         243 :         m_bModified = FALSE;
    1500             :     }
    1501             : 
    1502         686 :     return m_pszStyleString;
    1503             : }
    1504             : 
    1505             : /************************************************************************/
    1506             : /*                          GetRGBFromString()                          */
    1507             : /************************************************************************/
    1508             : /**
    1509             :  * \brief Return the r,g,b,a components of a color encoded in \#RRGGBB[AA]
    1510             :  * format.
    1511             :  *
    1512             :  * Maps to OGRStyleTool::GetRGBFromString().
    1513             :  *
    1514             :  * @param pszColor the color to parse
    1515             :  * @param nRed reference to an int in which the red value will be returned.
    1516             :  * @param nGreen reference to an int in which the green value will be returned.
    1517             :  * @param nBlue reference to an int in which the blue value will be returned.
    1518             :  * @param nTransparance reference to an int in which the (optional) alpha value
    1519             :  * will be returned.
    1520             :  *
    1521             :  * @return TRUE if the color could be successfully parsed, or FALSE in case of
    1522             :  * errors.
    1523             :  */
    1524          23 : GBool OGRStyleTool::GetRGBFromString(const char *pszColor, int &nRed,
    1525             :                                      int &nGreen, int &nBlue,
    1526             :                                      int &nTransparance)
    1527             : {
    1528          23 :     int nCount = 0;
    1529             : 
    1530          23 :     nTransparance = 255;
    1531             : 
    1532             :     // FIXME: should we really use sscanf here?
    1533          23 :     unsigned int unRed = 0;
    1534          23 :     unsigned int unGreen = 0;
    1535          23 :     unsigned int unBlue = 0;
    1536          23 :     unsigned int unTransparance = 0;
    1537          23 :     if (pszColor)
    1538          23 :         nCount = sscanf(pszColor, "#%2x%2x%2x%2x", &unRed, &unGreen, &unBlue,
    1539             :                         &unTransparance);
    1540          23 :     nRed = static_cast<int>(unRed);
    1541          23 :     nGreen = static_cast<int>(unGreen);
    1542          23 :     nBlue = static_cast<int>(unBlue);
    1543          23 :     if (nCount == 4)
    1544          18 :         nTransparance = static_cast<int>(unTransparance);
    1545          23 :     return nCount >= 3;
    1546             : }
    1547             : 
    1548             : /************************************************************************/
    1549             : /*                           GetSpecificId()                            */
    1550             : /*                                                                      */
    1551             : /*      return -1, if the wanted type is not found, ex:                 */
    1552             : /*      if you want ogr-pen value, pszWanted should be ogr-pen(case     */
    1553             : /*      sensitive)                                                      */
    1554             : /************************************************************************/
    1555             : 
    1556             : /** Undocumented
    1557             :  * @param pszId Undocumented
    1558             :  * @param pszWanted Undocumented
    1559             :  * @return Undocumented
    1560             :  */
    1561           0 : int OGRStyleTool::GetSpecificId(const char *pszId, const char *pszWanted)
    1562             : {
    1563           0 :     const char *pszRealWanted = pszWanted;
    1564             : 
    1565           0 :     if (pszWanted == nullptr || strlen(pszWanted) == 0)
    1566           0 :         pszRealWanted = "ogr-pen";
    1567             : 
    1568           0 :     if (pszId == nullptr)
    1569           0 :         return -1;
    1570             : 
    1571           0 :     int nValue = -1;
    1572           0 :     const char *pszFound = strstr(pszId, pszRealWanted);
    1573           0 :     if (pszFound != nullptr)
    1574             :     {
    1575             :         // We found the string, it could be no value after it, use default one.
    1576           0 :         nValue = 0;
    1577             : 
    1578           0 :         if (pszFound[strlen(pszRealWanted)] == '-')
    1579           0 :             nValue = atoi(&pszFound[strlen(pszRealWanted) + 1]);
    1580             :     }
    1581             : 
    1582           0 :     return nValue;
    1583             : }
    1584             : 
    1585             : /************************************************************************/
    1586             : /*                              GetType()                               */
    1587             : /************************************************************************/
    1588             : 
    1589             : /**
    1590             :  * \brief Determine type of Style Tool
    1591             :  *
    1592             :  * @return the style tool type, one of OGRSTCPen (1), OGRSTCBrush (2),
    1593             :  * OGRSTCSymbol (3) or OGRSTCLabel (4). Returns OGRSTCNone (0) if the
    1594             :  * OGRStyleToolH is invalid.
    1595             :  */
    1596        1577 : OGRSTClassId OGRStyleTool::GetType()
    1597             : {
    1598        1577 :     return m_eClassId;
    1599             : }
    1600             : 
    1601             : /************************************************************************/
    1602             : /*                           OGR_ST_GetType()                           */
    1603             : /************************************************************************/
    1604             : /**
    1605             :  * \brief Determine type of Style Tool
    1606             :  *
    1607             :  * @param hST handle to the style tool.
    1608             :  *
    1609             :  * @return the style tool type, one of OGRSTCPen (1), OGRSTCBrush (2),
    1610             :  * OGRSTCSymbol (3) or OGRSTCLabel (4). Returns OGRSTCNone (0) if the
    1611             :  * OGRStyleToolH is invalid.
    1612             :  */
    1613             : 
    1614         238 : OGRSTClassId OGR_ST_GetType(OGRStyleToolH hST)
    1615             : 
    1616             : {
    1617         238 :     VALIDATE_POINTER1(hST, "OGR_ST_GetType", OGRSTCNone);
    1618         238 :     return reinterpret_cast<OGRStyleTool *>(hST)->GetType();
    1619             : }
    1620             : 
    1621             : /************************************************************************/
    1622             : /*                           OGR_ST_GetUnit()                           */
    1623             : /************************************************************************/
    1624             : 
    1625             : /**
    1626             :  * \fn OGRStyleTool::GetUnit()
    1627             :  * \brief Get Style Tool units
    1628             :  *
    1629             :  * @return the style tool units.
    1630             :  */
    1631             : 
    1632             : /**
    1633             :  * \brief Get Style Tool units
    1634             :  *
    1635             :  * @param hST handle to the style tool.
    1636             :  *
    1637             :  * @return the style tool units.
    1638             :  */
    1639             : 
    1640           2 : OGRSTUnitId OGR_ST_GetUnit(OGRStyleToolH hST)
    1641             : 
    1642             : {
    1643           2 :     VALIDATE_POINTER1(hST, "OGR_ST_GetUnit", OGRSTUGround);
    1644           2 :     return reinterpret_cast<OGRStyleTool *>(hST)->GetUnit();
    1645             : }
    1646             : 
    1647             : /************************************************************************/
    1648             : /*                              SetUnit()                               */
    1649             : /************************************************************************/
    1650             : 
    1651             : /**
    1652             :  * \brief Set Style Tool units
    1653             :  *
    1654             :  * @param eUnit the new unit.
    1655             :  * @param dfGroundPaperScale ground to paper scale factor.
    1656             :  *
    1657             :  */
    1658         627 : void OGRStyleTool::SetUnit(OGRSTUnitId eUnit, double dfGroundPaperScale)
    1659             : {
    1660         627 :     m_eUnit = eUnit;
    1661         627 :     m_dfScale = dfGroundPaperScale;
    1662         627 : }
    1663             : 
    1664             : /************************************************************************/
    1665             : /*                           OGR_ST_SetUnit()                           */
    1666             : /************************************************************************/
    1667             : /**
    1668             :  * \brief Set Style Tool units
    1669             :  *
    1670             :  * This function is the same as OGRStyleTool::SetUnit()
    1671             :  *
    1672             :  * @param hST handle to the style tool.
    1673             :  * @param eUnit the new unit.
    1674             :  * @param dfGroundPaperScale ground to paper scale factor.
    1675             :  *
    1676             :  */
    1677             : 
    1678          65 : void OGR_ST_SetUnit(OGRStyleToolH hST, OGRSTUnitId eUnit,
    1679             :                     double dfGroundPaperScale)
    1680             : 
    1681             : {
    1682          65 :     VALIDATE_POINTER0(hST, "OGR_ST_SetUnit");
    1683          65 :     reinterpret_cast<OGRStyleTool *>(hST)->SetUnit(eUnit, dfGroundPaperScale);
    1684             : }
    1685             : 
    1686             : /************************************************************************/
    1687             : /*                               Parse()                                */
    1688             : /************************************************************************/
    1689             : 
    1690             : //! @cond Doxygen_Suppress
    1691        2782 : GBool OGRStyleTool::Parse(const OGRStyleParamId *pasStyle,
    1692             :                           OGRStyleValue *pasValue, int nCount)
    1693             : {
    1694        2782 :     if (IsStyleParsed())
    1695        2161 :         return TRUE;
    1696             : 
    1697         621 :     StyleParsed();
    1698             : 
    1699         621 :     if (m_pszStyleString == nullptr)
    1700         243 :         return FALSE;
    1701             : 
    1702             :     // Token to contains StyleString Type and content.
    1703             :     // Tokenize the String to get the Type and the content
    1704             :     // Example: Type(elem1:val2,elem2:val2)
    1705         756 :     char **papszToken = CSLTokenizeString2(
    1706         378 :         m_pszStyleString, "()",
    1707             :         CSLT_HONOURSTRINGS | CSLT_PRESERVEQUOTES | CSLT_PRESERVEESCAPES);
    1708             : 
    1709         378 :     if (CSLCount(papszToken) > 2 || CSLCount(papszToken) == 0)
    1710             :     {
    1711           0 :         CSLDestroy(papszToken);
    1712           0 :         CPLError(CE_Failure, CPLE_AppDefined,
    1713             :                  "Error in the format of the StyleTool %s", m_pszStyleString);
    1714           0 :         return FALSE;
    1715             :     }
    1716             : 
    1717             :     // Token that will contains StyleString elements.
    1718             :     // Tokenize the content of the StyleString to get paired components in it.
    1719         756 :     char **papszToken2 = CSLTokenizeString2(
    1720         378 :         papszToken[1], ",",
    1721             :         CSLT_HONOURSTRINGS | CSLT_PRESERVEQUOTES | CSLT_PRESERVEESCAPES);
    1722             : 
    1723             :     // Valid that we have the right StyleString for this feature type.
    1724         378 :     switch (GetType())
    1725             :     {
    1726          47 :         case OGRSTCPen:
    1727          47 :             if (!EQUAL(papszToken[0], "PEN"))
    1728             :             {
    1729           0 :                 CPLError(
    1730             :                     CE_Failure, CPLE_AppDefined,
    1731             :                     "Error in the Type of StyleTool %s should be a PEN Type",
    1732             :                     papszToken[0]);
    1733           0 :                 CSLDestroy(papszToken);
    1734           0 :                 CSLDestroy(papszToken2);
    1735           0 :                 return FALSE;
    1736             :             }
    1737          47 :             break;
    1738          35 :         case OGRSTCBrush:
    1739          35 :             if (!EQUAL(papszToken[0], "BRUSH"))
    1740             :             {
    1741           0 :                 CPLError(
    1742             :                     CE_Failure, CPLE_AppDefined,
    1743             :                     "Error in the Type of StyleTool %s should be a BRUSH Type",
    1744             :                     papszToken[0]);
    1745           0 :                 CSLDestroy(papszToken);
    1746           0 :                 CSLDestroy(papszToken2);
    1747           0 :                 return FALSE;
    1748             :             }
    1749          35 :             break;
    1750         277 :         case OGRSTCSymbol:
    1751         277 :             if (!EQUAL(papszToken[0], "SYMBOL"))
    1752             :             {
    1753           0 :                 CPLError(CE_Failure, CPLE_AppDefined,
    1754             :                          "Error in the Type of StyleTool %s should be "
    1755             :                          "a SYMBOL Type",
    1756             :                          papszToken[0]);
    1757           0 :                 CSLDestroy(papszToken);
    1758           0 :                 CSLDestroy(papszToken2);
    1759           0 :                 return FALSE;
    1760             :             }
    1761         277 :             break;
    1762          19 :         case OGRSTCLabel:
    1763          19 :             if (!EQUAL(papszToken[0], "LABEL"))
    1764             :             {
    1765           0 :                 CPLError(
    1766             :                     CE_Failure, CPLE_AppDefined,
    1767             :                     "Error in the Type of StyleTool %s should be a LABEL Type",
    1768             :                     papszToken[0]);
    1769           0 :                 CSLDestroy(papszToken);
    1770           0 :                 CSLDestroy(papszToken2);
    1771           0 :                 return FALSE;
    1772             :             }
    1773          19 :             break;
    1774           0 :         default:
    1775           0 :             CPLError(CE_Failure, CPLE_AppDefined,
    1776             :                      "Error in the Type of StyleTool, Type undetermined");
    1777           0 :             CSLDestroy(papszToken);
    1778           0 :             CSLDestroy(papszToken2);
    1779           0 :             return FALSE;
    1780             :     }
    1781             : 
    1782             :     ////////////////////////////////////////////////////////////////////////
    1783             :     // Here we will loop on each element in the StyleString. If it is
    1784             :     // a valid element, we will add it in the StyleTool with
    1785             :     // SetParamStr().
    1786             :     //
    1787             :     // It is important to note that the SetInternalUnit...() is use to update
    1788             :     // the unit of the StyleTool param (m_eUnit).
    1789             :     // See OGRStyleTool::SetParamStr().
    1790             :     // There's a StyleTool unit (m_eUnit), which is the output unit, and each
    1791             :     // parameter of the style have its own unit value (the input unit). Here we
    1792             :     // set m_eUnit to the input unit and in SetParamStr(), we will use this
    1793             :     // value to set the input unit. Then after the loop we will reset m_eUnit
    1794             :     // to its original value. (Yes it is a side effect / black magic)
    1795             :     //
    1796             :     // The pasStyle variable is a global variable passed in argument to the
    1797             :     // function. See at the top of this file the four OGRStyleParamId
    1798             :     // variable. They are used to register the valid parameter of each
    1799             :     // StyleTool.
    1800             :     ////////////////////////////////////////////////////////////////////////
    1801             : 
    1802             :     // Save Scale and output Units because the parsing code will alter
    1803             :     // the values.
    1804         378 :     OGRSTUnitId eLastUnit = m_eUnit;
    1805         378 :     double dSavedScale = m_dfScale;
    1806         378 :     const int nElements = CSLCount(papszToken2);
    1807             : 
    1808        1781 :     for (int i = 0; i < nElements; i++)
    1809             :     {
    1810             :         char **papszStylePair =
    1811        1403 :             CSLTokenizeString2(papszToken2[i], ":",
    1812             :                                CSLT_HONOURSTRINGS | CSLT_STRIPLEADSPACES |
    1813             :                                    CSLT_STRIPENDSPACES | CSLT_ALLOWEMPTYTOKENS);
    1814             : 
    1815        1403 :         const int nTokens = CSLCount(papszStylePair);
    1816             : 
    1817        1403 :         if (nTokens < 1 || nTokens > 2)
    1818             :         {
    1819           0 :             CPLError(CE_Warning, CPLE_AppDefined,
    1820             :                      "Error in the StyleTool String %s", m_pszStyleString);
    1821           0 :             CPLError(CE_Warning, CPLE_AppDefined,
    1822             :                      "Malformed element #%d (\"%s\") skipped", i,
    1823           0 :                      papszToken2[i]);
    1824           0 :             CSLDestroy(papszStylePair);
    1825           0 :             continue;
    1826             :         }
    1827             : 
    1828        3984 :         for (int j = 0; j < nCount; j++)
    1829             :         {
    1830        3984 :             if (pasStyle[j].pszToken &&
    1831        3982 :                 EQUAL(pasStyle[j].pszToken, papszStylePair[0]))
    1832             :             {
    1833        1403 :                 if (papszStylePair[1] != nullptr && pasStyle[j].bGeoref == TRUE)
    1834         336 :                     SetInternalInputUnitFromParam(papszStylePair[1]);
    1835             : 
    1836             :                 // Set either the actual value of style parameter or "1"
    1837             :                 // for boolean parameters which do not have values (legacy
    1838             :                 // behavior).
    1839        1403 :                 OGRStyleTool::SetParamStr(
    1840        1403 :                     pasStyle[j], pasValue[j],
    1841        1403 :                     papszStylePair[1] != nullptr ? papszStylePair[1] : "1");
    1842             : 
    1843        1403 :                 break;
    1844             :             }
    1845             :         }
    1846             : 
    1847        1403 :         CSLDestroy(papszStylePair);
    1848             :     }
    1849             : 
    1850         378 :     m_eUnit = eLastUnit;
    1851         378 :     m_dfScale = dSavedScale;
    1852             : 
    1853         378 :     CSLDestroy(papszToken2);
    1854         378 :     CSLDestroy(papszToken);
    1855             : 
    1856         378 :     return TRUE;
    1857             : }
    1858             : 
    1859             : //! @endcond
    1860             : 
    1861             : /************************************************************************/
    1862             : /*                   SetInternalInputUnitFromParam()                    */
    1863             : /************************************************************************/
    1864             : 
    1865             : //! @cond Doxygen_Suppress
    1866         336 : void OGRStyleTool::SetInternalInputUnitFromParam(char *pszString)
    1867             : {
    1868         336 :     if (pszString == nullptr)
    1869           0 :         return;
    1870             : 
    1871         336 :     char *pszUnit = strstr(pszString, "g");
    1872         336 :     if (pszUnit)
    1873             :     {
    1874           8 :         SetUnit(OGRSTUGround);
    1875           8 :         pszUnit[0] = '\0';
    1876           8 :         return;
    1877             :     }
    1878         328 :     pszUnit = strstr(pszString, "px");
    1879         328 :     if (pszUnit)
    1880             :     {
    1881          37 :         SetUnit(OGRSTUPixel);
    1882          37 :         pszUnit[0] = '\0';
    1883          37 :         return;
    1884             :     }
    1885         291 :     pszUnit = strstr(pszString, "pt");
    1886         291 :     if (pszUnit)
    1887             :     {
    1888         233 :         SetUnit(OGRSTUPoints);
    1889         233 :         pszUnit[0] = '\0';
    1890         233 :         return;
    1891             :     }
    1892          58 :     pszUnit = strstr(pszString, "mm");
    1893          58 :     if (pszUnit)
    1894             :     {
    1895           1 :         SetUnit(OGRSTUMM);
    1896           1 :         pszUnit[0] = '\0';
    1897           1 :         return;
    1898             :     }
    1899          57 :     pszUnit = strstr(pszString, "cm");
    1900          57 :     if (pszUnit)
    1901             :     {
    1902           0 :         SetUnit(OGRSTUCM);
    1903           0 :         pszUnit[0] = '\0';
    1904           0 :         return;
    1905             :     }
    1906          57 :     pszUnit = strstr(pszString, "in");
    1907          57 :     if (pszUnit)
    1908             :     {
    1909           0 :         SetUnit(OGRSTUInches);
    1910           0 :         pszUnit[0] = '\0';
    1911           0 :         return;
    1912             :     }
    1913             : 
    1914          57 :     SetUnit(OGRSTUMM);
    1915             : }
    1916             : 
    1917             : /************************************************************************/
    1918             : /*                          ComputeWithUnit()                           */
    1919             : /************************************************************************/
    1920         197 : double OGRStyleTool::ComputeWithUnit(double dfValue, OGRSTUnitId eInputUnit)
    1921             : {
    1922         197 :     OGRSTUnitId eOutputUnit = GetUnit();
    1923             : 
    1924         197 :     double dfNewValue = dfValue;  // dfValue in meters;
    1925             : 
    1926         197 :     if (eOutputUnit == eInputUnit)
    1927         174 :         return dfValue;
    1928             : 
    1929          23 :     switch (eInputUnit)
    1930             :     {
    1931           5 :         case OGRSTUGround:
    1932           5 :             dfNewValue = dfValue / m_dfScale;
    1933           5 :             break;
    1934           3 :         case OGRSTUPixel:
    1935           3 :             dfNewValue = dfValue / (72.0 * 39.37);
    1936           3 :             break;
    1937          14 :         case OGRSTUPoints:
    1938          14 :             dfNewValue = dfValue / (72.0 * 39.37);
    1939          14 :             break;
    1940           1 :         case OGRSTUMM:
    1941           1 :             dfNewValue = 0.001 * dfValue;
    1942           1 :             break;
    1943           0 :         case OGRSTUCM:
    1944           0 :             dfNewValue = 0.01 * dfValue;
    1945           0 :             break;
    1946           0 :         case OGRSTUInches:
    1947           0 :             dfNewValue = dfValue / 39.37;
    1948           0 :             break;
    1949           0 :         default:
    1950           0 :             break;  // imp.
    1951             :     }
    1952             : 
    1953          23 :     switch (eOutputUnit)
    1954             :     {
    1955           2 :         case OGRSTUGround:
    1956           2 :             dfNewValue *= m_dfScale;
    1957           2 :             break;
    1958           0 :         case OGRSTUPixel:
    1959           0 :             dfNewValue *= 72.0 * 39.37;
    1960           0 :             break;
    1961           0 :         case OGRSTUPoints:
    1962           0 :             dfNewValue *= 72.0 * 39.37;
    1963           0 :             break;
    1964          21 :         case OGRSTUMM:
    1965          21 :             dfNewValue *= 1000.0;
    1966          21 :             break;
    1967           0 :         case OGRSTUCM:
    1968           0 :             dfNewValue *= 100.0;
    1969           0 :             break;
    1970           0 :         case OGRSTUInches:
    1971           0 :             dfNewValue *= 39.37;
    1972           0 :             break;
    1973           0 :         default:
    1974           0 :             break;  // imp.
    1975             :     }
    1976          23 :     return dfNewValue;
    1977             : }
    1978             : 
    1979             : /************************************************************************/
    1980             : /*                          ComputeWithUnit()                           */
    1981             : /************************************************************************/
    1982           0 : int OGRStyleTool::ComputeWithUnit(int nValue, OGRSTUnitId eUnit)
    1983             : {
    1984             :     return static_cast<int>(
    1985           0 :         ComputeWithUnit(static_cast<double>(nValue), eUnit));
    1986             : }
    1987             : 
    1988             : //! @endcond
    1989             : 
    1990             : /************************************************************************/
    1991             : /*                            GetParamStr()                             */
    1992             : /************************************************************************/
    1993             : 
    1994             : /** Undocumented
    1995             :  * @param sStyleParam undocumented.
    1996             :  * @param sStyleValue undocumented.
    1997             :  * @param bValueIsNull undocumented.
    1998             :  * @return Undocumented.
    1999             :  */
    2000         693 : const char *OGRStyleTool::GetParamStr(const OGRStyleParamId &sStyleParam,
    2001             :                                       const OGRStyleValue &sStyleValue,
    2002             :                                       GBool &bValueIsNull)
    2003             : {
    2004         693 :     if (!Parse())
    2005             :     {
    2006           0 :         bValueIsNull = TRUE;
    2007           0 :         return nullptr;
    2008             :     }
    2009             : 
    2010         693 :     bValueIsNull = !sStyleValue.bValid;
    2011             : 
    2012         693 :     if (bValueIsNull == TRUE)
    2013          42 :         return nullptr;
    2014             : 
    2015         651 :     switch (sStyleParam.eType)
    2016             :     {
    2017             :         // If sStyleParam.bGeoref == TRUE, need to convert to output value.
    2018         651 :         case OGRSTypeString:
    2019         651 :             return sStyleValue.pszValue;
    2020           0 :         case OGRSTypeDouble:
    2021           0 :             if (sStyleParam.bGeoref)
    2022           0 :                 return CPLSPrintf("%f", ComputeWithUnit(sStyleValue.dfValue,
    2023           0 :                                                         sStyleValue.eUnit));
    2024             :             else
    2025           0 :                 return CPLSPrintf("%f", sStyleValue.dfValue);
    2026             : 
    2027           0 :         case OGRSTypeInteger:
    2028           0 :             if (sStyleParam.bGeoref)
    2029           0 :                 return CPLSPrintf("%d", ComputeWithUnit(sStyleValue.nValue,
    2030           0 :                                                         sStyleValue.eUnit));
    2031             :             else
    2032           0 :                 return CPLSPrintf("%d", sStyleValue.nValue);
    2033           0 :         case OGRSTypeBoolean:
    2034           0 :             return CPLSPrintf("%d", sStyleValue.nValue != 0);
    2035           0 :         default:
    2036           0 :             bValueIsNull = TRUE;
    2037           0 :             return nullptr;
    2038             :     }
    2039             : }
    2040             : 
    2041             : /****************************************************************************/
    2042             : /*    int OGRStyleTool::GetParamNum(OGRStyleParamId sStyleParam ,           */
    2043             : /*                               OGRStyleValue sStyleValue,                 */
    2044             : /*                               GBool &bValueIsNull)                       */
    2045             : /*                                                                          */
    2046             : /****************************************************************************/
    2047             : 
    2048             : /** Undocumented
    2049             :  * @param sStyleParam undocumented.
    2050             :  * @param sStyleValue undocumented.
    2051             :  * @param bValueIsNull undocumented.
    2052             :  * @return Undocumented.
    2053             :  */
    2054          49 : int OGRStyleTool::GetParamNum(const OGRStyleParamId &sStyleParam,
    2055             :                               const OGRStyleValue &sStyleValue,
    2056             :                               GBool &bValueIsNull)
    2057             : {
    2058             :     return static_cast<int>(
    2059          49 :         GetParamDbl(sStyleParam, sStyleValue, bValueIsNull));
    2060             : }
    2061             : 
    2062             : /****************************************************************************/
    2063             : /*       double OGRStyleTool::GetParamDbl(OGRStyleParamId sStyleParam ,     */
    2064             : /*                               OGRStyleValue sStyleValue,                 */
    2065             : /*                               GBool &bValueIsNull)                       */
    2066             : /*                                                                          */
    2067             : /****************************************************************************/
    2068             : 
    2069             : /** Undocumented
    2070             :  * @param sStyleParam undocumented.
    2071             :  * @param sStyleValue undocumented.
    2072             :  * @param bValueIsNull undocumented.
    2073             :  * @return Undocumented.
    2074             :  */
    2075         352 : double OGRStyleTool::GetParamDbl(const OGRStyleParamId &sStyleParam,
    2076             :                                  const OGRStyleValue &sStyleValue,
    2077             :                                  GBool &bValueIsNull)
    2078             : {
    2079         352 :     if (!Parse())
    2080             :     {
    2081           0 :         bValueIsNull = TRUE;
    2082           0 :         return 0.0;
    2083             :     }
    2084             : 
    2085         352 :     bValueIsNull = !sStyleValue.bValid;
    2086             : 
    2087         352 :     if (bValueIsNull == TRUE)
    2088         125 :         return 0.0;
    2089             : 
    2090         227 :     switch (sStyleParam.eType)
    2091             :     {
    2092             :         // if sStyleParam.bGeoref == TRUE, need to convert to output value.
    2093           0 :         case OGRSTypeString:
    2094           0 :             if (sStyleParam.bGeoref)
    2095           0 :                 return ComputeWithUnit(CPLAtof(sStyleValue.pszValue),
    2096           0 :                                        sStyleValue.eUnit);
    2097             :             else
    2098           0 :                 return CPLAtof(sStyleValue.pszValue);
    2099         214 :         case OGRSTypeDouble:
    2100         214 :             if (sStyleParam.bGeoref)
    2101         197 :                 return ComputeWithUnit(sStyleValue.dfValue, sStyleValue.eUnit);
    2102             :             else
    2103          17 :                 return sStyleValue.dfValue;
    2104           7 :         case OGRSTypeInteger:
    2105           7 :             if (sStyleParam.bGeoref)
    2106             :                 return static_cast<double>(
    2107           0 :                     ComputeWithUnit(sStyleValue.nValue, sStyleValue.eUnit));
    2108             :             else
    2109           7 :                 return static_cast<double>(sStyleValue.nValue);
    2110           6 :         case OGRSTypeBoolean:
    2111           6 :             return static_cast<double>(sStyleValue.nValue != 0);
    2112           0 :         default:
    2113           0 :             bValueIsNull = TRUE;
    2114           0 :             return 0.0;
    2115             :     }
    2116             : }
    2117             : 
    2118             : /****************************************************************************/
    2119             : /*                           GetRawParamDbl()                               */
    2120             : /****************************************************************************/
    2121             : 
    2122             : /** Return the raw value of a parameter of type double.
    2123             :  *
    2124             :  * @param sStyleParam Identifier of the parameter.
    2125             :  * @param sStyleValue Value of the parameter.
    2126             :  * @param[out] eRawUnit Raw unit
    2127             :  * @param[out] bValueIsNull if the value is null
    2128             :  * @return the raw value.
    2129             :  */
    2130          32 : double OGRStyleTool::GetRawParamDbl(const OGRStyleParamId &sStyleParam,
    2131             :                                     const OGRStyleValue &sStyleValue,
    2132             :                                     OGRSTUnitId &eRawUnit, GBool &bValueIsNull)
    2133             : {
    2134          32 :     eRawUnit = OGRSTUGround;
    2135          32 :     if (!Parse())
    2136             :     {
    2137           0 :         bValueIsNull = TRUE;
    2138           0 :         return 0.0;
    2139             :     }
    2140             : 
    2141          32 :     bValueIsNull = !sStyleValue.bValid;
    2142             : 
    2143          32 :     if (bValueIsNull == TRUE)
    2144           1 :         return 0.0;
    2145             : 
    2146          31 :     switch (sStyleParam.eType)
    2147             :     {
    2148          31 :         case OGRSTypeDouble:
    2149          31 :             eRawUnit = sStyleValue.eUnit;
    2150          31 :             return sStyleValue.dfValue;
    2151             : 
    2152           0 :         default:
    2153           0 :             bValueIsNull = TRUE;
    2154           0 :             return 0.0;
    2155             :     }
    2156             : }
    2157             : 
    2158             : /****************************************************************************/
    2159             : /*      void OGRStyleTool::SetParamStr(OGRStyleParamId &sStyleParam ,       */
    2160             : /*                             OGRStyleValue &sStyleValue,                  */
    2161             : /*                             const char *pszParamString)                  */
    2162             : /*                                                                          */
    2163             : /****************************************************************************/
    2164             : 
    2165             : /** Undocumented
    2166             :  * @param sStyleParam undocumented.
    2167             :  * @param sStyleValue undocumented.
    2168             :  * @param pszParamString undocumented.
    2169             :  */
    2170        1607 : void OGRStyleTool::SetParamStr(const OGRStyleParamId &sStyleParam,
    2171             :                                OGRStyleValue &sStyleValue,
    2172             :                                const char *pszParamString)
    2173             : {
    2174        1607 :     Parse();
    2175        1607 :     StyleModified();
    2176        1607 :     sStyleValue.bValid = TRUE;
    2177        1607 :     sStyleValue.eUnit = GetUnit();
    2178        1607 :     switch (sStyleParam.eType)
    2179             :     {
    2180             :         // If sStyleParam.bGeoref == TRUE, need to convert to output value;
    2181        1023 :         case OGRSTypeString:
    2182        1023 :             sStyleValue.pszValue = CPLStrdup(pszParamString);
    2183        1023 :             break;
    2184         571 :         case OGRSTypeDouble:
    2185         571 :             sStyleValue.dfValue = CPLAtof(pszParamString);
    2186         571 :             break;
    2187           7 :         case OGRSTypeInteger:
    2188           7 :             sStyleValue.nValue = atoi(pszParamString);
    2189           7 :             break;
    2190           6 :         case OGRSTypeBoolean:
    2191           6 :             sStyleValue.nValue = atoi(pszParamString) != 0;
    2192           6 :             break;
    2193           0 :         default:
    2194           0 :             sStyleValue.bValid = FALSE;
    2195           0 :             break;
    2196             :     }
    2197        1607 : }
    2198             : 
    2199             : /****************************************************************************/
    2200             : /*    void OGRStyleTool::SetParamNum(OGRStyleParamId &sStyleParam ,         */
    2201             : /*                             OGRStyleValue &sStyleValue,                  */
    2202             : /*                             int nParam)                                  */
    2203             : /*                                                                          */
    2204             : /****************************************************************************/
    2205             : 
    2206             : /** Undocumented
    2207             :  * @param sStyleParam undocumented.
    2208             :  * @param sStyleValue undocumented.
    2209             :  * @param nParam undocumented.
    2210             :  */
    2211           0 : void OGRStyleTool::SetParamNum(const OGRStyleParamId &sStyleParam,
    2212             :                                OGRStyleValue &sStyleValue, int nParam)
    2213             : {
    2214           0 :     Parse();
    2215           0 :     StyleModified();
    2216           0 :     sStyleValue.bValid = TRUE;
    2217           0 :     sStyleValue.eUnit = GetUnit();
    2218           0 :     switch (sStyleParam.eType)
    2219             :     {
    2220             : 
    2221             :         // If sStyleParam.bGeoref == TRUE, need to convert to output value;
    2222           0 :         case OGRSTypeString:
    2223           0 :             sStyleValue.pszValue = CPLStrdup(CPLString().Printf("%d", nParam));
    2224           0 :             break;
    2225           0 :         case OGRSTypeDouble:
    2226           0 :             sStyleValue.dfValue = static_cast<double>(nParam);
    2227           0 :             break;
    2228           0 :         case OGRSTypeInteger:
    2229           0 :             sStyleValue.nValue = nParam;
    2230           0 :             break;
    2231           0 :         case OGRSTypeBoolean:
    2232           0 :             sStyleValue.nValue = nParam != 0;
    2233           0 :             break;
    2234           0 :         default:
    2235           0 :             sStyleValue.bValid = FALSE;
    2236           0 :             break;
    2237             :     }
    2238           0 : }
    2239             : 
    2240             : /****************************************************************************/
    2241             : /*      void OGRStyleTool::SetParamDbl(OGRStyleParamId &sStyleParam ,       */
    2242             : /*                             OGRStyleValue &sStyleValue,                  */
    2243             : /*                             double dfParam)                              */
    2244             : /*                                                                          */
    2245             : /****************************************************************************/
    2246             : 
    2247             : /** Undocumented
    2248             :  * @param sStyleParam undocumented.
    2249             :  * @param sStyleValue undocumented.
    2250             :  * @param dfParam undocumented.
    2251             :  */
    2252          98 : void OGRStyleTool::SetParamDbl(const OGRStyleParamId &sStyleParam,
    2253             :                                OGRStyleValue &sStyleValue, double dfParam)
    2254             : {
    2255          98 :     Parse();
    2256          98 :     StyleModified();
    2257          98 :     sStyleValue.bValid = TRUE;
    2258          98 :     sStyleValue.eUnit = GetUnit();
    2259          98 :     switch (sStyleParam.eType)
    2260             :     {
    2261             :         // If sStyleParam.bGeoref == TRUE, need to convert to output value;
    2262           0 :         case OGRSTypeString:
    2263           0 :             sStyleValue.pszValue = CPLStrdup(CPLString().Printf("%f", dfParam));
    2264           0 :             break;
    2265          98 :         case OGRSTypeDouble:
    2266          98 :             sStyleValue.dfValue = dfParam;
    2267          98 :             break;
    2268           0 :         case OGRSTypeInteger:
    2269           0 :             sStyleValue.nValue = static_cast<int>(dfParam);
    2270           0 :             break;
    2271           0 :         case OGRSTypeBoolean:
    2272           0 :             sStyleValue.nValue = static_cast<int>(dfParam) != 0;
    2273           0 :             break;
    2274           0 :         default:
    2275           0 :             sStyleValue.bValid = FALSE;
    2276           0 :             break;
    2277             :     }
    2278          98 : }
    2279             : 
    2280             : /************************************************************************/
    2281             : /*                           OGR_ST_GetParamStr()                       */
    2282             : /************************************************************************/
    2283             : /**
    2284             :  * \brief Get Style Tool parameter value as string
    2285             :  *
    2286             :  * Maps to the OGRStyleTool subclasses' GetParamStr() methods.
    2287             :  *
    2288             :  * @param hST handle to the style tool.
    2289             :  * @param eParam the parameter id from the enumeration corresponding to the
    2290             :  * type of this style tool (one of the OGRSTPenParam, OGRSTBrushParam,
    2291             :  * OGRSTSymbolParam or OGRSTLabelParam enumerations)
    2292             :  * @param bValueIsNull pointer to an integer that will be set to TRUE or FALSE
    2293             :  * to indicate whether the parameter value is NULL.
    2294             :  *
    2295             :  * @return the parameter value as string and sets bValueIsNull.
    2296             :  */
    2297             : 
    2298         137 : const char *OGR_ST_GetParamStr(OGRStyleToolH hST, int eParam, int *bValueIsNull)
    2299             : {
    2300         137 :     VALIDATE_POINTER1(hST, "OGR_ST_GetParamStr", "");
    2301         137 :     VALIDATE_POINTER1(bValueIsNull, "OGR_ST_GetParamStr", "");
    2302             : 
    2303         137 :     GBool bIsNull = TRUE;
    2304         137 :     const char *pszVal = "";
    2305             : 
    2306         137 :     switch (reinterpret_cast<OGRStyleTool *>(hST)->GetType())
    2307             :     {
    2308           4 :         case OGRSTCPen:
    2309           4 :             pszVal = reinterpret_cast<OGRStylePen *>(hST)->GetParamStr(
    2310             :                 static_cast<OGRSTPenParam>(eParam), bIsNull);
    2311           4 :             break;
    2312           1 :         case OGRSTCBrush:
    2313           1 :             pszVal = reinterpret_cast<OGRStyleBrush *>(hST)->GetParamStr(
    2314             :                 static_cast<OGRSTBrushParam>(eParam), bIsNull);
    2315           1 :             break;
    2316         102 :         case OGRSTCSymbol:
    2317         102 :             pszVal = reinterpret_cast<OGRStyleSymbol *>(hST)->GetParamStr(
    2318             :                 static_cast<OGRSTSymbolParam>(eParam), bIsNull);
    2319         102 :             break;
    2320          30 :         case OGRSTCLabel:
    2321          30 :             pszVal = reinterpret_cast<OGRStyleLabel *>(hST)->GetParamStr(
    2322             :                 static_cast<OGRSTLabelParam>(eParam), bIsNull);
    2323          30 :             break;
    2324           0 :         default:
    2325           0 :             break;
    2326             :     }
    2327             : 
    2328         137 :     *bValueIsNull = bIsNull;
    2329         137 :     return pszVal;
    2330             : }
    2331             : 
    2332             : /************************************************************************/
    2333             : /*                           OGR_ST_GetParamNum()                       */
    2334             : /************************************************************************/
    2335             : /**
    2336             :  * \brief Get Style Tool parameter value as an integer
    2337             :  *
    2338             :  * Maps to the OGRStyleTool subclasses' GetParamNum() methods.
    2339             :  *
    2340             :  * @param hST handle to the style tool.
    2341             :  * @param eParam the parameter id from the enumeration corresponding to the
    2342             :  * type of this style tool (one of the OGRSTPenParam, OGRSTBrushParam,
    2343             :  * OGRSTSymbolParam or OGRSTLabelParam enumerations)
    2344             :  * @param bValueIsNull pointer to an integer that will be set to TRUE or FALSE
    2345             :  * to indicate whether the parameter value is NULL.
    2346             :  *
    2347             :  * @return the parameter value as integer and sets bValueIsNull.
    2348             :  */
    2349             : 
    2350          30 : int OGR_ST_GetParamNum(OGRStyleToolH hST, int eParam, int *bValueIsNull)
    2351             : {
    2352          30 :     VALIDATE_POINTER1(hST, "OGR_ST_GetParamNum", 0);
    2353          30 :     VALIDATE_POINTER1(bValueIsNull, "OGR_ST_GetParamNum", 0);
    2354             : 
    2355          30 :     GBool bIsNull = TRUE;
    2356          30 :     int nVal = 0;
    2357             : 
    2358          30 :     switch (reinterpret_cast<OGRStyleTool *>(hST)->GetType())
    2359             :     {
    2360           0 :         case OGRSTCPen:
    2361           0 :             nVal = reinterpret_cast<OGRStylePen *>(hST)->GetParamNum(
    2362             :                 static_cast<OGRSTPenParam>(eParam), bIsNull);
    2363           0 :             break;
    2364           0 :         case OGRSTCBrush:
    2365           0 :             nVal = reinterpret_cast<OGRStyleBrush *>(hST)->GetParamNum(
    2366             :                 static_cast<OGRSTBrushParam>(eParam), bIsNull);
    2367           0 :             break;
    2368           0 :         case OGRSTCSymbol:
    2369           0 :             nVal = reinterpret_cast<OGRStyleSymbol *>(hST)->GetParamNum(
    2370             :                 static_cast<OGRSTSymbolParam>(eParam), bIsNull);
    2371           0 :             break;
    2372          30 :         case OGRSTCLabel:
    2373          30 :             nVal = reinterpret_cast<OGRStyleLabel *>(hST)->GetParamNum(
    2374             :                 static_cast<OGRSTLabelParam>(eParam), bIsNull);
    2375          30 :             break;
    2376           0 :         default:
    2377           0 :             break;
    2378             :     }
    2379             : 
    2380          30 :     *bValueIsNull = bIsNull;
    2381          30 :     return nVal;
    2382             : }
    2383             : 
    2384             : /************************************************************************/
    2385             : /*                           OGR_ST_GetParamDbl()                       */
    2386             : /************************************************************************/
    2387             : /**
    2388             :  * \brief Get Style Tool parameter value as a double
    2389             :  *
    2390             :  * Maps to the OGRStyleTool subclasses' GetParamDbl() methods.
    2391             :  *
    2392             :  * @param hST handle to the style tool.
    2393             :  * @param eParam the parameter id from the enumeration corresponding to the
    2394             :  * type of this style tool (one of the OGRSTPenParam, OGRSTBrushParam,
    2395             :  * OGRSTSymbolParam or OGRSTLabelParam enumerations)
    2396             :  * @param bValueIsNull pointer to an integer that will be set to TRUE or FALSE
    2397             :  * to indicate whether the parameter value is NULL.
    2398             :  *
    2399             :  * @return the parameter value as double and sets bValueIsNull.
    2400             :  */
    2401             : 
    2402         105 : double OGR_ST_GetParamDbl(OGRStyleToolH hST, int eParam, int *bValueIsNull)
    2403             : {
    2404         105 :     VALIDATE_POINTER1(hST, "OGR_ST_GetParamDbl", 0.0);
    2405         105 :     VALIDATE_POINTER1(bValueIsNull, "OGR_ST_GetParamDbl", 0.0);
    2406             : 
    2407         105 :     GBool bIsNull = TRUE;
    2408         105 :     double dfVal = 0.0;
    2409             : 
    2410         105 :     switch (reinterpret_cast<OGRStyleTool *>(hST)->GetType())
    2411             :     {
    2412           4 :         case OGRSTCPen:
    2413           4 :             dfVal = reinterpret_cast<OGRStylePen *>(hST)->GetParamDbl(
    2414             :                 static_cast<OGRSTPenParam>(eParam), bIsNull);
    2415           4 :             break;
    2416           0 :         case OGRSTCBrush:
    2417           0 :             dfVal = reinterpret_cast<OGRStyleBrush *>(hST)->GetParamDbl(
    2418             :                 static_cast<OGRSTBrushParam>(eParam), bIsNull);
    2419           0 :             break;
    2420          51 :         case OGRSTCSymbol:
    2421          51 :             dfVal = reinterpret_cast<OGRStyleSymbol *>(hST)->GetParamDbl(
    2422             :                 static_cast<OGRSTSymbolParam>(eParam), bIsNull);
    2423          51 :             break;
    2424          50 :         case OGRSTCLabel:
    2425          50 :             dfVal = reinterpret_cast<OGRStyleLabel *>(hST)->GetParamDbl(
    2426             :                 static_cast<OGRSTLabelParam>(eParam), bIsNull);
    2427          50 :             break;
    2428           0 :         default:
    2429           0 :             break;
    2430             :     }
    2431             : 
    2432         105 :     *bValueIsNull = bIsNull;
    2433         105 :     return dfVal;
    2434             : }
    2435             : 
    2436             : /************************************************************************/
    2437             : /*                           OGR_ST_SetParamStr()                       */
    2438             : /************************************************************************/
    2439             : /**
    2440             :  * \brief Set Style Tool parameter value from a string
    2441             :  *
    2442             :  * Maps to the OGRStyleTool subclasses' SetParamStr() methods.
    2443             :  *
    2444             :  * @param hST handle to the style tool.
    2445             :  * @param eParam the parameter id from the enumeration corresponding to the
    2446             :  * type of this style tool (one of the OGRSTPenParam, OGRSTBrushParam,
    2447             :  * OGRSTSymbolParam or OGRSTLabelParam enumerations)
    2448             :  * @param pszValue the new parameter value
    2449             :  *
    2450             :  */
    2451             : 
    2452           0 : void OGR_ST_SetParamStr(OGRStyleToolH hST, int eParam, const char *pszValue)
    2453             : {
    2454           0 :     VALIDATE_POINTER0(hST, "OGR_ST_SetParamStr");
    2455           0 :     VALIDATE_POINTER0(pszValue, "OGR_ST_SetParamStr");
    2456             : 
    2457           0 :     switch (reinterpret_cast<OGRStyleTool *>(hST)->GetType())
    2458             :     {
    2459           0 :         case OGRSTCPen:
    2460           0 :             reinterpret_cast<OGRStylePen *>(hST)->SetParamStr(
    2461             :                 static_cast<OGRSTPenParam>(eParam), pszValue);
    2462           0 :             break;
    2463           0 :         case OGRSTCBrush:
    2464           0 :             reinterpret_cast<OGRStyleBrush *>(hST)->SetParamStr(
    2465             :                 static_cast<OGRSTBrushParam>(eParam), pszValue);
    2466           0 :             break;
    2467           0 :         case OGRSTCSymbol:
    2468           0 :             reinterpret_cast<OGRStyleSymbol *>(hST)->SetParamStr(
    2469             :                 static_cast<OGRSTSymbolParam>(eParam), pszValue);
    2470           0 :             break;
    2471           0 :         case OGRSTCLabel:
    2472           0 :             reinterpret_cast<OGRStyleLabel *>(hST)->SetParamStr(
    2473             :                 static_cast<OGRSTLabelParam>(eParam), pszValue);
    2474           0 :             break;
    2475           0 :         default:
    2476           0 :             break;
    2477             :     }
    2478             : }
    2479             : 
    2480             : /************************************************************************/
    2481             : /*                           OGR_ST_SetParamNum()                       */
    2482             : /************************************************************************/
    2483             : /**
    2484             :  * \brief Set Style Tool parameter value from an integer
    2485             :  *
    2486             :  * Maps to the OGRStyleTool subclasses' SetParamNum() methods.
    2487             :  *
    2488             :  * @param hST handle to the style tool.
    2489             :  * @param eParam the parameter id from the enumeration corresponding to the
    2490             :  * type of this style tool (one of the OGRSTPenParam, OGRSTBrushParam,
    2491             :  * OGRSTSymbolParam or OGRSTLabelParam enumerations)
    2492             :  * @param nValue the new parameter value
    2493             :  *
    2494             :  */
    2495             : 
    2496           0 : void OGR_ST_SetParamNum(OGRStyleToolH hST, int eParam, int nValue)
    2497             : {
    2498           0 :     VALIDATE_POINTER0(hST, "OGR_ST_SetParamNum");
    2499             : 
    2500           0 :     switch (reinterpret_cast<OGRStyleTool *>(hST)->GetType())
    2501             :     {
    2502           0 :         case OGRSTCPen:
    2503           0 :             reinterpret_cast<OGRStylePen *>(hST)->SetParamNum(
    2504             :                 static_cast<OGRSTPenParam>(eParam), nValue);
    2505           0 :             break;
    2506           0 :         case OGRSTCBrush:
    2507           0 :             reinterpret_cast<OGRStyleBrush *>(hST)->SetParamNum(
    2508             :                 static_cast<OGRSTBrushParam>(eParam), nValue);
    2509           0 :             break;
    2510           0 :         case OGRSTCSymbol:
    2511           0 :             reinterpret_cast<OGRStyleSymbol *>(hST)->SetParamNum(
    2512             :                 static_cast<OGRSTSymbolParam>(eParam), nValue);
    2513           0 :             break;
    2514           0 :         case OGRSTCLabel:
    2515           0 :             reinterpret_cast<OGRStyleLabel *>(hST)->SetParamNum(
    2516             :                 static_cast<OGRSTLabelParam>(eParam), nValue);
    2517           0 :             break;
    2518           0 :         default:
    2519           0 :             break;
    2520             :     }
    2521             : }
    2522             : 
    2523             : /************************************************************************/
    2524             : /*                           OGR_ST_SetParamDbl()                       */
    2525             : /************************************************************************/
    2526             : /**
    2527             :  * \brief Set Style Tool parameter value from a double
    2528             :  *
    2529             :  * Maps to the OGRStyleTool subclasses' SetParamDbl() methods.
    2530             :  *
    2531             :  * @param hST handle to the style tool.
    2532             :  * @param eParam the parameter id from the enumeration corresponding to the
    2533             :  * type of this style tool (one of the OGRSTPenParam, OGRSTBrushParam,
    2534             :  * OGRSTSymbolParam or OGRSTLabelParam enumerations)
    2535             :  * @param dfValue the new parameter value
    2536             :  *
    2537             :  */
    2538             : 
    2539           0 : void OGR_ST_SetParamDbl(OGRStyleToolH hST, int eParam, double dfValue)
    2540             : {
    2541           0 :     VALIDATE_POINTER0(hST, "OGR_ST_SetParamDbl");
    2542             : 
    2543           0 :     switch (reinterpret_cast<OGRStyleTool *>(hST)->GetType())
    2544             :     {
    2545           0 :         case OGRSTCPen:
    2546           0 :             reinterpret_cast<OGRStylePen *>(hST)->SetParamDbl(
    2547             :                 static_cast<OGRSTPenParam>(eParam), dfValue);
    2548           0 :             break;
    2549           0 :         case OGRSTCBrush:
    2550           0 :             reinterpret_cast<OGRStyleBrush *>(hST)->SetParamDbl(
    2551             :                 static_cast<OGRSTBrushParam>(eParam), dfValue);
    2552           0 :             break;
    2553           0 :         case OGRSTCSymbol:
    2554           0 :             reinterpret_cast<OGRStyleSymbol *>(hST)->SetParamDbl(
    2555             :                 static_cast<OGRSTSymbolParam>(eParam), dfValue);
    2556           0 :             break;
    2557           0 :         case OGRSTCLabel:
    2558           0 :             reinterpret_cast<OGRStyleLabel *>(hST)->SetParamDbl(
    2559             :                 static_cast<OGRSTLabelParam>(eParam), dfValue);
    2560           0 :             break;
    2561           0 :         default:
    2562           0 :             break;
    2563             :     }
    2564             : }
    2565             : 
    2566             : /************************************************************************/
    2567             : /*                           OGR_ST_GetStyleString()                    */
    2568             : /************************************************************************/
    2569             : 
    2570             : /**
    2571             :  * \fn OGRStyleTool::GetStyleString()
    2572             :  * \brief Get the style string for this Style Tool
    2573             :  *
    2574             :  * Maps to the OGRStyleTool subclasses' GetStyleString() methods.
    2575             :  *
    2576             :  * @return the style string for this style tool or "" if the hST is invalid.
    2577             :  */
    2578             : 
    2579             : /**
    2580             :  * \brief Get the style string for this Style Tool
    2581             :  *
    2582             :  * Maps to the OGRStyleTool subclasses' GetStyleString() methods.
    2583             :  *
    2584             :  * @param hST handle to the style tool.
    2585             :  *
    2586             :  * @return the style string for this style tool or "" if the hST is invalid.
    2587             :  */
    2588             : 
    2589           0 : const char *OGR_ST_GetStyleString(OGRStyleToolH hST)
    2590             : {
    2591           0 :     const char *pszVal = "";
    2592             : 
    2593           0 :     VALIDATE_POINTER1(hST, "OGR_ST_GetStyleString", "");
    2594             : 
    2595           0 :     switch (reinterpret_cast<OGRStyleTool *>(hST)->GetType())
    2596             :     {
    2597           0 :         case OGRSTCPen:
    2598           0 :             pszVal = reinterpret_cast<OGRStylePen *>(hST)->GetStyleString();
    2599           0 :             break;
    2600           0 :         case OGRSTCBrush:
    2601           0 :             pszVal = reinterpret_cast<OGRStyleBrush *>(hST)->GetStyleString();
    2602           0 :             break;
    2603           0 :         case OGRSTCSymbol:
    2604           0 :             pszVal = reinterpret_cast<OGRStyleSymbol *>(hST)->GetStyleString();
    2605           0 :             break;
    2606           0 :         case OGRSTCLabel:
    2607           0 :             pszVal = reinterpret_cast<OGRStyleLabel *>(hST)->GetStyleString();
    2608           0 :             break;
    2609           0 :         default:
    2610           0 :             break;
    2611             :     }
    2612             : 
    2613           0 :     return pszVal;
    2614             : }
    2615             : 
    2616             : /************************************************************************/
    2617             : /*                           OGR_ST_GetRGBFromString()                  */
    2618             : /************************************************************************/
    2619             : /**
    2620             :  * \brief Return the r,g,b,a components of a color encoded in \#RRGGBB[AA]
    2621             :  * format.
    2622             :  *
    2623             :  * Maps to OGRStyleTool::GetRGBFromString().
    2624             :  *
    2625             :  * @param hST handle to the style tool.
    2626             :  * @param pszColor the color to parse
    2627             :  * @param pnRed pointer to an int in which the red value will be returned
    2628             :  * @param pnGreen pointer to an int in which the green value will be returned
    2629             :  * @param pnBlue pointer to an int in which the blue value will be returned
    2630             :  * @param pnAlpha pointer to an int in which the (optional) alpha value will
    2631             :  * be returned
    2632             :  *
    2633             :  * @return TRUE if the color could be successfully parsed, or FALSE in case of
    2634             :  * errors.
    2635             :  */
    2636             : 
    2637           0 : int OGR_ST_GetRGBFromString(OGRStyleToolH hST, const char *pszColor, int *pnRed,
    2638             :                             int *pnGreen, int *pnBlue, int *pnAlpha)
    2639             : {
    2640             : 
    2641           0 :     VALIDATE_POINTER1(hST, "OGR_ST_GetRGBFromString", FALSE);
    2642           0 :     VALIDATE_POINTER1(pnRed, "OGR_ST_GetRGBFromString", FALSE);
    2643           0 :     VALIDATE_POINTER1(pnGreen, "OGR_ST_GetRGBFromString", FALSE);
    2644           0 :     VALIDATE_POINTER1(pnBlue, "OGR_ST_GetRGBFromString", FALSE);
    2645           0 :     VALIDATE_POINTER1(pnAlpha, "OGR_ST_GetRGBFromString", FALSE);
    2646             : 
    2647           0 :     return reinterpret_cast<OGRStyleTool *>(hST)->GetRGBFromString(
    2648           0 :         pszColor, *pnRed, *pnGreen, *pnBlue, *pnAlpha);
    2649             : }
    2650             : 
    2651             : //! @cond Doxygen_Suppress
    2652             : /* ======================================================================== */
    2653             : /*                OGRStylePen                                               */
    2654             : /*       Specific parameter (Set/Get) for the StylePen                      */
    2655             : /* ======================================================================== */
    2656             : 
    2657             : /****************************************************************************/
    2658             : /*                      OGRStylePen::OGRStylePen()                          */
    2659             : /*                                                                          */
    2660             : /****************************************************************************/
    2661         255 : OGRStylePen::OGRStylePen()
    2662             :     : OGRStyleTool(OGRSTCPen),
    2663             :       m_pasStyleValue(static_cast<OGRStyleValue *>(
    2664         255 :           CPLCalloc(OGRSTPenLast, sizeof(OGRStyleValue))))
    2665             : {
    2666         255 : }
    2667             : 
    2668             : /****************************************************************************/
    2669             : /*                      OGRStylePen::~OGRStylePen()                         */
    2670             : /*                                                                          */
    2671             : /****************************************************************************/
    2672         500 : OGRStylePen::~OGRStylePen()
    2673             : {
    2674        2295 :     for (int i = 0; i < OGRSTPenLast; i++)
    2675             :     {
    2676        2040 :         if (m_pasStyleValue[i].pszValue != nullptr)
    2677             :         {
    2678         192 :             CPLFree(m_pasStyleValue[i].pszValue);
    2679         192 :             m_pasStyleValue[i].pszValue = nullptr;
    2680             :         }
    2681             :     }
    2682             : 
    2683         255 :     CPLFree(m_pasStyleValue);
    2684         500 : }
    2685             : 
    2686             : /************************************************************************/
    2687             : /*                         OGRStylePen::Parse()                         */
    2688             : /************************************************************************/
    2689         453 : GBool OGRStylePen::Parse()
    2690             : 
    2691             : {
    2692         453 :     return OGRStyleTool::Parse(asStylePen, m_pasStyleValue,
    2693         453 :                                static_cast<int>(OGRSTPenLast));
    2694             : }
    2695             : 
    2696             : /************************************************************************/
    2697             : /*                            GetParamStr()                             */
    2698             : /************************************************************************/
    2699          89 : const char *OGRStylePen::GetParamStr(OGRSTPenParam eParam, GBool &bValueIsNull)
    2700             : {
    2701         178 :     return OGRStyleTool::GetParamStr(asStylePen[eParam],
    2702          89 :                                      m_pasStyleValue[eParam], bValueIsNull);
    2703             : }
    2704             : 
    2705             : /************************************************************************/
    2706             : /*                            GetParamNum()                             */
    2707             : /************************************************************************/
    2708           0 : int OGRStylePen::GetParamNum(OGRSTPenParam eParam, GBool &bValueIsNull)
    2709             : {
    2710           0 :     return OGRStyleTool::GetParamNum(asStylePen[eParam],
    2711           0 :                                      m_pasStyleValue[eParam], bValueIsNull);
    2712             : }
    2713             : 
    2714             : /************************************************************************/
    2715             : /*                            GetParamDbl()                             */
    2716             : /************************************************************************/
    2717          14 : double OGRStylePen::GetParamDbl(OGRSTPenParam eParam, GBool &bValueIsNull)
    2718             : {
    2719          28 :     return OGRStyleTool::GetParamDbl(asStylePen[eParam],
    2720          14 :                                      m_pasStyleValue[eParam], bValueIsNull);
    2721             : }
    2722             : 
    2723             : /************************************************************************/
    2724             : /*                           GetRawParamDbl()                           */
    2725             : /************************************************************************/
    2726          32 : double OGRStylePen::GetRawParamDbl(OGRSTPenParam eParam, OGRSTUnitId &eRawUnit,
    2727             :                                    GBool &bValueIsNull)
    2728             : {
    2729          64 :     return OGRStyleTool::GetRawParamDbl(
    2730          32 :         asStylePen[eParam], m_pasStyleValue[eParam], eRawUnit, bValueIsNull);
    2731             : }
    2732             : 
    2733             : /************************************************************************/
    2734             : /*                            SetParamStr()                             */
    2735             : /************************************************************************/
    2736             : 
    2737          53 : void OGRStylePen::SetParamStr(OGRSTPenParam eParam, const char *pszParamString)
    2738             : {
    2739          53 :     OGRStyleTool::SetParamStr(asStylePen[eParam], m_pasStyleValue[eParam],
    2740             :                               pszParamString);
    2741          53 : }
    2742             : 
    2743             : /************************************************************************/
    2744             : /*                            SetParamNum()                             */
    2745             : /************************************************************************/
    2746           0 : void OGRStylePen::SetParamNum(OGRSTPenParam eParam, int nParam)
    2747             : {
    2748           0 :     OGRStyleTool::SetParamNum(asStylePen[eParam], m_pasStyleValue[eParam],
    2749             :                               nParam);
    2750           0 : }
    2751             : 
    2752             : /************************************************************************/
    2753             : /*                            SetParamDbl()                             */
    2754             : /************************************************************************/
    2755          83 : void OGRStylePen::SetParamDbl(OGRSTPenParam eParam, double dfParam)
    2756             : {
    2757          83 :     OGRStyleTool::SetParamDbl(asStylePen[eParam], m_pasStyleValue[eParam],
    2758             :                               dfParam);
    2759          83 : }
    2760             : 
    2761             : /************************************************************************/
    2762             : /*                           GetStyleString()                           */
    2763             : /************************************************************************/
    2764         396 : const char *OGRStylePen::GetStyleString()
    2765             : {
    2766         396 :     return OGRStyleTool::GetStyleString(asStylePen, m_pasStyleValue,
    2767         396 :                                         static_cast<int>(OGRSTPenLast));
    2768             : }
    2769             : 
    2770             : /****************************************************************************/
    2771             : /*                      OGRStyleBrush::OGRStyleBrush()                      */
    2772             : /*                                                                          */
    2773             : /****************************************************************************/
    2774         139 : OGRStyleBrush::OGRStyleBrush()
    2775             :     : OGRStyleTool(OGRSTCBrush),
    2776             :       m_pasStyleValue(static_cast<OGRStyleValue *>(
    2777         139 :           CPLCalloc(OGRSTBrushLast, sizeof(OGRStyleValue))))
    2778             : {
    2779         139 : }
    2780             : 
    2781             : /****************************************************************************/
    2782             : /*                      OGRStyleBrush::~OGRStyleBrush()                     */
    2783             : /*                                                                          */
    2784             : /****************************************************************************/
    2785         278 : OGRStyleBrush::~OGRStyleBrush()
    2786             : {
    2787        1251 :     for (int i = 0; i < OGRSTBrushLast; i++)
    2788             :     {
    2789        1112 :         if (m_pasStyleValue[i].pszValue != nullptr)
    2790             :         {
    2791         170 :             CPLFree(m_pasStyleValue[i].pszValue);
    2792         170 :             m_pasStyleValue[i].pszValue = nullptr;
    2793             :         }
    2794             :     }
    2795             : 
    2796         139 :     CPLFree(m_pasStyleValue);
    2797         278 : }
    2798             : 
    2799             : /************************************************************************/
    2800             : /*                               Parse()                                */
    2801             : /************************************************************************/
    2802         283 : GBool OGRStyleBrush::Parse()
    2803             : {
    2804         283 :     return OGRStyleTool::Parse(asStyleBrush, m_pasStyleValue,
    2805         283 :                                static_cast<int>(OGRSTBrushLast));
    2806             : }
    2807             : 
    2808             : /************************************************************************/
    2809             : /*                            GetParamStr()                             */
    2810             : /************************************************************************/
    2811          91 : const char *OGRStyleBrush::GetParamStr(OGRSTBrushParam eParam,
    2812             :                                        GBool &bValueIsNull)
    2813             : {
    2814         182 :     return OGRStyleTool::GetParamStr(asStyleBrush[eParam],
    2815          91 :                                      m_pasStyleValue[eParam], bValueIsNull);
    2816             : }
    2817             : 
    2818             : /************************************************************************/
    2819             : /*                            GetParamNum()                             */
    2820             : /************************************************************************/
    2821           0 : int OGRStyleBrush::GetParamNum(OGRSTBrushParam eParam, GBool &bValueIsNull)
    2822             : {
    2823           0 :     return OGRStyleTool::GetParamNum(asStyleBrush[eParam],
    2824           0 :                                      m_pasStyleValue[eParam], bValueIsNull);
    2825             : }
    2826             : 
    2827             : /************************************************************************/
    2828             : /*                            GetParamDbl()                             */
    2829             : /************************************************************************/
    2830          20 : double OGRStyleBrush::GetParamDbl(OGRSTBrushParam eParam, GBool &bValueIsNull)
    2831             : {
    2832          40 :     return OGRStyleTool::GetParamDbl(asStyleBrush[eParam],
    2833          20 :                                      m_pasStyleValue[eParam], bValueIsNull);
    2834             : }
    2835             : 
    2836             : /************************************************************************/
    2837             : /*                            SetParamStr()                             */
    2838             : /************************************************************************/
    2839          83 : void OGRStyleBrush::SetParamStr(OGRSTBrushParam eParam,
    2840             :                                 const char *pszParamString)
    2841             : {
    2842          83 :     OGRStyleTool::SetParamStr(asStyleBrush[eParam], m_pasStyleValue[eParam],
    2843             :                               pszParamString);
    2844          83 : }
    2845             : 
    2846             : /************************************************************************/
    2847             : /*                            SetParamNum()                             */
    2848             : /************************************************************************/
    2849           0 : void OGRStyleBrush::SetParamNum(OGRSTBrushParam eParam, int nParam)
    2850             : {
    2851           0 :     OGRStyleTool::SetParamNum(asStyleBrush[eParam], m_pasStyleValue[eParam],
    2852             :                               nParam);
    2853           0 : }
    2854             : 
    2855             : /************************************************************************/
    2856             : /*                            SetParamDbl()                             */
    2857             : /************************************************************************/
    2858           0 : void OGRStyleBrush::SetParamDbl(OGRSTBrushParam eParam, double dfParam)
    2859             : {
    2860           0 :     OGRStyleTool::SetParamDbl(asStyleBrush[eParam], m_pasStyleValue[eParam],
    2861             :                               dfParam);
    2862           0 : }
    2863             : 
    2864             : /************************************************************************/
    2865             : /*                           GetStyleString()                           */
    2866             : /************************************************************************/
    2867         170 : const char *OGRStyleBrush::GetStyleString()
    2868             : {
    2869         170 :     return OGRStyleTool::GetStyleString(asStyleBrush, m_pasStyleValue,
    2870         170 :                                         static_cast<int>(OGRSTBrushLast));
    2871             : }
    2872             : 
    2873             : /****************************************************************************/
    2874             : /*                      OGRStyleSymbol::OGRStyleSymbol()                    */
    2875             : /****************************************************************************/
    2876         332 : OGRStyleSymbol::OGRStyleSymbol()
    2877             :     : OGRStyleTool(OGRSTCSymbol),
    2878             :       m_pasStyleValue(static_cast<OGRStyleValue *>(
    2879         332 :           CPLCalloc(OGRSTSymbolLast, sizeof(OGRStyleValue))))
    2880             : {
    2881         332 : }
    2882             : 
    2883             : /****************************************************************************/
    2884             : /*                      OGRStyleSymbol::~OGRStyleSymbol()                   */
    2885             : /*                                                                          */
    2886             : /****************************************************************************/
    2887         664 : OGRStyleSymbol::~OGRStyleSymbol()
    2888             : {
    2889        4316 :     for (int i = 0; i < OGRSTSymbolLast; i++)
    2890             :     {
    2891        3984 :         if (m_pasStyleValue[i].pszValue != nullptr)
    2892             :         {
    2893         619 :             CPLFree(m_pasStyleValue[i].pszValue);
    2894         619 :             m_pasStyleValue[i].pszValue = nullptr;
    2895             :         }
    2896             :     }
    2897             : 
    2898         332 :     CPLFree(m_pasStyleValue);
    2899         664 : }
    2900             : 
    2901             : /************************************************************************/
    2902             : /*                               Parse()                                */
    2903             : /************************************************************************/
    2904        1765 : GBool OGRStyleSymbol::Parse()
    2905             : {
    2906        1765 :     return OGRStyleTool::Parse(asStyleSymbol, m_pasStyleValue,
    2907        1765 :                                static_cast<int>(OGRSTSymbolLast));
    2908             : }
    2909             : 
    2910             : /************************************************************************/
    2911             : /*                            GetParamStr()                             */
    2912             : /************************************************************************/
    2913         451 : const char *OGRStyleSymbol::GetParamStr(OGRSTSymbolParam eParam,
    2914             :                                         GBool &bValueIsNull)
    2915             : {
    2916         902 :     return OGRStyleTool::GetParamStr(asStyleSymbol[eParam],
    2917         451 :                                      m_pasStyleValue[eParam], bValueIsNull);
    2918             : }
    2919             : 
    2920             : /************************************************************************/
    2921             : /*                            GetParamNum()                             */
    2922             : /************************************************************************/
    2923           0 : int OGRStyleSymbol::GetParamNum(OGRSTSymbolParam eParam, GBool &bValueIsNull)
    2924             : {
    2925           0 :     return OGRStyleTool::GetParamNum(asStyleSymbol[eParam],
    2926           0 :                                      m_pasStyleValue[eParam], bValueIsNull);
    2927             : }
    2928             : 
    2929             : /************************************************************************/
    2930             : /*                            GetParamDbl()                             */
    2931             : /************************************************************************/
    2932         192 : double OGRStyleSymbol::GetParamDbl(OGRSTSymbolParam eParam, GBool &bValueIsNull)
    2933             : {
    2934         384 :     return OGRStyleTool::GetParamDbl(asStyleSymbol[eParam],
    2935         192 :                                      m_pasStyleValue[eParam], bValueIsNull);
    2936             : }
    2937             : 
    2938             : /************************************************************************/
    2939             : /*                            SetParamStr()                             */
    2940             : /************************************************************************/
    2941          63 : void OGRStyleSymbol::SetParamStr(OGRSTSymbolParam eParam,
    2942             :                                  const char *pszParamString)
    2943             : {
    2944          63 :     OGRStyleTool::SetParamStr(asStyleSymbol[eParam], m_pasStyleValue[eParam],
    2945             :                               pszParamString);
    2946          63 : }
    2947             : 
    2948             : /************************************************************************/
    2949             : /*                            SetParamNum()                             */
    2950             : /************************************************************************/
    2951           0 : void OGRStyleSymbol::SetParamNum(OGRSTSymbolParam eParam, int nParam)
    2952             : {
    2953           0 :     OGRStyleTool::SetParamNum(asStyleSymbol[eParam], m_pasStyleValue[eParam],
    2954             :                               nParam);
    2955           0 : }
    2956             : 
    2957             : /************************************************************************/
    2958             : /*                            SetParamDbl()                             */
    2959             : /************************************************************************/
    2960          10 : void OGRStyleSymbol::SetParamDbl(OGRSTSymbolParam eParam, double dfParam)
    2961             : {
    2962          10 :     OGRStyleTool::SetParamDbl(asStyleSymbol[eParam], m_pasStyleValue[eParam],
    2963             :                               dfParam);
    2964          10 : }
    2965             : 
    2966             : /************************************************************************/
    2967             : /*                           GetStyleString()                           */
    2968             : /************************************************************************/
    2969         110 : const char *OGRStyleSymbol::GetStyleString()
    2970             : {
    2971         110 :     return OGRStyleTool::GetStyleString(asStyleSymbol, m_pasStyleValue,
    2972         110 :                                         static_cast<int>(OGRSTSymbolLast));
    2973             : }
    2974             : 
    2975             : /****************************************************************************/
    2976             : /*                      OGRStyleLabel::OGRStyleLabel()                      */
    2977             : /*                                                                          */
    2978             : /****************************************************************************/
    2979          24 : OGRStyleLabel::OGRStyleLabel()
    2980             :     : OGRStyleTool(OGRSTCLabel),
    2981             :       m_pasStyleValue(static_cast<OGRStyleValue *>(
    2982          24 :           CPLCalloc(OGRSTLabelLast, sizeof(OGRStyleValue))))
    2983             : {
    2984          24 : }
    2985             : 
    2986             : /****************************************************************************/
    2987             : /*                      OGRStyleLabel::~OGRStyleLabel()                     */
    2988             : /*                                                                          */
    2989             : /****************************************************************************/
    2990          48 : OGRStyleLabel::~OGRStyleLabel()
    2991             : {
    2992         528 :     for (int i = 0; i < OGRSTLabelLast; i++)
    2993             :     {
    2994         504 :         if (m_pasStyleValue[i].pszValue != nullptr)
    2995             :         {
    2996          42 :             CPLFree(m_pasStyleValue[i].pszValue);
    2997          42 :             m_pasStyleValue[i].pszValue = nullptr;
    2998             :         }
    2999             :     }
    3000             : 
    3001          24 :     CPLFree(m_pasStyleValue);
    3002          48 : }
    3003             : 
    3004             : /************************************************************************/
    3005             : /*                               Parse()                                */
    3006             : /************************************************************************/
    3007         281 : GBool OGRStyleLabel::Parse()
    3008             : {
    3009         281 :     return OGRStyleTool::Parse(asStyleLabel, m_pasStyleValue,
    3010         281 :                                static_cast<int>(OGRSTLabelLast));
    3011             : }
    3012             : 
    3013             : /************************************************************************/
    3014             : /*                            GetParamStr()                             */
    3015             : /************************************************************************/
    3016          62 : const char *OGRStyleLabel::GetParamStr(OGRSTLabelParam eParam,
    3017             :                                        GBool &bValueIsNull)
    3018             : {
    3019         124 :     return OGRStyleTool::GetParamStr(asStyleLabel[eParam],
    3020          62 :                                      m_pasStyleValue[eParam], bValueIsNull);
    3021             : }
    3022             : 
    3023             : /************************************************************************/
    3024             : /*                            GetParamNum()                             */
    3025             : /************************************************************************/
    3026          49 : int OGRStyleLabel::GetParamNum(OGRSTLabelParam eParam, GBool &bValueIsNull)
    3027             : {
    3028          98 :     return OGRStyleTool::GetParamNum(asStyleLabel[eParam],
    3029          49 :                                      m_pasStyleValue[eParam], bValueIsNull);
    3030             : }
    3031             : 
    3032             : /************************************************************************/
    3033             : /*                            GetParamDbl()                             */
    3034             : /************************************************************************/
    3035          77 : double OGRStyleLabel::GetParamDbl(OGRSTLabelParam eParam, GBool &bValueIsNull)
    3036             : {
    3037         154 :     return OGRStyleTool::GetParamDbl(asStyleLabel[eParam],
    3038          77 :                                      m_pasStyleValue[eParam], bValueIsNull);
    3039             : }
    3040             : 
    3041             : /************************************************************************/
    3042             : /*                            SetParamStr()                             */
    3043             : /************************************************************************/
    3044           5 : void OGRStyleLabel::SetParamStr(OGRSTLabelParam eParam,
    3045             :                                 const char *pszParamString)
    3046             : {
    3047           5 :     OGRStyleTool::SetParamStr(asStyleLabel[eParam], m_pasStyleValue[eParam],
    3048             :                               pszParamString);
    3049           5 : }
    3050             : 
    3051             : /************************************************************************/
    3052             : /*                            SetParamNum()                             */
    3053             : /************************************************************************/
    3054           0 : void OGRStyleLabel::SetParamNum(OGRSTLabelParam eParam, int nParam)
    3055             : {
    3056           0 :     OGRStyleTool::SetParamNum(asStyleLabel[eParam], m_pasStyleValue[eParam],
    3057             :                               nParam);
    3058           0 : }
    3059             : 
    3060             : /************************************************************************/
    3061             : /*                            SetParamDbl()                             */
    3062             : /************************************************************************/
    3063           5 : void OGRStyleLabel::SetParamDbl(OGRSTLabelParam eParam, double dfParam)
    3064             : {
    3065           5 :     OGRStyleTool::SetParamDbl(asStyleLabel[eParam], m_pasStyleValue[eParam],
    3066             :                               dfParam);
    3067           5 : }
    3068             : 
    3069             : /************************************************************************/
    3070             : /*                           GetStyleString()                           */
    3071             : /************************************************************************/
    3072          10 : const char *OGRStyleLabel::GetStyleString()
    3073             : {
    3074          10 :     return OGRStyleTool::GetStyleString(asStyleLabel, m_pasStyleValue,
    3075          10 :                                         static_cast<int>(OGRSTLabelLast));
    3076             : }
    3077             : 
    3078             : //! @endcond

Generated by: LCOV version 1.14