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

Generated by: LCOV version 1.14