/work/workdir/UnpackedTarball/graphite/src/CmapCache.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | /* GRAPHITE2 LICENSING |
2 | | |
3 | | Copyright 2010, SIL International |
4 | | All rights reserved. |
5 | | |
6 | | This library is free software; you can redistribute it and/or modify |
7 | | it under the terms of the GNU Lesser General Public License as published |
8 | | by the Free Software Foundation; either version 2.1 of License, or |
9 | | (at your option) any later version. |
10 | | |
11 | | This program is distributed in the hope that it will be useful, |
12 | | but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
14 | | Lesser General Public License for more details. |
15 | | |
16 | | You should also have received a copy of the GNU Lesser General Public |
17 | | License along with this library in the file named "LICENSE". |
18 | | If not, write to the Free Software Foundation, 51 Franklin Street, |
19 | | Suite 500, Boston, MA 02110-1335, USA or visit their web page on the |
20 | | internet at http://www.fsf.org/licenses/lgpl.html. |
21 | | |
22 | | Alternatively, the contents of this file may be used under the terms of the |
23 | | Mozilla Public License (http://mozilla.org/MPL) or the GNU General Public |
24 | | License, as published by the Free Software Foundation, either version 2 |
25 | | of the License or (at your option) any later version. |
26 | | */ |
27 | | |
28 | | #include "inc/Main.h" |
29 | | #include "inc/CmapCache.h" |
30 | | #include "inc/Face.h" |
31 | | #include "inc/TtfTypes.h" |
32 | | #include "inc/TtfUtil.h" |
33 | | |
34 | | |
35 | | using namespace graphite2; |
36 | | |
37 | | const void * bmp_subtable(const Face::Table & cmap) |
38 | 0 | { |
39 | 0 | const void * stbl; |
40 | 0 | if (!cmap.size()) return 0; |
41 | 0 | if (TtfUtil::CheckCmapSubtable4(stbl = TtfUtil::FindCmapSubtable(cmap, 3, 1, cmap.size()), cmap + cmap.size()) |
42 | 0 | || TtfUtil::CheckCmapSubtable4(stbl = TtfUtil::FindCmapSubtable(cmap, 0, 3, cmap.size()), cmap + cmap.size()) |
43 | 0 | || TtfUtil::CheckCmapSubtable4(stbl = TtfUtil::FindCmapSubtable(cmap, 0, 2, cmap.size()), cmap + cmap.size()) |
44 | 0 | || TtfUtil::CheckCmapSubtable4(stbl = TtfUtil::FindCmapSubtable(cmap, 0, 1, cmap.size()), cmap + cmap.size()) |
45 | 0 | || TtfUtil::CheckCmapSubtable4(stbl = TtfUtil::FindCmapSubtable(cmap, 0, 0, cmap.size()), cmap + cmap.size())) |
46 | 0 | return stbl; |
47 | 0 | return 0; |
48 | 0 | } |
49 | | |
50 | | const void * smp_subtable(const Face::Table & cmap) |
51 | 0 | { |
52 | 0 | const void * stbl; |
53 | 0 | if (!cmap.size()) return 0; |
54 | 0 | if (TtfUtil::CheckCmapSubtable12(stbl = TtfUtil::FindCmapSubtable(cmap, 3, 10, cmap.size()), cmap + cmap.size()) |
55 | 0 | || TtfUtil::CheckCmapSubtable12(stbl = TtfUtil::FindCmapSubtable(cmap, 0, 4, cmap.size()), cmap + cmap.size())) |
56 | 0 | return stbl; |
57 | 0 | return 0; |
58 | 0 | } |
59 | | |
60 | | template <unsigned int (*NextCodePoint)(const void *, unsigned int, int *), |
61 | | uint16 (*LookupCodePoint)(const void *, unsigned int, int)> |
62 | | bool cache_subtable(uint16 * blocks[], const void * cst, const unsigned int limit) |
63 | 0 | { |
64 | 0 | int rangeKey = 0; |
65 | 0 | uint32 codePoint = NextCodePoint(cst, 0, &rangeKey), |
66 | 0 | prevCodePoint = 0; |
67 | 0 | while (codePoint < limit) |
68 | 0 | { |
69 | 0 | unsigned int block = codePoint >> 8; |
70 | 0 | if (!blocks[block]) |
71 | 0 | { |
72 | 0 | blocks[block] = grzeroalloc<uint16>(0x100); |
73 | 0 | if (!blocks[block]) |
74 | 0 | return false; |
75 | 0 | } |
76 | 0 | blocks[block][codePoint & 0xFF] = LookupCodePoint(cst, codePoint, rangeKey); |
77 | | // prevent infinite loop |
78 | 0 | if (codePoint <= prevCodePoint) |
79 | 0 | codePoint = prevCodePoint + 1; |
80 | 0 | prevCodePoint = codePoint; |
81 | 0 | codePoint = NextCodePoint(cst, codePoint, &rangeKey); |
82 | 0 | } |
83 | 0 | return true; |
84 | 0 | } Unexecuted instantiation: bool cache_subtable<&graphite2::TtfUtil::CmapSubtable12NextCodepoint, &graphite2::TtfUtil::CmapSubtable12Lookup>(unsigned short**, void const*, unsigned int) Unexecuted instantiation: bool cache_subtable<&graphite2::TtfUtil::CmapSubtable4NextCodepoint, &graphite2::TtfUtil::CmapSubtable4Lookup>(unsigned short**, void const*, unsigned int) |
85 | | |
86 | | |
87 | | CachedCmap::CachedCmap(const Face & face) |
88 | 0 | : m_isBmpOnly(true), |
89 | 0 | m_blocks(0) |
90 | 0 | { |
91 | 0 | const Face::Table cmap(face, Tag::cmap); |
92 | 0 | if (!cmap) return; |
93 | | |
94 | 0 | const void * bmp_cmap = bmp_subtable(cmap); |
95 | 0 | const void * smp_cmap = smp_subtable(cmap); |
96 | 0 | m_isBmpOnly = !smp_cmap; |
97 | |
|
98 | 0 | m_blocks = grzeroalloc<uint16 *>(m_isBmpOnly ? 0x100 : 0x1100); |
99 | 0 | if (m_blocks && smp_cmap) |
100 | 0 | { |
101 | 0 | if (!cache_subtable<TtfUtil::CmapSubtable12NextCodepoint, TtfUtil::CmapSubtable12Lookup>(m_blocks, smp_cmap, 0x10FFFF)) |
102 | 0 | return; |
103 | 0 | } |
104 | | |
105 | 0 | if (m_blocks && bmp_cmap) |
106 | 0 | { |
107 | 0 | if (!cache_subtable<TtfUtil::CmapSubtable4NextCodepoint, TtfUtil::CmapSubtable4Lookup>(m_blocks, bmp_cmap, 0xFFFF)) |
108 | 0 | return; |
109 | 0 | } |
110 | 0 | } |
111 | | |
112 | | CachedCmap::~CachedCmap() throw() |
113 | 0 | { |
114 | 0 | if (!m_blocks) return; |
115 | 0 | unsigned int numBlocks = (m_isBmpOnly)? 0x100 : 0x1100; |
116 | 0 | for (unsigned int i = 0; i < numBlocks; i++) |
117 | 0 | free(m_blocks[i]); |
118 | 0 | free(m_blocks); |
119 | 0 | } |
120 | | |
121 | | uint16 CachedCmap::operator [] (const uint32 usv) const throw() |
122 | 0 | { |
123 | 0 | if ((m_isBmpOnly && usv > 0xFFFF) || (usv > 0x10FFFF)) |
124 | 0 | return 0; |
125 | 0 | const uint32 block = 0xFFFF & (usv >> 8); |
126 | 0 | if (m_blocks[block]) |
127 | 0 | return m_blocks[block][usv & 0xFF]; |
128 | 0 | return 0; |
129 | 0 | }; |
130 | | |
131 | | CachedCmap::operator bool() const throw() |
132 | 0 | { |
133 | 0 | return m_blocks != 0; |
134 | 0 | } |
135 | | |
136 | | |
137 | | DirectCmap::DirectCmap(const Face & face) |
138 | 0 | : _cmap(face, Tag::cmap), |
139 | 0 | _smp(smp_subtable(_cmap)), |
140 | 0 | _bmp(bmp_subtable(_cmap)) |
141 | 0 | { |
142 | 0 | } |
143 | | |
144 | | uint16 DirectCmap::operator [] (const uint32 usv) const throw() |
145 | 0 | { |
146 | 0 | return usv > 0xFFFF |
147 | 0 | ? (_smp ? TtfUtil::CmapSubtable12Lookup(_smp, usv, 0) : 0) |
148 | 0 | : TtfUtil::CmapSubtable4Lookup(_bmp, usv, 0); |
149 | 0 | } |
150 | | |
151 | | DirectCmap::operator bool () const throw() |
152 | 0 | { |
153 | 0 | return _cmap && _bmp; |
154 | 0 | } |
155 | | |