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