LCOV - code coverage report
Current view: top level - ogr/ogrsf_frmts/mitab - mitab_tooldef.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 268 293 91.5 %
Date: 2024-11-21 22:18:42 Functions: 17 17 100.0 %

          Line data    Source code
       1             : /**********************************************************************
       2             :  *
       3             :  * Name:     mitab_tooldef.cpp
       4             :  * Project:  MapInfo TAB Read/Write library
       5             :  * Language: C++
       6             :  * Purpose:  Implementation of the TABToolDefTable class used to handle
       7             :  *           a dataset's table of drawing tool blocks
       8             :  * Author:   Daniel Morissette, dmorissette@dmsolutions.ca
       9             :  *
      10             :  **********************************************************************
      11             :  * Copyright (c) 1999, 2000, Daniel Morissette
      12             :  *
      13             :  * SPDX-License-Identifier: MIT
      14             :  **********************************************************************/
      15             : 
      16             : #include "cpl_port.h"
      17             : #include "mitab.h"
      18             : 
      19             : #include <cstddef>
      20             : #include <algorithm>
      21             : 
      22             : #include "cpl_conv.h"
      23             : #include "cpl_error.h"
      24             : #include "mitab_priv.h"
      25             : #include "mitab_utils.h"
      26             : 
      27             : /*=====================================================================
      28             :  *                      class TABToolDefTable
      29             :  *====================================================================*/
      30             : 
      31             : /**********************************************************************
      32             :  *                   TABToolDefTable::TABToolDefTable()
      33             :  *
      34             :  * Constructor.
      35             :  **********************************************************************/
      36        1325 : TABToolDefTable::TABToolDefTable()
      37             :     : m_papsPen(nullptr), m_numPen(0), m_numAllocatedPen(0),
      38             :       m_papsBrush(nullptr), m_numBrushes(0), m_numAllocatedBrushes(0),
      39             :       m_papsFont(nullptr), m_numFonts(0), m_numAllocatedFonts(0),
      40        1325 :       m_papsSymbol(nullptr), m_numSymbols(0), m_numAllocatedSymbols(0)
      41             : {
      42        1325 : }
      43             : 
      44             : /**********************************************************************
      45             :  *                   TABToolDefTable::~TABToolDefTable()
      46             :  *
      47             :  * Destructor.
      48             :  **********************************************************************/
      49        2650 : TABToolDefTable::~TABToolDefTable()
      50             : {
      51        1410 :     for (int i = 0; m_papsPen && i < m_numPen; i++)
      52          85 :         CPLFree(m_papsPen[i]);
      53        1325 :     CPLFree(m_papsPen);
      54             : 
      55        1386 :     for (int i = 0; m_papsBrush && i < m_numBrushes; i++)
      56          61 :         CPLFree(m_papsBrush[i]);
      57        1325 :     CPLFree(m_papsBrush);
      58             : 
      59        1344 :     for (int i = 0; m_papsFont && i < m_numFonts; i++)
      60          19 :         CPLFree(m_papsFont[i]);
      61        1325 :     CPLFree(m_papsFont);
      62             : 
      63        2589 :     for (int i = 0; m_papsSymbol && i < m_numSymbols; i++)
      64        1264 :         CPLFree(m_papsSymbol[i]);
      65        1325 :     CPLFree(m_papsSymbol);
      66        1325 : }
      67             : 
      68             : /**********************************************************************
      69             :  *                   TABToolDefTable::ReadAllToolDefs()
      70             :  *
      71             :  * Read all tool definition blocks until we reach the end of the chain.
      72             :  * This function will be called only once per dataset, after that
      73             :  * we keep all the tool definitions in memory.
      74             :  *
      75             :  * Returns 0 on success, -1 on error.
      76             :  **********************************************************************/
      77        1211 : int TABToolDefTable::ReadAllToolDefs(TABMAPToolBlock *poBlock)
      78             : {
      79        1211 :     int nStatus = 0;
      80             : 
      81             :     /*-----------------------------------------------------------------
      82             :      * Loop until we reach the end of the chain of blocks... we assume
      83             :      * that the first block of data is already pre-loaded.
      84             :      *----------------------------------------------------------------*/
      85        2495 :     while (!poBlock->EndOfChain())
      86             :     {
      87        1284 :         const int nDefType = poBlock->ReadByte();
      88        1284 :         switch (nDefType)
      89             :         {
      90          43 :             case TABMAP_TOOL_PEN:  // PEN
      91          43 :                 if (m_numPen >= m_numAllocatedPen)
      92             :                 {
      93             :                     // Realloc array by blocks of 20 items
      94          37 :                     m_numAllocatedPen += 20;
      95          37 :                     m_papsPen = static_cast<TABPenDef **>(CPLRealloc(
      96          37 :                         m_papsPen, m_numAllocatedPen * sizeof(TABPenDef *)));
      97             :                 }
      98          86 :                 m_papsPen[m_numPen] =
      99          43 :                     static_cast<TABPenDef *>(CPLCalloc(1, sizeof(TABPenDef)));
     100             : 
     101          43 :                 m_papsPen[m_numPen]->nRefCount = poBlock->ReadInt32();
     102          43 :                 m_papsPen[m_numPen]->nPixelWidth = poBlock->ReadByte();
     103          43 :                 m_papsPen[m_numPen]->nLinePattern = poBlock->ReadByte();
     104          43 :                 m_papsPen[m_numPen]->nPointWidth = poBlock->ReadByte();
     105          43 :                 m_papsPen[m_numPen]->rgbColor =
     106          43 :                     poBlock->ReadByte() * 256 * 256 +
     107          43 :                     poBlock->ReadByte() * 256 + poBlock->ReadByte();
     108             : 
     109             :                 // Adjust width value...
     110             :                 // High bits for point width values > 255 are stored in the
     111             :                 // pixel width byte
     112          43 :                 if (m_papsPen[m_numPen]->nPixelWidth > 7)
     113             :                 {
     114           0 :                     m_papsPen[m_numPen]->nPointWidth +=
     115           0 :                         (m_papsPen[m_numPen]->nPixelWidth - 8) * 0x100;
     116           0 :                     m_papsPen[m_numPen]->nPixelWidth = 1;
     117             :                 }
     118             : 
     119          43 :                 m_numPen++;
     120             : 
     121          43 :                 break;
     122          32 :             case TABMAP_TOOL_BRUSH:  // BRUSH
     123          32 :                 if (m_numBrushes >= m_numAllocatedBrushes)
     124             :                 {
     125             :                     // Realloc array by blocks of 20 items
     126          26 :                     m_numAllocatedBrushes += 20;
     127          26 :                     m_papsBrush = static_cast<TABBrushDef **>(
     128          26 :                         CPLRealloc(m_papsBrush, m_numAllocatedBrushes *
     129             :                                                     sizeof(TABBrushDef *)));
     130             :                 }
     131          64 :                 m_papsBrush[m_numBrushes] = static_cast<TABBrushDef *>(
     132          32 :                     CPLCalloc(1, sizeof(TABBrushDef)));
     133             : 
     134          32 :                 m_papsBrush[m_numBrushes]->nRefCount = poBlock->ReadInt32();
     135          32 :                 m_papsBrush[m_numBrushes]->nFillPattern = poBlock->ReadByte();
     136          64 :                 m_papsBrush[m_numBrushes]->bTransparentFill =
     137          32 :                     poBlock->ReadByte();
     138          32 :                 m_papsBrush[m_numBrushes]->rgbFGColor =
     139          32 :                     poBlock->ReadByte() * 256 * 256 +
     140          32 :                     poBlock->ReadByte() * 256 + poBlock->ReadByte();
     141          32 :                 m_papsBrush[m_numBrushes]->rgbBGColor =
     142          32 :                     poBlock->ReadByte() * 256 * 256 +
     143          32 :                     poBlock->ReadByte() * 256 + poBlock->ReadByte();
     144             : 
     145          32 :                 m_numBrushes++;
     146             : 
     147          32 :                 break;
     148          13 :             case TABMAP_TOOL_FONT:  // FONT NAME
     149          13 :                 if (m_numFonts >= m_numAllocatedFonts)
     150             :                 {
     151             :                     // Realloc array by blocks of 20 items
     152           7 :                     m_numAllocatedFonts += 20;
     153           7 :                     m_papsFont = static_cast<TABFontDef **>(
     154           7 :                         CPLRealloc(m_papsFont,
     155           7 :                                    m_numAllocatedFonts * sizeof(TABFontDef *)));
     156             :                 }
     157          26 :                 m_papsFont[m_numFonts] =
     158          13 :                     static_cast<TABFontDef *>(CPLCalloc(1, sizeof(TABFontDef)));
     159             : 
     160          13 :                 m_papsFont[m_numFonts]->nRefCount = poBlock->ReadInt32();
     161          13 :                 poBlock->ReadBytes(32, reinterpret_cast<GByte *>(
     162          13 :                                            m_papsFont[m_numFonts]->szFontName));
     163          13 :                 m_papsFont[m_numFonts]->szFontName[32] = '\0';
     164             : 
     165          13 :                 m_numFonts++;
     166             : 
     167          13 :                 break;
     168        1196 :             case TABMAP_TOOL_SYMBOL:  // SYMBOL
     169        1196 :                 if (m_numSymbols >= m_numAllocatedSymbols)
     170             :                 {
     171             :                     // Realloc array by blocks of 20 items
     172        1190 :                     m_numAllocatedSymbols += 20;
     173        1190 :                     m_papsSymbol = static_cast<TABSymbolDef **>(
     174        1190 :                         CPLRealloc(m_papsSymbol, m_numAllocatedSymbols *
     175             :                                                      sizeof(TABSymbolDef *)));
     176             :                 }
     177        2392 :                 m_papsSymbol[m_numSymbols] = static_cast<TABSymbolDef *>(
     178        1196 :                     CPLCalloc(1, sizeof(TABSymbolDef)));
     179             : 
     180        1196 :                 m_papsSymbol[m_numSymbols]->nRefCount = poBlock->ReadInt32();
     181        1196 :                 m_papsSymbol[m_numSymbols]->nSymbolNo = poBlock->ReadInt16();
     182        1196 :                 m_papsSymbol[m_numSymbols]->nPointSize = poBlock->ReadInt16();
     183        2392 :                 m_papsSymbol[m_numSymbols]->_nUnknownValue_ =
     184        1196 :                     poBlock->ReadByte();
     185        1196 :                 m_papsSymbol[m_numSymbols]->rgbColor =
     186        1196 :                     poBlock->ReadByte() * 256 * 256 +
     187        1196 :                     poBlock->ReadByte() * 256 + poBlock->ReadByte();
     188             : 
     189        1196 :                 m_numSymbols++;
     190             : 
     191        1196 :                 break;
     192           0 :             default:
     193             :                 /* Unsupported Tool type!!! */
     194           0 :                 CPLError(CE_Failure, CPLE_NotSupported,
     195             :                          "Unsupported drawing tool type: `%d'", nDefType);
     196           0 :                 nStatus = -1;
     197             :         }
     198             : 
     199        1284 :         if (CPLGetLastErrorType() == CE_Failure)
     200             :         {
     201             :             // An error happened reading this tool definition... stop now.
     202           0 :             nStatus = -1;
     203           0 :             break;
     204             :         }
     205             :     }
     206             : 
     207        1211 :     return nStatus;
     208             : }
     209             : 
     210             : /**********************************************************************
     211             :  *                   TABToolDefTable::WriteAllToolDefs()
     212             :  *
     213             :  * Write all tool definition structures to the TABMAPToolBlock.
     214             :  *
     215             :  * Note that at the end of this call, poBlock->CommitToFile() will have
     216             :  * been called.
     217             :  *
     218             :  * Returns 0 on success, -1 on error.
     219             :  **********************************************************************/
     220        1165 : int TABToolDefTable::WriteAllToolDefs(TABMAPToolBlock *poBlock)
     221             : {
     222        1165 :     int nStatus = 0;
     223             : 
     224             :     /*-----------------------------------------------------------------
     225             :      * Write Pen Defs
     226             :      *----------------------------------------------------------------*/
     227        1210 :     for (int i = 0; nStatus == 0 && i < m_numPen; i++)
     228             :     {
     229             :         // The pen width is encoded over 2 bytes
     230          45 :         GByte byPixelWidth = 1;
     231          45 :         GByte byPointWidth = 0;
     232          45 :         if (m_papsPen[i]->nPointWidth > 0)
     233             :         {
     234           0 :             byPointWidth = static_cast<GByte>(m_papsPen[i]->nPointWidth & 0xff);
     235           0 :             if (m_papsPen[i]->nPointWidth > 255)
     236           0 :                 byPixelWidth =
     237           0 :                     8 + static_cast<GByte>(m_papsPen[i]->nPointWidth / 0x100);
     238             :         }
     239             :         else
     240             :         {
     241          45 :             const GByte nMinWidth = 1;
     242          45 :             const GByte nMaxWidth = 7;
     243          45 :             byPixelWidth = std::min(
     244          45 :                 std::max(m_papsPen[i]->nPixelWidth, nMinWidth), nMaxWidth);
     245             :         }
     246             : 
     247          45 :         poBlock->CheckAvailableSpace(TABMAP_TOOL_PEN);
     248          45 :         poBlock->WriteByte(TABMAP_TOOL_PEN);  // Def Type = Pen
     249          45 :         poBlock->WriteInt32(m_papsPen[i]->nRefCount);
     250             : 
     251          45 :         poBlock->WriteByte(byPixelWidth);
     252          45 :         poBlock->WriteByte(m_papsPen[i]->nLinePattern);
     253          45 :         poBlock->WriteByte(byPointWidth);
     254          45 :         poBlock->WriteByte(static_cast<GByte>(COLOR_R(m_papsPen[i]->rgbColor)));
     255          45 :         poBlock->WriteByte(static_cast<GByte>(COLOR_G(m_papsPen[i]->rgbColor)));
     256          45 :         poBlock->WriteByte(static_cast<GByte>(COLOR_B(m_papsPen[i]->rgbColor)));
     257             : 
     258          45 :         if (CPLGetLastErrorType() == CE_Failure)
     259             :         {
     260             :             // An error happened reading this tool definition... stop now.
     261           0 :             nStatus = -1;
     262             :         }
     263             :     }
     264             : 
     265             :     /*-----------------------------------------------------------------
     266             :      * Write Brush Defs
     267             :      *----------------------------------------------------------------*/
     268        1195 :     for (int i = 0; nStatus == 0 && i < m_numBrushes; i++)
     269             :     {
     270          30 :         poBlock->CheckAvailableSpace(TABMAP_TOOL_BRUSH);
     271             : 
     272          30 :         poBlock->WriteByte(TABMAP_TOOL_BRUSH);  // Def Type = Brush
     273          30 :         poBlock->WriteInt32(m_papsBrush[i]->nRefCount);
     274             : 
     275          30 :         poBlock->WriteByte(m_papsBrush[i]->nFillPattern);
     276          30 :         poBlock->WriteByte(m_papsBrush[i]->bTransparentFill);
     277          30 :         poBlock->WriteByte(
     278          30 :             static_cast<GByte>(COLOR_R(m_papsBrush[i]->rgbFGColor)));
     279          30 :         poBlock->WriteByte(
     280          30 :             static_cast<GByte>(COLOR_G(m_papsBrush[i]->rgbFGColor)));
     281          30 :         poBlock->WriteByte(
     282          30 :             static_cast<GByte>(COLOR_B(m_papsBrush[i]->rgbFGColor)));
     283          30 :         poBlock->WriteByte(
     284          30 :             static_cast<GByte>(COLOR_R(m_papsBrush[i]->rgbBGColor)));
     285          30 :         poBlock->WriteByte(
     286          30 :             static_cast<GByte>(COLOR_G(m_papsBrush[i]->rgbBGColor)));
     287          30 :         poBlock->WriteByte(
     288          30 :             static_cast<GByte>(COLOR_B(m_papsBrush[i]->rgbBGColor)));
     289             : 
     290          30 :         if (CPLGetLastErrorType() == CE_Failure)
     291             :         {
     292             :             // An error happened reading this tool definition... stop now.
     293           0 :             nStatus = -1;
     294             :         }
     295             :     }
     296             : 
     297             :     /*-----------------------------------------------------------------
     298             :      * Write Font Defs
     299             :      *----------------------------------------------------------------*/
     300        1171 :     for (int i = 0; nStatus == 0 && i < m_numFonts; i++)
     301             :     {
     302           6 :         poBlock->CheckAvailableSpace(TABMAP_TOOL_FONT);
     303             : 
     304           6 :         poBlock->WriteByte(TABMAP_TOOL_FONT);  // Def Type = Font name
     305           6 :         poBlock->WriteInt32(m_papsFont[i]->nRefCount);
     306             : 
     307           6 :         poBlock->WriteBytes(
     308           6 :             32, reinterpret_cast<GByte *>(m_papsFont[i]->szFontName));
     309             : 
     310           6 :         if (CPLGetLastErrorType() == CE_Failure)
     311             :         {
     312             :             // An error happened reading this tool definition... stop now.
     313           0 :             nStatus = -1;
     314             :         }
     315             :     }
     316             : 
     317             :     /*-----------------------------------------------------------------
     318             :      * Write Symbol Defs
     319             :      *----------------------------------------------------------------*/
     320        2305 :     for (int i = 0; nStatus == 0 && i < m_numSymbols; i++)
     321             :     {
     322        1140 :         poBlock->CheckAvailableSpace(TABMAP_TOOL_SYMBOL);
     323             : 
     324        1140 :         poBlock->WriteByte(TABMAP_TOOL_SYMBOL);  // Def Type = Symbol
     325        1140 :         poBlock->WriteInt32(m_papsSymbol[i]->nRefCount);
     326             : 
     327        1140 :         poBlock->WriteInt16(m_papsSymbol[i]->nSymbolNo);
     328        1140 :         poBlock->WriteInt16(m_papsSymbol[i]->nPointSize);
     329        1140 :         poBlock->WriteByte(m_papsSymbol[i]->_nUnknownValue_);
     330        1140 :         poBlock->WriteByte(
     331        1140 :             static_cast<GByte>(COLOR_R(m_papsSymbol[i]->rgbColor)));
     332        1140 :         poBlock->WriteByte(
     333        1140 :             static_cast<GByte>(COLOR_G(m_papsSymbol[i]->rgbColor)));
     334        1140 :         poBlock->WriteByte(
     335        1140 :             static_cast<GByte>(COLOR_B(m_papsSymbol[i]->rgbColor)));
     336             : 
     337        1140 :         if (CPLGetLastErrorType() == CE_Failure)
     338             :         {
     339             :             // An error happened reading this tool definition... stop now.
     340           0 :             nStatus = -1;
     341             :         }
     342             :     }
     343             : 
     344        1165 :     if (nStatus == 0)
     345        1165 :         nStatus = poBlock->CommitToFile();
     346             : 
     347        1165 :     return nStatus;
     348             : }
     349             : 
     350             : /**********************************************************************
     351             :  *                   TABToolDefTable::GetNumPen()
     352             :  *
     353             :  * Return the number of valid pen indexes for this .MAP file
     354             :  **********************************************************************/
     355        2330 : int TABToolDefTable::GetNumPen()
     356             : {
     357        2330 :     return m_numPen;
     358             : }
     359             : 
     360             : /**********************************************************************
     361             :  *                   TABToolDefTable::GetPenDefRef()
     362             :  *
     363             :  * Return a reference to the specified Pen tool definition, or NULL if
     364             :  * specified index is invalid.
     365             :  *
     366             :  * Note that nIndex is a 1-based index.  A value of 0 indicates "none"
     367             :  * in MapInfo.
     368             :  **********************************************************************/
     369        1956 : TABPenDef *TABToolDefTable::GetPenDefRef(int nIndex)
     370             : {
     371        1956 :     if (nIndex > 0 && nIndex <= m_numPen)
     372        1954 :         return m_papsPen[nIndex - 1];
     373             : 
     374           2 :     return nullptr;
     375             : }
     376             : 
     377             : /**********************************************************************
     378             :  *                   TABToolDefTable::AddPenDefRef()
     379             :  *
     380             :  * Either create a new PenDefRef or add a reference to an existing one.
     381             :  *
     382             :  * Return the pen index that has been attributed to this Pen tool
     383             :  * definition, or -1 if something went wrong
     384             :  *
     385             :  * Note that nIndex is a 1-based index.  A value of 0 indicates "none"
     386             :  * in MapInfo.
     387             :  **********************************************************************/
     388         330 : int TABToolDefTable::AddPenDefRef(TABPenDef *poNewPenDef)
     389             : {
     390         330 :     if (poNewPenDef == nullptr)
     391           0 :         return -1;
     392             : 
     393             :     /*-----------------------------------------------------------------
     394             :      * Check for "none" case: pattern = 0 (pattern 0 does not exist!)
     395             :      *----------------------------------------------------------------*/
     396         330 :     if (poNewPenDef->nLinePattern < 1)
     397           0 :         return 0;
     398             : 
     399             :     /*-----------------------------------------------------------------
     400             :      * Start by searching the list of existing pens
     401             :      *----------------------------------------------------------------*/
     402         330 :     int nNewPenIndex = 0;
     403         630 :     for (int i = 0; nNewPenIndex == 0 && i < m_numPen; i++)
     404             :     {
     405         300 :         TABPenDef *poDef = m_papsPen[i];
     406         300 :         if (poDef->nPixelWidth == poNewPenDef->nPixelWidth &&
     407         300 :             poDef->nLinePattern == poNewPenDef->nLinePattern &&
     408         300 :             poDef->nPointWidth == poNewPenDef->nPointWidth &&
     409         300 :             poDef->rgbColor == poNewPenDef->rgbColor)
     410             :         {
     411         288 :             nNewPenIndex = i + 1;  // Fount it!
     412         288 :             poDef->nRefCount++;
     413             :         }
     414             :     }
     415             : 
     416             :     /*-----------------------------------------------------------------
     417             :      * OK, we did not find a match, then create a new entry
     418             :      *----------------------------------------------------------------*/
     419         330 :     if (nNewPenIndex == 0)
     420             :     {
     421          42 :         if (m_numPen >= m_numAllocatedPen)
     422             :         {
     423             :             // Realloc array by blocks of 20 items
     424          39 :             m_numAllocatedPen += 20;
     425          39 :             m_papsPen = static_cast<TABPenDef **>(
     426          39 :                 CPLRealloc(m_papsPen, m_numAllocatedPen * sizeof(TABPenDef *)));
     427             :         }
     428          84 :         m_papsPen[m_numPen] =
     429          42 :             static_cast<TABPenDef *>(CPLCalloc(1, sizeof(TABPenDef)));
     430             : 
     431          42 :         *m_papsPen[m_numPen] = *poNewPenDef;
     432          42 :         m_papsPen[m_numPen]->nRefCount = 1;
     433          42 :         nNewPenIndex = ++m_numPen;
     434             :     }
     435             : 
     436         330 :     return nNewPenIndex;
     437             : }
     438             : 
     439             : /**********************************************************************
     440             :  *                   TABToolDefTable::GetNumBrushes()
     441             :  *
     442             :  * Return the number of valid Brush indexes for this .MAP file
     443             :  **********************************************************************/
     444        2330 : int TABToolDefTable::GetNumBrushes()
     445             : {
     446        2330 :     return m_numBrushes;
     447             : }
     448             : 
     449             : /**********************************************************************
     450             :  *                   TABToolDefTable::GetBrushDefRef()
     451             :  *
     452             :  * Return a reference to the specified Brush tool definition, or NULL if
     453             :  * specified index is invalid.
     454             :  *
     455             :  * Note that nIndex is a 1-based index.  A value of 0 indicates "none"
     456             :  * in MapInfo.
     457             :  **********************************************************************/
     458         526 : TABBrushDef *TABToolDefTable::GetBrushDefRef(int nIndex)
     459             : {
     460         526 :     if (nIndex > 0 && nIndex <= m_numBrushes)
     461         521 :         return m_papsBrush[nIndex - 1];
     462             : 
     463           5 :     return nullptr;
     464             : }
     465             : 
     466             : /**********************************************************************
     467             :  *                   TABToolDefTable::AddBrushDefRef()
     468             :  *
     469             :  * Either create a new BrushDefRef or add a reference to an existing one.
     470             :  *
     471             :  * Return the Brush index that has been attributed to this Brush tool
     472             :  * definition, or -1 if something went wrong
     473             :  *
     474             :  * Note that nIndex is a 1-based index.  A value of 0 indicates "none"
     475             :  * in MapInfo.
     476             :  **********************************************************************/
     477          88 : int TABToolDefTable::AddBrushDefRef(TABBrushDef *poNewBrushDef)
     478             : {
     479          88 :     if (poNewBrushDef == nullptr)
     480           0 :         return -1;
     481             : 
     482             :     /*-----------------------------------------------------------------
     483             :      * Check for "none" case: pattern = 0 (pattern 0 does not exist!)
     484             :      *----------------------------------------------------------------*/
     485          88 :     if (poNewBrushDef->nFillPattern < 1)
     486           0 :         return 0;
     487             : 
     488             :     /*-----------------------------------------------------------------
     489             :      * Start by searching the list of existing Brushs
     490             :      *----------------------------------------------------------------*/
     491          88 :     int nNewBrushIndex = 0;
     492         153 :     for (int i = 0; nNewBrushIndex == 0 && i < m_numBrushes; i++)
     493             :     {
     494          65 :         TABBrushDef *poDef = m_papsBrush[i];
     495          65 :         if (poDef->nFillPattern == poNewBrushDef->nFillPattern &&
     496          63 :             poDef->bTransparentFill == poNewBrushDef->bTransparentFill &&
     497          63 :             poDef->rgbFGColor == poNewBrushDef->rgbFGColor &&
     498          59 :             poDef->rgbBGColor == poNewBrushDef->rgbBGColor)
     499             :         {
     500          59 :             nNewBrushIndex = i + 1;  // Fount it!
     501          59 :             poDef->nRefCount++;
     502             :         }
     503             :     }
     504             : 
     505             :     /*-----------------------------------------------------------------
     506             :      * OK, we did not find a match, then create a new entry
     507             :      *----------------------------------------------------------------*/
     508          88 :     if (nNewBrushIndex == 0)
     509             :     {
     510          29 :         if (m_numBrushes >= m_numAllocatedBrushes)
     511             :         {
     512             :             // Realloc array by blocks of 20 items
     513          26 :             m_numAllocatedBrushes += 20;
     514          26 :             m_papsBrush = static_cast<TABBrushDef **>(CPLRealloc(
     515          26 :                 m_papsBrush, m_numAllocatedBrushes * sizeof(TABBrushDef *)));
     516             :         }
     517          58 :         m_papsBrush[m_numBrushes] =
     518          29 :             static_cast<TABBrushDef *>(CPLCalloc(1, sizeof(TABBrushDef)));
     519             : 
     520          29 :         *m_papsBrush[m_numBrushes] = *poNewBrushDef;
     521          29 :         m_papsBrush[m_numBrushes]->nRefCount = 1;
     522          29 :         nNewBrushIndex = ++m_numBrushes;
     523             :     }
     524             : 
     525          88 :     return nNewBrushIndex;
     526             : }
     527             : 
     528             : /**********************************************************************
     529             :  *                   TABToolDefTable::GetNumFonts()
     530             :  *
     531             :  * Return the number of valid Font indexes for this .MAP file
     532             :  **********************************************************************/
     533        2330 : int TABToolDefTable::GetNumFonts()
     534             : {
     535        2330 :     return m_numFonts;
     536             : }
     537             : 
     538             : /**********************************************************************
     539             :  *                   TABToolDefTable::GetFontDefRef()
     540             :  *
     541             :  * Return a reference to the specified Font tool definition, or NULL if
     542             :  * specified index is invalid.
     543             :  *
     544             :  * Note that nIndex is a 1-based index.  A value of 0 indicates "none"
     545             :  * in MapInfo.
     546             :  **********************************************************************/
     547          20 : TABFontDef *TABToolDefTable::GetFontDefRef(int nIndex)
     548             : {
     549          20 :     if (nIndex > 0 && nIndex <= m_numFonts)
     550          20 :         return m_papsFont[nIndex - 1];
     551             : 
     552           0 :     return nullptr;
     553             : }
     554             : 
     555             : /**********************************************************************
     556             :  *                   TABToolDefTable::AddFontDefRef()
     557             :  *
     558             :  * Either create a new FontDefRef or add a reference to an existing one.
     559             :  *
     560             :  * Return the Font index that has been attributed to this Font tool
     561             :  * definition, or -1 if something went wrong
     562             :  *
     563             :  * Note that nIndex is a 1-based index.  A value of 0 indicates "none"
     564             :  * in MapInfo.
     565             :  **********************************************************************/
     566           8 : int TABToolDefTable::AddFontDefRef(TABFontDef *poNewFontDef)
     567             : {
     568           8 :     if (poNewFontDef == nullptr)
     569           0 :         return -1;
     570             : 
     571             :     /*-----------------------------------------------------------------
     572             :      * Start by searching the list of existing Fonts
     573             :      *----------------------------------------------------------------*/
     574           8 :     int nNewFontIndex = 0;
     575          12 :     for (int i = 0; nNewFontIndex == 0 && i < m_numFonts; i++)
     576             :     {
     577           4 :         TABFontDef *poDef = m_papsFont[i];
     578           4 :         if (EQUAL(poDef->szFontName, poNewFontDef->szFontName))
     579             :         {
     580           2 :             nNewFontIndex = i + 1;  // Fount it!
     581           2 :             poDef->nRefCount++;
     582             :         }
     583             :     }
     584             : 
     585             :     /*-----------------------------------------------------------------
     586             :      * OK, we did not find a match, then create a new entry
     587             :      *----------------------------------------------------------------*/
     588           8 :     if (nNewFontIndex == 0)
     589             :     {
     590           6 :         if (m_numFonts >= m_numAllocatedFonts)
     591             :         {
     592             :             // Realloc array by blocks of 20 items
     593           4 :             m_numAllocatedFonts += 20;
     594           4 :             m_papsFont = static_cast<TABFontDef **>(CPLRealloc(
     595           4 :                 m_papsFont, m_numAllocatedFonts * sizeof(TABFontDef *)));
     596             :         }
     597          12 :         m_papsFont[m_numFonts] =
     598           6 :             static_cast<TABFontDef *>(CPLCalloc(1, sizeof(TABFontDef)));
     599             : 
     600           6 :         *m_papsFont[m_numFonts] = *poNewFontDef;
     601           6 :         m_papsFont[m_numFonts]->nRefCount = 1;
     602           6 :         nNewFontIndex = ++m_numFonts;
     603             :     }
     604             : 
     605           8 :     return nNewFontIndex;
     606             : }
     607             : 
     608             : /**********************************************************************
     609             :  *                   TABToolDefTable::GetNumSymbols()
     610             :  *
     611             :  * Return the number of valid Symbol indexes for this .MAP file
     612             :  **********************************************************************/
     613        2330 : int TABToolDefTable::GetNumSymbols()
     614             : {
     615        2330 :     return m_numSymbols;
     616             : }
     617             : 
     618             : /**********************************************************************
     619             :  *                   TABToolDefTable::GetSymbolDefRef()
     620             :  *
     621             :  * Return a reference to the specified Symbol tool definition, or NULL if
     622             :  * specified index is invalid.
     623             :  *
     624             :  * Note that nIndex is a 1-based index.  A value of 0 indicates "none"
     625             :  * in MapInfo.
     626             :  **********************************************************************/
     627      527324 : TABSymbolDef *TABToolDefTable::GetSymbolDefRef(int nIndex)
     628             : {
     629      527324 :     if (nIndex > 0 && nIndex <= m_numSymbols)
     630      527324 :         return m_papsSymbol[nIndex - 1];
     631             : 
     632           0 :     return nullptr;
     633             : }
     634             : 
     635             : /**********************************************************************
     636             :  *                   TABToolDefTable::AddSymbolDefRef()
     637             :  *
     638             :  * Either create a new SymbolDefRef or add a reference to an existing one.
     639             :  *
     640             :  * Return the Symbol index that has been attributed to this Symbol tool
     641             :  * definition, or -1 if something went wrong
     642             :  *
     643             :  * Note that nIndex is a 1-based index.  A value of 0 indicates "none"
     644             :  * in MapInfo.
     645             :  **********************************************************************/
     646       14689 : int TABToolDefTable::AddSymbolDefRef(TABSymbolDef *poNewSymbolDef)
     647             : {
     648       14689 :     if (poNewSymbolDef == nullptr)
     649           0 :         return -1;
     650             : 
     651             :     /*-----------------------------------------------------------------
     652             :      * Start by searching the list of existing Symbols
     653             :      *----------------------------------------------------------------*/
     654       14689 :     int nNewSymbolIndex = 0;
     655       29312 :     for (int i = 0; nNewSymbolIndex == 0 && i < m_numSymbols; i++)
     656             :     {
     657       14623 :         TABSymbolDef *poDef = m_papsSymbol[i];
     658       14623 :         if (poDef->nSymbolNo == poNewSymbolDef->nSymbolNo &&
     659       14623 :             poDef->nPointSize == poNewSymbolDef->nPointSize &&
     660       14621 :             poDef->_nUnknownValue_ == poNewSymbolDef->_nUnknownValue_ &&
     661       14621 :             poDef->rgbColor == poNewSymbolDef->rgbColor)
     662             :         {
     663       14621 :             nNewSymbolIndex = i + 1;  // Fount it!
     664       14621 :             poDef->nRefCount++;
     665             :         }
     666             :     }
     667             : 
     668             :     /*-----------------------------------------------------------------
     669             :      * OK, we did not find a match, then create a new entry
     670             :      *----------------------------------------------------------------*/
     671       14689 :     if (nNewSymbolIndex == 0)
     672             :     {
     673          68 :         if (m_numSymbols >= m_numAllocatedSymbols)
     674             :         {
     675             :             // Realloc array by blocks of 20 items
     676          66 :             m_numAllocatedSymbols += 20;
     677          66 :             m_papsSymbol = static_cast<TABSymbolDef **>(CPLRealloc(
     678          66 :                 m_papsSymbol, m_numAllocatedSymbols * sizeof(TABSymbolDef *)));
     679             :         }
     680         136 :         m_papsSymbol[m_numSymbols] =
     681          68 :             static_cast<TABSymbolDef *>(CPLCalloc(1, sizeof(TABSymbolDef)));
     682             : 
     683          68 :         *m_papsSymbol[m_numSymbols] = *poNewSymbolDef;
     684          68 :         m_papsSymbol[m_numSymbols]->nRefCount = 1;
     685          68 :         nNewSymbolIndex = ++m_numSymbols;
     686             :     }
     687             : 
     688       14689 :     return nNewSymbolIndex;
     689             : }
     690             : 
     691             : /**********************************************************************
     692             :  *                   TABToolDefTable::GetMinVersionNumber()
     693             :  *
     694             :  * Returns the minimum file version number that can accept all the
     695             :  * tool objects currently defined.
     696             :  *
     697             :  * Default is 300, and currently 450 can be returned if file contains
     698             :  * pen widths defined in points.
     699             :  **********************************************************************/
     700         108 : int TABToolDefTable::GetMinVersionNumber()
     701             : {
     702         108 :     int i, nVersion = 300;
     703             : 
     704             :     /*-----------------------------------------------------------------
     705             :      * Scan Pen Defs
     706             :      *----------------------------------------------------------------*/
     707         149 :     for (i = 0; i < m_numPen; i++)
     708             :     {
     709          41 :         if (m_papsPen[i]->nPointWidth > 0)
     710             :         {
     711           0 :             nVersion = std::max(nVersion, 450);  // Raise version to 450
     712             :         }
     713             :     }
     714             : 
     715         108 :     return nVersion;
     716             : }

Generated by: LCOV version 1.14