1 /* 2 * FTGL - OpenGL font library 3 * 4 * Copyright (c) 2001-2004 Henry Maddocks <ftgl@opengl.geek.nz> 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining 7 * a copy of this software and associated documentation files (the 8 * "Software"), to deal in the Software without restriction, including 9 * without limitation the rights to use, copy, modify, merge, publish, 10 * distribute, sublicense, and/or sell copies of the Software, and to 11 * permit persons to whom the Software is furnished to do so, subject to 12 * the following conditions: 13 * 14 * The above copyright notice and this permission notice shall be 15 * included in all copies or substantial portions of the Software. 16 * 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 18 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 20 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 21 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 22 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 23 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 */ 25 26 #ifndef __FTCharToGlyphIndexMap__ 27 #define __FTCharToGlyphIndexMap__ 28 29 #include <stdlib.h> 30 31 #include "FTGL/ftgl.h" 32 33 /** 34 * Provides a non-STL alternative to the STL map<unsigned long, unsigned long> 35 * which maps character codes to glyph indices inside FTCharmap. 36 * 37 * Implementation: 38 * - NumberOfBuckets buckets are considered. 39 * - Each bucket has BucketSize entries. 40 * - When the glyph index for the character code C has to be stored, the 41 * bucket this character belongs to is found using 'C div BucketSize'. 42 * If this bucket has not been allocated yet, do it now. 43 * The entry in the bucked is found using 'C mod BucketSize'. 44 * If it is set to IndexNotFound, then the glyph entry has not been set. 45 * - Try to mimic the calls made to the STL map API. 46 * 47 * Caveats: 48 * - The glyph index is now a signed long instead of unsigned long, so 49 * the special value IndexNotFound (= -1) can be used to specify that the 50 * glyph index has not been stored yet. 51 */ 52 class FTCharToGlyphIndexMap 53 { 54 public: 55 56 typedef unsigned long CharacterCode; 57 typedef signed long GlyphIndex; 58 59 enum 60 { 61 NumberOfBuckets = 256, 62 BucketSize = 256, 63 IndexNotFound = -1 64 }; 65 FTCharToGlyphIndexMap()66 FTCharToGlyphIndexMap() 67 { 68 this->Indices = 0; 69 } 70 ~FTCharToGlyphIndexMap()71 virtual ~FTCharToGlyphIndexMap() 72 { 73 if(this->Indices) 74 { 75 // Free all buckets 76 this->clear(); 77 78 // Free main structure 79 delete [] this->Indices; 80 this->Indices = 0; 81 } 82 } 83 clear()84 void clear() 85 { 86 if(this->Indices) 87 { 88 for(int i = 0; i < FTCharToGlyphIndexMap::NumberOfBuckets; i++) 89 { 90 if(this->Indices[i]) 91 { 92 delete [] this->Indices[i]; 93 this->Indices[i] = 0; 94 } 95 } 96 } 97 } 98 find(CharacterCode c)99 const GlyphIndex find(CharacterCode c) 100 { 101 if(!this->Indices) 102 { 103 return 0; 104 } 105 106 // Find position of char code in buckets 107 div_t pos = div(c, FTCharToGlyphIndexMap::BucketSize); 108 109 if(!this->Indices[pos.quot]) 110 { 111 return 0; 112 } 113 114 const FTCharToGlyphIndexMap::GlyphIndex *ptr = &this->Indices[pos.quot][pos.rem]; 115 if(*ptr == FTCharToGlyphIndexMap::IndexNotFound) 116 { 117 return 0; 118 } 119 120 return *ptr; 121 } 122 insert(CharacterCode c,GlyphIndex g)123 void insert(CharacterCode c, GlyphIndex g) 124 { 125 if(!this->Indices) 126 { 127 this->Indices = new GlyphIndex* [FTCharToGlyphIndexMap::NumberOfBuckets]; 128 for(int i = 0; i < FTCharToGlyphIndexMap::NumberOfBuckets; i++) 129 { 130 this->Indices[i] = 0; 131 } 132 } 133 134 // Find position of char code in buckets 135 div_t pos = div(c, FTCharToGlyphIndexMap::BucketSize); 136 137 // Allocate bucket if does not exist yet 138 if(!this->Indices[pos.quot]) 139 { 140 this->Indices[pos.quot] = new GlyphIndex [FTCharToGlyphIndexMap::BucketSize]; 141 for(int i = 0; i < FTCharToGlyphIndexMap::BucketSize; i++) 142 { 143 this->Indices[pos.quot][i] = FTCharToGlyphIndexMap::IndexNotFound; 144 } 145 } 146 147 this->Indices[pos.quot][pos.rem] = g; 148 } 149 150 private: 151 GlyphIndex** Indices; 152 }; 153 154 155 #endif // __FTCharToGlyphIndexMap__ 156