LCOV - code coverage report
Current view: top level - ogr - ogrfeaturestyle.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 608 973 62.5 %
Date: 2025-09-10 17:48:50 Functions: 97 123 78.9 %

          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         664 :     while ((pszPart = strstr(pszStrTmp, ";")) != nullptr && pszPart[1] != '\0')
     590             :     {
     591          81 :         pszStrTmp = &pszPart[1];
     592          81 :         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         497 : OGRStyleTool *OGRStyleMgr::GetPart(int nPartId, const char *pszStyleString)
     644             : {
     645         497 :     const char *pszStyle = pszStyleString ? pszStyleString : m_pszStyleString;
     646             : 
     647         497 :     if (pszStyle == nullptr)
     648           1 :         return nullptr;
     649             : 
     650         496 :     char **papszStyleString = CSLTokenizeString2(
     651             :         pszStyle, ";",
     652             :         CSLT_HONOURSTRINGS | CSLT_PRESERVEQUOTES | CSLT_PRESERVEESCAPES);
     653             : 
     654         496 :     const char *pszString = CSLGetField(papszStyleString, nPartId);
     655             : 
     656         496 :     OGRStyleTool *poStyleTool = nullptr;
     657         496 :     if (strlen(pszString) > 0)
     658             :     {
     659         495 :         poStyleTool = CreateStyleToolFromStyleString(pszString);
     660         495 :         if (poStyleTool)
     661         495 :             poStyleTool->SetStyleString(pszString);
     662             :     }
     663             : 
     664         496 :     CSLDestroy(papszStyleString);
     665             : 
     666         496 :     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         495 : OGRStyleMgr::CreateStyleToolFromStyleString(const char *pszStyleString)
     709             : {
     710         495 :     char **papszToken = CSLTokenizeString2(
     711             :         pszStyleString, "();",
     712             :         CSLT_HONOURSTRINGS | CSLT_PRESERVEQUOTES | CSLT_PRESERVEESCAPES);
     713         495 :     OGRStyleTool *poStyleTool = nullptr;
     714             : 
     715         495 :     if (CSLCount(papszToken) < 2)
     716           0 :         poStyleTool = nullptr;
     717         495 :     else if (EQUAL(papszToken[0], "PEN"))
     718         140 :         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         495 :     CSLDestroy(papszToken);
     729             : 
     730         495 :     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         748 : OGRStyleTool::OGRStyleTool(OGRSTClassId eClassId) : m_eClassId(eClassId)
    1322             : {
    1323         748 : }
    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        1496 : OGRStyleTool::~OGRStyleTool()
    1363             : {
    1364         748 :     CPLFree(m_pszStyleString);
    1365         748 : }
    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         495 : void OGRStyleTool::SetStyleString(const char *pszStyleString)
    1391             : {
    1392         495 :     m_pszStyleString = CPLStrdup(pszStyleString);
    1393         495 : }
    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        1573 : OGRSTClassId OGRStyleTool::GetType()
    1597             : {
    1598        1573 :     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         655 : void OGRStyleTool::SetUnit(OGRSTUnitId eUnit, double dfGroundPaperScale)
    1659             : {
    1660         655 :     m_eUnit = eUnit;
    1661         655 :     m_dfScale = dfGroundPaperScale;
    1662         655 : }
    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        2801 : GBool OGRStyleTool::Parse(const OGRStyleParamId *pasStyle,
    1692             :                           OGRStyleValue *pasValue, int nCount)
    1693             : {
    1694        2801 :     if (IsStyleParsed())
    1695        2182 :         return TRUE;
    1696             : 
    1697         619 :     StyleParsed();
    1698             : 
    1699         619 :     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         752 :     char **papszToken = CSLTokenizeString2(
    1706         376 :         m_pszStyleString, "()",
    1707             :         CSLT_HONOURSTRINGS | CSLT_PRESERVEQUOTES | CSLT_PRESERVEESCAPES);
    1708             : 
    1709         376 :     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         752 :     char **papszToken2 = CSLTokenizeString2(
    1720         376 :         papszToken[1], ",",
    1721             :         CSLT_HONOURSTRINGS | CSLT_PRESERVEQUOTES | CSLT_PRESERVEESCAPES);
    1722             : 
    1723             :     // Valid that we have the right StyleString for this feature type.
    1724         376 :     switch (GetType())
    1725             :     {
    1726          45 :         case OGRSTCPen:
    1727          45 :             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          45 :             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         376 :     OGRSTUnitId eLastUnit = m_eUnit;
    1805         376 :     double dSavedScale = m_dfScale;
    1806         376 :     const int nElements = CSLCount(papszToken2);
    1807             : 
    1808        1777 :     for (int i = 0; i < nElements; i++)
    1809             :     {
    1810             :         char **papszStylePair =
    1811        1401 :             CSLTokenizeString2(papszToken2[i], ":",
    1812             :                                CSLT_HONOURSTRINGS | CSLT_STRIPLEADSPACES |
    1813             :                                    CSLT_STRIPENDSPACES | CSLT_ALLOWEMPTYTOKENS);
    1814             : 
    1815        1401 :         const int nTokens = CSLCount(papszStylePair);
    1816             : 
    1817        1401 :         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        3980 :         for (int j = 0; j < nCount; j++)
    1829             :         {
    1830        3980 :             if (pasStyle[j].pszToken &&
    1831        3978 :                 EQUAL(pasStyle[j].pszToken, papszStylePair[0]))
    1832             :             {
    1833        1401 :                 if (papszStylePair[1] != nullptr && pasStyle[j].bGeoref == TRUE)
    1834         334 :                     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        1401 :                 OGRStyleTool::SetParamStr(
    1840        1401 :                     pasStyle[j], pasValue[j],
    1841        1401 :                     papszStylePair[1] != nullptr ? papszStylePair[1] : "1");
    1842             : 
    1843        1401 :                 break;
    1844             :             }
    1845             :         }
    1846             : 
    1847        1401 :         CSLDestroy(papszStylePair);
    1848             :     }
    1849             : 
    1850         376 :     m_eUnit = eLastUnit;
    1851         376 :     m_dfScale = dSavedScale;
    1852             : 
    1853         376 :     CSLDestroy(papszToken2);
    1854         376 :     CSLDestroy(papszToken);
    1855             : 
    1856         376 :     return TRUE;
    1857             : }
    1858             : 
    1859             : //! @endcond
    1860             : 
    1861             : /************************************************************************/
    1862             : /*                   SetInternalInputUnitFromParam()                    */
    1863             : /************************************************************************/
    1864             : 
    1865             : //! @cond Doxygen_Suppress
    1866         334 : void OGRStyleTool::SetInternalInputUnitFromParam(char *pszString)
    1867             : {
    1868         334 :     if (pszString == nullptr)
    1869           0 :         return;
    1870             : 
    1871         334 :     char *pszUnit = strstr(pszString, "g");
    1872         334 :     if (pszUnit)
    1873             :     {
    1874           8 :         SetUnit(OGRSTUGround);
    1875           8 :         pszUnit[0] = '\0';
    1876           8 :         return;
    1877             :     }
    1878         326 :     pszUnit = strstr(pszString, "px");
    1879         326 :     if (pszUnit)
    1880             :     {
    1881          36 :         SetUnit(OGRSTUPixel);
    1882          36 :         pszUnit[0] = '\0';
    1883          36 :         return;
    1884             :     }
    1885         290 :     pszUnit = strstr(pszString, "pt");
    1886         290 :     if (pszUnit)
    1887             :     {
    1888         232 :         SetUnit(OGRSTUPoints);
    1889         232 :         pszUnit[0] = '\0';
    1890         232 :         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         255 : double OGRStyleTool::ComputeWithUnit(double dfValue, OGRSTUnitId eInputUnit)
    1921             : {
    1922         255 :     OGRSTUnitId eOutputUnit = GetUnit();
    1923             : 
    1924         255 :     double dfNewValue = dfValue;  // dfValue in meters;
    1925             : 
    1926         255 :     if (eOutputUnit == eInputUnit)
    1927         174 :         return dfValue;
    1928             : 
    1929          81 :     switch (eInputUnit)
    1930             :     {
    1931           5 :         case OGRSTUGround:
    1932           5 :             dfNewValue = dfValue / m_dfScale;
    1933           5 :             break;
    1934          61 :         case OGRSTUPixel:
    1935          61 :             dfNewValue = dfValue / (72.0 * 39.37);
    1936          61 :             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          81 :     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          58 :         case OGRSTUPoints:
    1962          58 :             dfNewValue *= 72.0 * 39.37;
    1963          58 :             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          81 :     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         687 : const char *OGRStyleTool::GetParamStr(const OGRStyleParamId &sStyleParam,
    2001             :                                       const OGRStyleValue &sStyleValue,
    2002             :                                       GBool &bValueIsNull)
    2003             : {
    2004         687 :     if (!Parse())
    2005             :     {
    2006           0 :         bValueIsNull = TRUE;
    2007           0 :         return nullptr;
    2008             :     }
    2009             : 
    2010         687 :     bValueIsNull = !sStyleValue.bValid;
    2011             : 
    2012         687 :     if (bValueIsNull == TRUE)
    2013          36 :         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         411 : double OGRStyleTool::GetParamDbl(const OGRStyleParamId &sStyleParam,
    2076             :                                  const OGRStyleValue &sStyleValue,
    2077             :                                  GBool &bValueIsNull)
    2078             : {
    2079         411 :     if (!Parse())
    2080             :     {
    2081           0 :         bValueIsNull = TRUE;
    2082           0 :         return 0.0;
    2083             :     }
    2084             : 
    2085         411 :     bValueIsNull = !sStyleValue.bValid;
    2086             : 
    2087         411 :     if (bValueIsNull == TRUE)
    2088         126 :         return 0.0;
    2089             : 
    2090         285 :     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         272 :         case OGRSTypeDouble:
    2100         272 :             if (sStyleParam.bGeoref)
    2101         255 :                 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             : /*      void OGRStyleTool::SetParamStr(OGRStyleParamId &sStyleParam ,       */
    2120             : /*                             OGRStyleValue &sStyleValue,                  */
    2121             : /*                             const char *pszParamString)                  */
    2122             : /*                                                                          */
    2123             : /****************************************************************************/
    2124             : 
    2125             : /** Undocumented
    2126             :  * @param sStyleParam undocumented.
    2127             :  * @param sStyleValue undocumented.
    2128             :  * @param pszParamString undocumented.
    2129             :  */
    2130        1605 : void OGRStyleTool::SetParamStr(const OGRStyleParamId &sStyleParam,
    2131             :                                OGRStyleValue &sStyleValue,
    2132             :                                const char *pszParamString)
    2133             : {
    2134        1605 :     Parse();
    2135        1605 :     StyleModified();
    2136        1605 :     sStyleValue.bValid = TRUE;
    2137        1605 :     sStyleValue.eUnit = GetUnit();
    2138        1605 :     switch (sStyleParam.eType)
    2139             :     {
    2140             :         // If sStyleParam.bGeoref == TRUE, need to convert to output value;
    2141        1023 :         case OGRSTypeString:
    2142        1023 :             sStyleValue.pszValue = CPLStrdup(pszParamString);
    2143        1023 :             break;
    2144         569 :         case OGRSTypeDouble:
    2145         569 :             sStyleValue.dfValue = CPLAtof(pszParamString);
    2146         569 :             break;
    2147           7 :         case OGRSTypeInteger:
    2148           7 :             sStyleValue.nValue = atoi(pszParamString);
    2149           7 :             break;
    2150           6 :         case OGRSTypeBoolean:
    2151           6 :             sStyleValue.nValue = atoi(pszParamString) != 0;
    2152           6 :             break;
    2153           0 :         default:
    2154           0 :             sStyleValue.bValid = FALSE;
    2155           0 :             break;
    2156             :     }
    2157        1605 : }
    2158             : 
    2159             : /****************************************************************************/
    2160             : /*    void OGRStyleTool::SetParamNum(OGRStyleParamId &sStyleParam ,         */
    2161             : /*                             OGRStyleValue &sStyleValue,                  */
    2162             : /*                             int nParam)                                  */
    2163             : /*                                                                          */
    2164             : /****************************************************************************/
    2165             : 
    2166             : /** Undocumented
    2167             :  * @param sStyleParam undocumented.
    2168             :  * @param sStyleValue undocumented.
    2169             :  * @param nParam undocumented.
    2170             :  */
    2171           0 : void OGRStyleTool::SetParamNum(const OGRStyleParamId &sStyleParam,
    2172             :                                OGRStyleValue &sStyleValue, int nParam)
    2173             : {
    2174           0 :     Parse();
    2175           0 :     StyleModified();
    2176           0 :     sStyleValue.bValid = TRUE;
    2177           0 :     sStyleValue.eUnit = GetUnit();
    2178           0 :     switch (sStyleParam.eType)
    2179             :     {
    2180             : 
    2181             :         // If sStyleParam.bGeoref == TRUE, need to convert to output value;
    2182           0 :         case OGRSTypeString:
    2183           0 :             sStyleValue.pszValue = CPLStrdup(CPLString().Printf("%d", nParam));
    2184           0 :             break;
    2185           0 :         case OGRSTypeDouble:
    2186           0 :             sStyleValue.dfValue = static_cast<double>(nParam);
    2187           0 :             break;
    2188           0 :         case OGRSTypeInteger:
    2189           0 :             sStyleValue.nValue = nParam;
    2190           0 :             break;
    2191           0 :         case OGRSTypeBoolean:
    2192           0 :             sStyleValue.nValue = nParam != 0;
    2193           0 :             break;
    2194           0 :         default:
    2195           0 :             sStyleValue.bValid = FALSE;
    2196           0 :             break;
    2197             :     }
    2198           0 : }
    2199             : 
    2200             : /****************************************************************************/
    2201             : /*      void OGRStyleTool::SetParamDbl(OGRStyleParamId &sStyleParam ,       */
    2202             : /*                             OGRStyleValue &sStyleValue,                  */
    2203             : /*                             double dfParam)                              */
    2204             : /*                                                                          */
    2205             : /****************************************************************************/
    2206             : 
    2207             : /** Undocumented
    2208             :  * @param sStyleParam undocumented.
    2209             :  * @param sStyleValue undocumented.
    2210             :  * @param dfParam undocumented.
    2211             :  */
    2212          98 : void OGRStyleTool::SetParamDbl(const OGRStyleParamId &sStyleParam,
    2213             :                                OGRStyleValue &sStyleValue, double dfParam)
    2214             : {
    2215          98 :     Parse();
    2216          98 :     StyleModified();
    2217          98 :     sStyleValue.bValid = TRUE;
    2218          98 :     sStyleValue.eUnit = GetUnit();
    2219          98 :     switch (sStyleParam.eType)
    2220             :     {
    2221             :         // If sStyleParam.bGeoref == TRUE, need to convert to output value;
    2222           0 :         case OGRSTypeString:
    2223           0 :             sStyleValue.pszValue = CPLStrdup(CPLString().Printf("%f", dfParam));
    2224           0 :             break;
    2225          98 :         case OGRSTypeDouble:
    2226          98 :             sStyleValue.dfValue = dfParam;
    2227          98 :             break;
    2228           0 :         case OGRSTypeInteger:
    2229           0 :             sStyleValue.nValue = static_cast<int>(dfParam);
    2230           0 :             break;
    2231           0 :         case OGRSTypeBoolean:
    2232           0 :             sStyleValue.nValue = static_cast<int>(dfParam) != 0;
    2233           0 :             break;
    2234           0 :         default:
    2235           0 :             sStyleValue.bValid = FALSE;
    2236           0 :             break;
    2237             :     }
    2238          98 : }
    2239             : 
    2240             : /************************************************************************/
    2241             : /*                           OGR_ST_GetParamStr()                       */
    2242             : /************************************************************************/
    2243             : /**
    2244             :  * \brief Get Style Tool parameter value as string
    2245             :  *
    2246             :  * Maps to the OGRStyleTool subclasses' GetParamStr() methods.
    2247             :  *
    2248             :  * @param hST handle to the style tool.
    2249             :  * @param eParam the parameter id from the enumeration corresponding to the
    2250             :  * type of this style tool (one of the OGRSTPenParam, OGRSTBrushParam,
    2251             :  * OGRSTSymbolParam or OGRSTLabelParam enumerations)
    2252             :  * @param bValueIsNull pointer to an integer that will be set to TRUE or FALSE
    2253             :  * to indicate whether the parameter value is NULL.
    2254             :  *
    2255             :  * @return the parameter value as string and sets bValueIsNull.
    2256             :  */
    2257             : 
    2258         137 : const char *OGR_ST_GetParamStr(OGRStyleToolH hST, int eParam, int *bValueIsNull)
    2259             : {
    2260         137 :     VALIDATE_POINTER1(hST, "OGR_ST_GetParamStr", "");
    2261         137 :     VALIDATE_POINTER1(bValueIsNull, "OGR_ST_GetParamStr", "");
    2262             : 
    2263         137 :     GBool bIsNull = TRUE;
    2264         137 :     const char *pszVal = "";
    2265             : 
    2266         137 :     switch (reinterpret_cast<OGRStyleTool *>(hST)->GetType())
    2267             :     {
    2268           4 :         case OGRSTCPen:
    2269           4 :             pszVal = reinterpret_cast<OGRStylePen *>(hST)->GetParamStr(
    2270             :                 static_cast<OGRSTPenParam>(eParam), bIsNull);
    2271           4 :             break;
    2272           1 :         case OGRSTCBrush:
    2273           1 :             pszVal = reinterpret_cast<OGRStyleBrush *>(hST)->GetParamStr(
    2274             :                 static_cast<OGRSTBrushParam>(eParam), bIsNull);
    2275           1 :             break;
    2276         102 :         case OGRSTCSymbol:
    2277         102 :             pszVal = reinterpret_cast<OGRStyleSymbol *>(hST)->GetParamStr(
    2278             :                 static_cast<OGRSTSymbolParam>(eParam), bIsNull);
    2279         102 :             break;
    2280          30 :         case OGRSTCLabel:
    2281          30 :             pszVal = reinterpret_cast<OGRStyleLabel *>(hST)->GetParamStr(
    2282             :                 static_cast<OGRSTLabelParam>(eParam), bIsNull);
    2283          30 :             break;
    2284           0 :         default:
    2285           0 :             break;
    2286             :     }
    2287             : 
    2288         137 :     *bValueIsNull = bIsNull;
    2289         137 :     return pszVal;
    2290             : }
    2291             : 
    2292             : /************************************************************************/
    2293             : /*                           OGR_ST_GetParamNum()                       */
    2294             : /************************************************************************/
    2295             : /**
    2296             :  * \brief Get Style Tool parameter value as an integer
    2297             :  *
    2298             :  * Maps to the OGRStyleTool subclasses' GetParamNum() methods.
    2299             :  *
    2300             :  * @param hST handle to the style tool.
    2301             :  * @param eParam the parameter id from the enumeration corresponding to the
    2302             :  * type of this style tool (one of the OGRSTPenParam, OGRSTBrushParam,
    2303             :  * OGRSTSymbolParam or OGRSTLabelParam enumerations)
    2304             :  * @param bValueIsNull pointer to an integer that will be set to TRUE or FALSE
    2305             :  * to indicate whether the parameter value is NULL.
    2306             :  *
    2307             :  * @return the parameter value as integer and sets bValueIsNull.
    2308             :  */
    2309             : 
    2310          30 : int OGR_ST_GetParamNum(OGRStyleToolH hST, int eParam, int *bValueIsNull)
    2311             : {
    2312          30 :     VALIDATE_POINTER1(hST, "OGR_ST_GetParamNum", 0);
    2313          30 :     VALIDATE_POINTER1(bValueIsNull, "OGR_ST_GetParamNum", 0);
    2314             : 
    2315          30 :     GBool bIsNull = TRUE;
    2316          30 :     int nVal = 0;
    2317             : 
    2318          30 :     switch (reinterpret_cast<OGRStyleTool *>(hST)->GetType())
    2319             :     {
    2320           0 :         case OGRSTCPen:
    2321           0 :             nVal = reinterpret_cast<OGRStylePen *>(hST)->GetParamNum(
    2322             :                 static_cast<OGRSTPenParam>(eParam), bIsNull);
    2323           0 :             break;
    2324           0 :         case OGRSTCBrush:
    2325           0 :             nVal = reinterpret_cast<OGRStyleBrush *>(hST)->GetParamNum(
    2326             :                 static_cast<OGRSTBrushParam>(eParam), bIsNull);
    2327           0 :             break;
    2328           0 :         case OGRSTCSymbol:
    2329           0 :             nVal = reinterpret_cast<OGRStyleSymbol *>(hST)->GetParamNum(
    2330             :                 static_cast<OGRSTSymbolParam>(eParam), bIsNull);
    2331           0 :             break;
    2332          30 :         case OGRSTCLabel:
    2333          30 :             nVal = reinterpret_cast<OGRStyleLabel *>(hST)->GetParamNum(
    2334             :                 static_cast<OGRSTLabelParam>(eParam), bIsNull);
    2335          30 :             break;
    2336           0 :         default:
    2337           0 :             break;
    2338             :     }
    2339             : 
    2340          30 :     *bValueIsNull = bIsNull;
    2341          30 :     return nVal;
    2342             : }
    2343             : 
    2344             : /************************************************************************/
    2345             : /*                           OGR_ST_GetParamDbl()                       */
    2346             : /************************************************************************/
    2347             : /**
    2348             :  * \brief Get Style Tool parameter value as a double
    2349             :  *
    2350             :  * Maps to the OGRStyleTool subclasses' GetParamDbl() methods.
    2351             :  *
    2352             :  * @param hST handle to the style tool.
    2353             :  * @param eParam the parameter id from the enumeration corresponding to the
    2354             :  * type of this style tool (one of the OGRSTPenParam, OGRSTBrushParam,
    2355             :  * OGRSTSymbolParam or OGRSTLabelParam enumerations)
    2356             :  * @param bValueIsNull pointer to an integer that will be set to TRUE or FALSE
    2357             :  * to indicate whether the parameter value is NULL.
    2358             :  *
    2359             :  * @return the parameter value as double and sets bValueIsNull.
    2360             :  */
    2361             : 
    2362         105 : double OGR_ST_GetParamDbl(OGRStyleToolH hST, int eParam, int *bValueIsNull)
    2363             : {
    2364         105 :     VALIDATE_POINTER1(hST, "OGR_ST_GetParamDbl", 0.0);
    2365         105 :     VALIDATE_POINTER1(bValueIsNull, "OGR_ST_GetParamDbl", 0.0);
    2366             : 
    2367         105 :     GBool bIsNull = TRUE;
    2368         105 :     double dfVal = 0.0;
    2369             : 
    2370         105 :     switch (reinterpret_cast<OGRStyleTool *>(hST)->GetType())
    2371             :     {
    2372           4 :         case OGRSTCPen:
    2373           4 :             dfVal = reinterpret_cast<OGRStylePen *>(hST)->GetParamDbl(
    2374             :                 static_cast<OGRSTPenParam>(eParam), bIsNull);
    2375           4 :             break;
    2376           0 :         case OGRSTCBrush:
    2377           0 :             dfVal = reinterpret_cast<OGRStyleBrush *>(hST)->GetParamDbl(
    2378             :                 static_cast<OGRSTBrushParam>(eParam), bIsNull);
    2379           0 :             break;
    2380          51 :         case OGRSTCSymbol:
    2381          51 :             dfVal = reinterpret_cast<OGRStyleSymbol *>(hST)->GetParamDbl(
    2382             :                 static_cast<OGRSTSymbolParam>(eParam), bIsNull);
    2383          51 :             break;
    2384          50 :         case OGRSTCLabel:
    2385          50 :             dfVal = reinterpret_cast<OGRStyleLabel *>(hST)->GetParamDbl(
    2386             :                 static_cast<OGRSTLabelParam>(eParam), bIsNull);
    2387          50 :             break;
    2388           0 :         default:
    2389           0 :             break;
    2390             :     }
    2391             : 
    2392         105 :     *bValueIsNull = bIsNull;
    2393         105 :     return dfVal;
    2394             : }
    2395             : 
    2396             : /************************************************************************/
    2397             : /*                           OGR_ST_SetParamStr()                       */
    2398             : /************************************************************************/
    2399             : /**
    2400             :  * \brief Set Style Tool parameter value from a string
    2401             :  *
    2402             :  * Maps to the OGRStyleTool subclasses' SetParamStr() methods.
    2403             :  *
    2404             :  * @param hST handle to the style tool.
    2405             :  * @param eParam the parameter id from the enumeration corresponding to the
    2406             :  * type of this style tool (one of the OGRSTPenParam, OGRSTBrushParam,
    2407             :  * OGRSTSymbolParam or OGRSTLabelParam enumerations)
    2408             :  * @param pszValue the new parameter value
    2409             :  *
    2410             :  */
    2411             : 
    2412           0 : void OGR_ST_SetParamStr(OGRStyleToolH hST, int eParam, const char *pszValue)
    2413             : {
    2414           0 :     VALIDATE_POINTER0(hST, "OGR_ST_SetParamStr");
    2415           0 :     VALIDATE_POINTER0(pszValue, "OGR_ST_SetParamStr");
    2416             : 
    2417           0 :     switch (reinterpret_cast<OGRStyleTool *>(hST)->GetType())
    2418             :     {
    2419           0 :         case OGRSTCPen:
    2420           0 :             reinterpret_cast<OGRStylePen *>(hST)->SetParamStr(
    2421             :                 static_cast<OGRSTPenParam>(eParam), pszValue);
    2422           0 :             break;
    2423           0 :         case OGRSTCBrush:
    2424           0 :             reinterpret_cast<OGRStyleBrush *>(hST)->SetParamStr(
    2425             :                 static_cast<OGRSTBrushParam>(eParam), pszValue);
    2426           0 :             break;
    2427           0 :         case OGRSTCSymbol:
    2428           0 :             reinterpret_cast<OGRStyleSymbol *>(hST)->SetParamStr(
    2429             :                 static_cast<OGRSTSymbolParam>(eParam), pszValue);
    2430           0 :             break;
    2431           0 :         case OGRSTCLabel:
    2432           0 :             reinterpret_cast<OGRStyleLabel *>(hST)->SetParamStr(
    2433             :                 static_cast<OGRSTLabelParam>(eParam), pszValue);
    2434           0 :             break;
    2435           0 :         default:
    2436           0 :             break;
    2437             :     }
    2438             : }
    2439             : 
    2440             : /************************************************************************/
    2441             : /*                           OGR_ST_SetParamNum()                       */
    2442             : /************************************************************************/
    2443             : /**
    2444             :  * \brief Set Style Tool parameter value from an integer
    2445             :  *
    2446             :  * Maps to the OGRStyleTool subclasses' SetParamNum() methods.
    2447             :  *
    2448             :  * @param hST handle to the style tool.
    2449             :  * @param eParam the parameter id from the enumeration corresponding to the
    2450             :  * type of this style tool (one of the OGRSTPenParam, OGRSTBrushParam,
    2451             :  * OGRSTSymbolParam or OGRSTLabelParam enumerations)
    2452             :  * @param nValue the new parameter value
    2453             :  *
    2454             :  */
    2455             : 
    2456           0 : void OGR_ST_SetParamNum(OGRStyleToolH hST, int eParam, int nValue)
    2457             : {
    2458           0 :     VALIDATE_POINTER0(hST, "OGR_ST_SetParamNum");
    2459             : 
    2460           0 :     switch (reinterpret_cast<OGRStyleTool *>(hST)->GetType())
    2461             :     {
    2462           0 :         case OGRSTCPen:
    2463           0 :             reinterpret_cast<OGRStylePen *>(hST)->SetParamNum(
    2464             :                 static_cast<OGRSTPenParam>(eParam), nValue);
    2465           0 :             break;
    2466           0 :         case OGRSTCBrush:
    2467           0 :             reinterpret_cast<OGRStyleBrush *>(hST)->SetParamNum(
    2468             :                 static_cast<OGRSTBrushParam>(eParam), nValue);
    2469           0 :             break;
    2470           0 :         case OGRSTCSymbol:
    2471           0 :             reinterpret_cast<OGRStyleSymbol *>(hST)->SetParamNum(
    2472             :                 static_cast<OGRSTSymbolParam>(eParam), nValue);
    2473           0 :             break;
    2474           0 :         case OGRSTCLabel:
    2475           0 :             reinterpret_cast<OGRStyleLabel *>(hST)->SetParamNum(
    2476             :                 static_cast<OGRSTLabelParam>(eParam), nValue);
    2477           0 :             break;
    2478           0 :         default:
    2479           0 :             break;
    2480             :     }
    2481             : }
    2482             : 
    2483             : /************************************************************************/
    2484             : /*                           OGR_ST_SetParamDbl()                       */
    2485             : /************************************************************************/
    2486             : /**
    2487             :  * \brief Set Style Tool parameter value from a double
    2488             :  *
    2489             :  * Maps to the OGRStyleTool subclasses' SetParamDbl() methods.
    2490             :  *
    2491             :  * @param hST handle to the style tool.
    2492             :  * @param eParam the parameter id from the enumeration corresponding to the
    2493             :  * type of this style tool (one of the OGRSTPenParam, OGRSTBrushParam,
    2494             :  * OGRSTSymbolParam or OGRSTLabelParam enumerations)
    2495             :  * @param dfValue the new parameter value
    2496             :  *
    2497             :  */
    2498             : 
    2499           0 : void OGR_ST_SetParamDbl(OGRStyleToolH hST, int eParam, double dfValue)
    2500             : {
    2501           0 :     VALIDATE_POINTER0(hST, "OGR_ST_SetParamDbl");
    2502             : 
    2503           0 :     switch (reinterpret_cast<OGRStyleTool *>(hST)->GetType())
    2504             :     {
    2505           0 :         case OGRSTCPen:
    2506           0 :             reinterpret_cast<OGRStylePen *>(hST)->SetParamDbl(
    2507             :                 static_cast<OGRSTPenParam>(eParam), dfValue);
    2508           0 :             break;
    2509           0 :         case OGRSTCBrush:
    2510           0 :             reinterpret_cast<OGRStyleBrush *>(hST)->SetParamDbl(
    2511             :                 static_cast<OGRSTBrushParam>(eParam), dfValue);
    2512           0 :             break;
    2513           0 :         case OGRSTCSymbol:
    2514           0 :             reinterpret_cast<OGRStyleSymbol *>(hST)->SetParamDbl(
    2515             :                 static_cast<OGRSTSymbolParam>(eParam), dfValue);
    2516           0 :             break;
    2517           0 :         case OGRSTCLabel:
    2518           0 :             reinterpret_cast<OGRStyleLabel *>(hST)->SetParamDbl(
    2519             :                 static_cast<OGRSTLabelParam>(eParam), dfValue);
    2520           0 :             break;
    2521           0 :         default:
    2522           0 :             break;
    2523             :     }
    2524             : }
    2525             : 
    2526             : /************************************************************************/
    2527             : /*                           OGR_ST_GetStyleString()                    */
    2528             : /************************************************************************/
    2529             : 
    2530             : /**
    2531             :  * \fn OGRStyleTool::GetStyleString()
    2532             :  * \brief Get the style string for this Style Tool
    2533             :  *
    2534             :  * Maps to the OGRStyleTool subclasses' GetStyleString() methods.
    2535             :  *
    2536             :  * @return the style string for this style tool or "" if the hST is invalid.
    2537             :  */
    2538             : 
    2539             : /**
    2540             :  * \brief Get the style string for this Style Tool
    2541             :  *
    2542             :  * Maps to the OGRStyleTool subclasses' GetStyleString() methods.
    2543             :  *
    2544             :  * @param hST handle to the style tool.
    2545             :  *
    2546             :  * @return the style string for this style tool or "" if the hST is invalid.
    2547             :  */
    2548             : 
    2549           0 : const char *OGR_ST_GetStyleString(OGRStyleToolH hST)
    2550             : {
    2551           0 :     const char *pszVal = "";
    2552             : 
    2553           0 :     VALIDATE_POINTER1(hST, "OGR_ST_GetStyleString", "");
    2554             : 
    2555           0 :     switch (reinterpret_cast<OGRStyleTool *>(hST)->GetType())
    2556             :     {
    2557           0 :         case OGRSTCPen:
    2558           0 :             pszVal = reinterpret_cast<OGRStylePen *>(hST)->GetStyleString();
    2559           0 :             break;
    2560           0 :         case OGRSTCBrush:
    2561           0 :             pszVal = reinterpret_cast<OGRStyleBrush *>(hST)->GetStyleString();
    2562           0 :             break;
    2563           0 :         case OGRSTCSymbol:
    2564           0 :             pszVal = reinterpret_cast<OGRStyleSymbol *>(hST)->GetStyleString();
    2565           0 :             break;
    2566           0 :         case OGRSTCLabel:
    2567           0 :             pszVal = reinterpret_cast<OGRStyleLabel *>(hST)->GetStyleString();
    2568           0 :             break;
    2569           0 :         default:
    2570           0 :             break;
    2571             :     }
    2572             : 
    2573           0 :     return pszVal;
    2574             : }
    2575             : 
    2576             : /************************************************************************/
    2577             : /*                           OGR_ST_GetRGBFromString()                  */
    2578             : /************************************************************************/
    2579             : /**
    2580             :  * \brief Return the r,g,b,a components of a color encoded in \#RRGGBB[AA]
    2581             :  * format.
    2582             :  *
    2583             :  * Maps to OGRStyleTool::GetRGBFromString().
    2584             :  *
    2585             :  * @param hST handle to the style tool.
    2586             :  * @param pszColor the color to parse
    2587             :  * @param pnRed pointer to an int in which the red value will be returned
    2588             :  * @param pnGreen pointer to an int in which the green value will be returned
    2589             :  * @param pnBlue pointer to an int in which the blue value will be returned
    2590             :  * @param pnAlpha pointer to an int in which the (optional) alpha value will
    2591             :  * be returned
    2592             :  *
    2593             :  * @return TRUE if the color could be successfully parsed, or FALSE in case of
    2594             :  * errors.
    2595             :  */
    2596             : 
    2597           0 : int OGR_ST_GetRGBFromString(OGRStyleToolH hST, const char *pszColor, int *pnRed,
    2598             :                             int *pnGreen, int *pnBlue, int *pnAlpha)
    2599             : {
    2600             : 
    2601           0 :     VALIDATE_POINTER1(hST, "OGR_ST_GetRGBFromString", FALSE);
    2602           0 :     VALIDATE_POINTER1(pnRed, "OGR_ST_GetRGBFromString", FALSE);
    2603           0 :     VALIDATE_POINTER1(pnGreen, "OGR_ST_GetRGBFromString", FALSE);
    2604           0 :     VALIDATE_POINTER1(pnBlue, "OGR_ST_GetRGBFromString", FALSE);
    2605           0 :     VALIDATE_POINTER1(pnAlpha, "OGR_ST_GetRGBFromString", FALSE);
    2606             : 
    2607           0 :     return reinterpret_cast<OGRStyleTool *>(hST)->GetRGBFromString(
    2608           0 :         pszColor, *pnRed, *pnGreen, *pnBlue, *pnAlpha);
    2609             : }
    2610             : 
    2611             : //! @cond Doxygen_Suppress
    2612             : /* ======================================================================== */
    2613             : /*                OGRStylePen                                               */
    2614             : /*       Specific parameter (Set/Get) for the StylePen                      */
    2615             : /* ======================================================================== */
    2616             : 
    2617             : /****************************************************************************/
    2618             : /*                      OGRStylePen::OGRStylePen()                          */
    2619             : /*                                                                          */
    2620             : /****************************************************************************/
    2621         253 : OGRStylePen::OGRStylePen()
    2622             :     : OGRStyleTool(OGRSTCPen),
    2623             :       m_pasStyleValue(static_cast<OGRStyleValue *>(
    2624         253 :           CPLCalloc(OGRSTPenLast, sizeof(OGRStyleValue))))
    2625             : {
    2626         253 : }
    2627             : 
    2628             : /****************************************************************************/
    2629             : /*                      OGRStylePen::~OGRStylePen()                         */
    2630             : /*                                                                          */
    2631             : /****************************************************************************/
    2632         496 : OGRStylePen::~OGRStylePen()
    2633             : {
    2634        2277 :     for (int i = 0; i < OGRSTPenLast; i++)
    2635             :     {
    2636        2024 :         if (m_pasStyleValue[i].pszValue != nullptr)
    2637             :         {
    2638         192 :             CPLFree(m_pasStyleValue[i].pszValue);
    2639         192 :             m_pasStyleValue[i].pszValue = nullptr;
    2640             :         }
    2641             :     }
    2642             : 
    2643         253 :     CPLFree(m_pasStyleValue);
    2644         496 : }
    2645             : 
    2646             : /************************************************************************/
    2647             : /*                         OGRStylePen::Parse()                         */
    2648             : /************************************************************************/
    2649         472 : GBool OGRStylePen::Parse()
    2650             : 
    2651             : {
    2652         472 :     return OGRStyleTool::Parse(asStylePen, m_pasStyleValue,
    2653         472 :                                static_cast<int>(OGRSTPenLast));
    2654             : }
    2655             : 
    2656             : /************************************************************************/
    2657             : /*                            GetParamStr()                             */
    2658             : /************************************************************************/
    2659          83 : const char *OGRStylePen::GetParamStr(OGRSTPenParam eParam, GBool &bValueIsNull)
    2660             : {
    2661         166 :     return OGRStyleTool::GetParamStr(asStylePen[eParam],
    2662          83 :                                      m_pasStyleValue[eParam], bValueIsNull);
    2663             : }
    2664             : 
    2665             : /************************************************************************/
    2666             : /*                            GetParamNum()                             */
    2667             : /************************************************************************/
    2668           0 : int OGRStylePen::GetParamNum(OGRSTPenParam eParam, GBool &bValueIsNull)
    2669             : {
    2670           0 :     return OGRStyleTool::GetParamNum(asStylePen[eParam],
    2671           0 :                                      m_pasStyleValue[eParam], bValueIsNull);
    2672             : }
    2673             : 
    2674             : /************************************************************************/
    2675             : /*                            GetParamDbl()                             */
    2676             : /************************************************************************/
    2677          73 : double OGRStylePen::GetParamDbl(OGRSTPenParam eParam, GBool &bValueIsNull)
    2678             : {
    2679         146 :     return OGRStyleTool::GetParamDbl(asStylePen[eParam],
    2680          73 :                                      m_pasStyleValue[eParam], bValueIsNull);
    2681             : }
    2682             : 
    2683             : /************************************************************************/
    2684             : /*                            SetParamStr()                             */
    2685             : /************************************************************************/
    2686             : 
    2687          53 : void OGRStylePen::SetParamStr(OGRSTPenParam eParam, const char *pszParamString)
    2688             : {
    2689          53 :     OGRStyleTool::SetParamStr(asStylePen[eParam], m_pasStyleValue[eParam],
    2690             :                               pszParamString);
    2691          53 : }
    2692             : 
    2693             : /************************************************************************/
    2694             : /*                            SetParamNum()                             */
    2695             : /************************************************************************/
    2696           0 : void OGRStylePen::SetParamNum(OGRSTPenParam eParam, int nParam)
    2697             : {
    2698           0 :     OGRStyleTool::SetParamNum(asStylePen[eParam], m_pasStyleValue[eParam],
    2699             :                               nParam);
    2700           0 : }
    2701             : 
    2702             : /************************************************************************/
    2703             : /*                            SetParamDbl()                             */
    2704             : /************************************************************************/
    2705          83 : void OGRStylePen::SetParamDbl(OGRSTPenParam eParam, double dfParam)
    2706             : {
    2707          83 :     OGRStyleTool::SetParamDbl(asStylePen[eParam], m_pasStyleValue[eParam],
    2708             :                               dfParam);
    2709          83 : }
    2710             : 
    2711             : /************************************************************************/
    2712             : /*                           GetStyleString()                           */
    2713             : /************************************************************************/
    2714         396 : const char *OGRStylePen::GetStyleString()
    2715             : {
    2716         396 :     return OGRStyleTool::GetStyleString(asStylePen, m_pasStyleValue,
    2717         396 :                                         static_cast<int>(OGRSTPenLast));
    2718             : }
    2719             : 
    2720             : /****************************************************************************/
    2721             : /*                      OGRStyleBrush::OGRStyleBrush()                      */
    2722             : /*                                                                          */
    2723             : /****************************************************************************/
    2724         139 : OGRStyleBrush::OGRStyleBrush()
    2725             :     : OGRStyleTool(OGRSTCBrush),
    2726             :       m_pasStyleValue(static_cast<OGRStyleValue *>(
    2727         139 :           CPLCalloc(OGRSTBrushLast, sizeof(OGRStyleValue))))
    2728             : {
    2729         139 : }
    2730             : 
    2731             : /****************************************************************************/
    2732             : /*                      OGRStyleBrush::~OGRStyleBrush()                     */
    2733             : /*                                                                          */
    2734             : /****************************************************************************/
    2735         278 : OGRStyleBrush::~OGRStyleBrush()
    2736             : {
    2737        1251 :     for (int i = 0; i < OGRSTBrushLast; i++)
    2738             :     {
    2739        1112 :         if (m_pasStyleValue[i].pszValue != nullptr)
    2740             :         {
    2741         170 :             CPLFree(m_pasStyleValue[i].pszValue);
    2742         170 :             m_pasStyleValue[i].pszValue = nullptr;
    2743             :         }
    2744             :     }
    2745             : 
    2746         139 :     CPLFree(m_pasStyleValue);
    2747         278 : }
    2748             : 
    2749             : /************************************************************************/
    2750             : /*                               Parse()                                */
    2751             : /************************************************************************/
    2752         283 : GBool OGRStyleBrush::Parse()
    2753             : {
    2754         283 :     return OGRStyleTool::Parse(asStyleBrush, m_pasStyleValue,
    2755         283 :                                static_cast<int>(OGRSTBrushLast));
    2756             : }
    2757             : 
    2758             : /************************************************************************/
    2759             : /*                            GetParamStr()                             */
    2760             : /************************************************************************/
    2761          91 : const char *OGRStyleBrush::GetParamStr(OGRSTBrushParam eParam,
    2762             :                                        GBool &bValueIsNull)
    2763             : {
    2764         182 :     return OGRStyleTool::GetParamStr(asStyleBrush[eParam],
    2765          91 :                                      m_pasStyleValue[eParam], bValueIsNull);
    2766             : }
    2767             : 
    2768             : /************************************************************************/
    2769             : /*                            GetParamNum()                             */
    2770             : /************************************************************************/
    2771           0 : int OGRStyleBrush::GetParamNum(OGRSTBrushParam eParam, GBool &bValueIsNull)
    2772             : {
    2773           0 :     return OGRStyleTool::GetParamNum(asStyleBrush[eParam],
    2774           0 :                                      m_pasStyleValue[eParam], bValueIsNull);
    2775             : }
    2776             : 
    2777             : /************************************************************************/
    2778             : /*                            GetParamDbl()                             */
    2779             : /************************************************************************/
    2780          20 : double OGRStyleBrush::GetParamDbl(OGRSTBrushParam eParam, GBool &bValueIsNull)
    2781             : {
    2782          40 :     return OGRStyleTool::GetParamDbl(asStyleBrush[eParam],
    2783          20 :                                      m_pasStyleValue[eParam], bValueIsNull);
    2784             : }
    2785             : 
    2786             : /************************************************************************/
    2787             : /*                            SetParamStr()                             */
    2788             : /************************************************************************/
    2789          83 : void OGRStyleBrush::SetParamStr(OGRSTBrushParam eParam,
    2790             :                                 const char *pszParamString)
    2791             : {
    2792          83 :     OGRStyleTool::SetParamStr(asStyleBrush[eParam], m_pasStyleValue[eParam],
    2793             :                               pszParamString);
    2794          83 : }
    2795             : 
    2796             : /************************************************************************/
    2797             : /*                            SetParamNum()                             */
    2798             : /************************************************************************/
    2799           0 : void OGRStyleBrush::SetParamNum(OGRSTBrushParam eParam, int nParam)
    2800             : {
    2801           0 :     OGRStyleTool::SetParamNum(asStyleBrush[eParam], m_pasStyleValue[eParam],
    2802             :                               nParam);
    2803           0 : }
    2804             : 
    2805             : /************************************************************************/
    2806             : /*                            SetParamDbl()                             */
    2807             : /************************************************************************/
    2808           0 : void OGRStyleBrush::SetParamDbl(OGRSTBrushParam eParam, double dfParam)
    2809             : {
    2810           0 :     OGRStyleTool::SetParamDbl(asStyleBrush[eParam], m_pasStyleValue[eParam],
    2811             :                               dfParam);
    2812           0 : }
    2813             : 
    2814             : /************************************************************************/
    2815             : /*                           GetStyleString()                           */
    2816             : /************************************************************************/
    2817         170 : const char *OGRStyleBrush::GetStyleString()
    2818             : {
    2819         170 :     return OGRStyleTool::GetStyleString(asStyleBrush, m_pasStyleValue,
    2820         170 :                                         static_cast<int>(OGRSTBrushLast));
    2821             : }
    2822             : 
    2823             : /****************************************************************************/
    2824             : /*                      OGRStyleSymbol::OGRStyleSymbol()                    */
    2825             : /****************************************************************************/
    2826         332 : OGRStyleSymbol::OGRStyleSymbol()
    2827             :     : OGRStyleTool(OGRSTCSymbol),
    2828             :       m_pasStyleValue(static_cast<OGRStyleValue *>(
    2829         332 :           CPLCalloc(OGRSTSymbolLast, sizeof(OGRStyleValue))))
    2830             : {
    2831         332 : }
    2832             : 
    2833             : /****************************************************************************/
    2834             : /*                      OGRStyleSymbol::~OGRStyleSymbol()                   */
    2835             : /*                                                                          */
    2836             : /****************************************************************************/
    2837         664 : OGRStyleSymbol::~OGRStyleSymbol()
    2838             : {
    2839        4316 :     for (int i = 0; i < OGRSTSymbolLast; i++)
    2840             :     {
    2841        3984 :         if (m_pasStyleValue[i].pszValue != nullptr)
    2842             :         {
    2843         619 :             CPLFree(m_pasStyleValue[i].pszValue);
    2844         619 :             m_pasStyleValue[i].pszValue = nullptr;
    2845             :         }
    2846             :     }
    2847             : 
    2848         332 :     CPLFree(m_pasStyleValue);
    2849         664 : }
    2850             : 
    2851             : /************************************************************************/
    2852             : /*                               Parse()                                */
    2853             : /************************************************************************/
    2854        1765 : GBool OGRStyleSymbol::Parse()
    2855             : {
    2856        1765 :     return OGRStyleTool::Parse(asStyleSymbol, m_pasStyleValue,
    2857        1765 :                                static_cast<int>(OGRSTSymbolLast));
    2858             : }
    2859             : 
    2860             : /************************************************************************/
    2861             : /*                            GetParamStr()                             */
    2862             : /************************************************************************/
    2863         451 : const char *OGRStyleSymbol::GetParamStr(OGRSTSymbolParam eParam,
    2864             :                                         GBool &bValueIsNull)
    2865             : {
    2866         902 :     return OGRStyleTool::GetParamStr(asStyleSymbol[eParam],
    2867         451 :                                      m_pasStyleValue[eParam], bValueIsNull);
    2868             : }
    2869             : 
    2870             : /************************************************************************/
    2871             : /*                            GetParamNum()                             */
    2872             : /************************************************************************/
    2873           0 : int OGRStyleSymbol::GetParamNum(OGRSTSymbolParam eParam, GBool &bValueIsNull)
    2874             : {
    2875           0 :     return OGRStyleTool::GetParamNum(asStyleSymbol[eParam],
    2876           0 :                                      m_pasStyleValue[eParam], bValueIsNull);
    2877             : }
    2878             : 
    2879             : /************************************************************************/
    2880             : /*                            GetParamDbl()                             */
    2881             : /************************************************************************/
    2882         192 : double OGRStyleSymbol::GetParamDbl(OGRSTSymbolParam eParam, GBool &bValueIsNull)
    2883             : {
    2884         384 :     return OGRStyleTool::GetParamDbl(asStyleSymbol[eParam],
    2885         192 :                                      m_pasStyleValue[eParam], bValueIsNull);
    2886             : }
    2887             : 
    2888             : /************************************************************************/
    2889             : /*                            SetParamStr()                             */
    2890             : /************************************************************************/
    2891          63 : void OGRStyleSymbol::SetParamStr(OGRSTSymbolParam eParam,
    2892             :                                  const char *pszParamString)
    2893             : {
    2894          63 :     OGRStyleTool::SetParamStr(asStyleSymbol[eParam], m_pasStyleValue[eParam],
    2895             :                               pszParamString);
    2896          63 : }
    2897             : 
    2898             : /************************************************************************/
    2899             : /*                            SetParamNum()                             */
    2900             : /************************************************************************/
    2901           0 : void OGRStyleSymbol::SetParamNum(OGRSTSymbolParam eParam, int nParam)
    2902             : {
    2903           0 :     OGRStyleTool::SetParamNum(asStyleSymbol[eParam], m_pasStyleValue[eParam],
    2904             :                               nParam);
    2905           0 : }
    2906             : 
    2907             : /************************************************************************/
    2908             : /*                            SetParamDbl()                             */
    2909             : /************************************************************************/
    2910          10 : void OGRStyleSymbol::SetParamDbl(OGRSTSymbolParam eParam, double dfParam)
    2911             : {
    2912          10 :     OGRStyleTool::SetParamDbl(asStyleSymbol[eParam], m_pasStyleValue[eParam],
    2913             :                               dfParam);
    2914          10 : }
    2915             : 
    2916             : /************************************************************************/
    2917             : /*                           GetStyleString()                           */
    2918             : /************************************************************************/
    2919         110 : const char *OGRStyleSymbol::GetStyleString()
    2920             : {
    2921         110 :     return OGRStyleTool::GetStyleString(asStyleSymbol, m_pasStyleValue,
    2922         110 :                                         static_cast<int>(OGRSTSymbolLast));
    2923             : }
    2924             : 
    2925             : /****************************************************************************/
    2926             : /*                      OGRStyleLabel::OGRStyleLabel()                      */
    2927             : /*                                                                          */
    2928             : /****************************************************************************/
    2929          24 : OGRStyleLabel::OGRStyleLabel()
    2930             :     : OGRStyleTool(OGRSTCLabel),
    2931             :       m_pasStyleValue(static_cast<OGRStyleValue *>(
    2932          24 :           CPLCalloc(OGRSTLabelLast, sizeof(OGRStyleValue))))
    2933             : {
    2934          24 : }
    2935             : 
    2936             : /****************************************************************************/
    2937             : /*                      OGRStyleLabel::~OGRStyleLabel()                     */
    2938             : /*                                                                          */
    2939             : /****************************************************************************/
    2940          48 : OGRStyleLabel::~OGRStyleLabel()
    2941             : {
    2942         528 :     for (int i = 0; i < OGRSTLabelLast; i++)
    2943             :     {
    2944         504 :         if (m_pasStyleValue[i].pszValue != nullptr)
    2945             :         {
    2946          42 :             CPLFree(m_pasStyleValue[i].pszValue);
    2947          42 :             m_pasStyleValue[i].pszValue = nullptr;
    2948             :         }
    2949             :     }
    2950             : 
    2951          24 :     CPLFree(m_pasStyleValue);
    2952          48 : }
    2953             : 
    2954             : /************************************************************************/
    2955             : /*                               Parse()                                */
    2956             : /************************************************************************/
    2957         281 : GBool OGRStyleLabel::Parse()
    2958             : {
    2959         281 :     return OGRStyleTool::Parse(asStyleLabel, m_pasStyleValue,
    2960         281 :                                static_cast<int>(OGRSTLabelLast));
    2961             : }
    2962             : 
    2963             : /************************************************************************/
    2964             : /*                            GetParamStr()                             */
    2965             : /************************************************************************/
    2966          62 : const char *OGRStyleLabel::GetParamStr(OGRSTLabelParam eParam,
    2967             :                                        GBool &bValueIsNull)
    2968             : {
    2969         124 :     return OGRStyleTool::GetParamStr(asStyleLabel[eParam],
    2970          62 :                                      m_pasStyleValue[eParam], bValueIsNull);
    2971             : }
    2972             : 
    2973             : /************************************************************************/
    2974             : /*                            GetParamNum()                             */
    2975             : /************************************************************************/
    2976          49 : int OGRStyleLabel::GetParamNum(OGRSTLabelParam eParam, GBool &bValueIsNull)
    2977             : {
    2978          98 :     return OGRStyleTool::GetParamNum(asStyleLabel[eParam],
    2979          49 :                                      m_pasStyleValue[eParam], bValueIsNull);
    2980             : }
    2981             : 
    2982             : /************************************************************************/
    2983             : /*                            GetParamDbl()                             */
    2984             : /************************************************************************/
    2985          77 : double OGRStyleLabel::GetParamDbl(OGRSTLabelParam eParam, GBool &bValueIsNull)
    2986             : {
    2987         154 :     return OGRStyleTool::GetParamDbl(asStyleLabel[eParam],
    2988          77 :                                      m_pasStyleValue[eParam], bValueIsNull);
    2989             : }
    2990             : 
    2991             : /************************************************************************/
    2992             : /*                            SetParamStr()                             */
    2993             : /************************************************************************/
    2994           5 : void OGRStyleLabel::SetParamStr(OGRSTLabelParam eParam,
    2995             :                                 const char *pszParamString)
    2996             : {
    2997           5 :     OGRStyleTool::SetParamStr(asStyleLabel[eParam], m_pasStyleValue[eParam],
    2998             :                               pszParamString);
    2999           5 : }
    3000             : 
    3001             : /************************************************************************/
    3002             : /*                            SetParamNum()                             */
    3003             : /************************************************************************/
    3004           0 : void OGRStyleLabel::SetParamNum(OGRSTLabelParam eParam, int nParam)
    3005             : {
    3006           0 :     OGRStyleTool::SetParamNum(asStyleLabel[eParam], m_pasStyleValue[eParam],
    3007             :                               nParam);
    3008           0 : }
    3009             : 
    3010             : /************************************************************************/
    3011             : /*                            SetParamDbl()                             */
    3012             : /************************************************************************/
    3013           5 : void OGRStyleLabel::SetParamDbl(OGRSTLabelParam eParam, double dfParam)
    3014             : {
    3015           5 :     OGRStyleTool::SetParamDbl(asStyleLabel[eParam], m_pasStyleValue[eParam],
    3016             :                               dfParam);
    3017           5 : }
    3018             : 
    3019             : /************************************************************************/
    3020             : /*                           GetStyleString()                           */
    3021             : /************************************************************************/
    3022          10 : const char *OGRStyleLabel::GetStyleString()
    3023             : {
    3024          10 :     return OGRStyleTool::GetStyleString(asStyleLabel, m_pasStyleValue,
    3025          10 :                                         static_cast<int>(OGRSTLabelLast));
    3026             : }
    3027             : 
    3028             : //! @endcond

Generated by: LCOV version 1.14