Line data Source code
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 : #pragma once
28 :
29 : #include <utility>
30 :
31 : #include "inc/Main.h"
32 : #include "inc/List.h"
33 : #include "inc/json.h"
34 : #include "inc/Position.h"
35 :
36 : // An IntervalSet represents the possible movement of a given glyph in a given direction
37 : // (horizontally, vertically, or diagonally).
38 : // A vector is needed to represent disjoint ranges, eg, -300..-150, 20..200, 500..750.
39 : // Each pair represents the min/max of a sub-range.
40 :
41 : namespace graphite2 {
42 :
43 : class Segment;
44 :
45 : enum zones_t {SD, XY};
46 :
47 0 : class Zones
48 : {
49 : struct Exclusion
50 : {
51 : template<zones_t O>
52 : static Exclusion weighted(float xmin, float xmax, float f, float a0,
53 : float m, float xi, float ai, float c, bool nega);
54 :
55 : float x, // x position
56 : xm, // xmax position
57 : c, // constant + sum(MiXi^2)
58 : sm, // sum(Mi)
59 : smx; // sum(MiXi)
60 : bool open;
61 :
62 : Exclusion(float x, float w, float smi, float smxi, float c);
63 : Exclusion & operator += (Exclusion const & rhs);
64 : uint8 outcode(float p) const;
65 :
66 : Exclusion split_at(float p);
67 : void left_trim(float p);
68 :
69 : bool track_cost(float & cost, float & x, float origin) const;
70 :
71 : private:
72 : float test_position(float origin) const;
73 : float cost(float x) const;
74 : };
75 :
76 : typedef Vector<Exclusion> exclusions;
77 :
78 : typedef exclusions::iterator iterator;
79 : typedef Exclusion * pointer;
80 : typedef Exclusion & reference;
81 : typedef std::reverse_iterator<iterator> reverse_iterator;
82 :
83 : public:
84 : typedef exclusions::const_iterator const_iterator;
85 : typedef Exclusion const * const_pointer;
86 : typedef Exclusion const & const_reference;
87 : typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
88 :
89 : #if !defined GRAPHITE2_NTRACING
90 : struct Debug
91 : {
92 : Exclusion _excl;
93 : bool _isdel;
94 : Vector<void *> _env;
95 :
96 : Debug(Exclusion *e, bool isdel, json *dbg) : _excl(*e), _isdel(isdel), _env(dbg->getenvs()) { };
97 : };
98 :
99 : typedef Vector<Debug> debugs;
100 : typedef debugs::const_iterator idebugs;
101 : void addDebug(Exclusion *e);
102 : void removeDebug(float pos, float posm);
103 : void setdebug(json *dbgout) { _dbg = dbgout; }
104 : idebugs dbgs_begin() const { return _dbgs.begin(); }
105 : idebugs dbgs_end() const { return _dbgs.end(); }
106 : void jsonDbgOut(Segment *seg) const;
107 : Position position() const { return Position(_pos, _posm); }
108 : #endif
109 :
110 : Zones();
111 : template<zones_t O>
112 : void initialise(float xmin, float xmax, float margin_len, float margin_weight, float ao);
113 :
114 : void exclude(float xmin, float xmax);
115 : void exclude_with_margins(float xmin, float xmax, int axis);
116 :
117 : template<zones_t O>
118 : void weighted(float xmin, float xmax, float f, float a0, float mi, float xi, float ai, float c, bool nega);
119 : void weightedAxis(int axis, float xmin, float xmax, float f, float a0, float mi, float xi, float ai, float c, bool nega);
120 :
121 : float closest( float origin, float &cost) const;
122 :
123 : const_iterator begin() const { return _exclusions.begin(); }
124 : const_iterator end() const { return _exclusions.end(); }
125 :
126 : private:
127 : exclusions _exclusions;
128 : #if !defined GRAPHITE2_NTRACING
129 : json * _dbg;
130 : debugs _dbgs;
131 : #endif
132 : float _margin_len,
133 : _margin_weight,
134 : _pos,
135 : _posm;
136 :
137 : void insert(Exclusion e);
138 : void remove(float x, float xm);
139 : const_iterator find_exclusion_under(float x) const;
140 : };
141 :
142 :
143 : inline
144 0 : Zones::Zones()
145 0 : : _margin_len(0), _margin_weight(0), _pos(0), _posm(0)
146 : {
147 : #if !defined GRAPHITE2_NTRACING
148 : _dbg = 0;
149 : #endif
150 0 : _exclusions.reserve(8);
151 0 : }
152 :
153 : inline
154 0 : Zones::Exclusion::Exclusion(float x_, float xm_, float smi, float smxi, float c_)
155 0 : : x(x_), xm(xm_), c(c_), sm(smi), smx(smxi), open(false)
156 0 : { }
157 :
158 : template<zones_t O>
159 : inline
160 0 : void Zones::initialise(float xmin, float xmax, float margin_len,
161 : float margin_weight, float a0)
162 : {
163 0 : _margin_len = margin_len;
164 0 : _margin_weight = margin_weight;
165 0 : _pos = xmin;
166 0 : _posm = xmax;
167 0 : _exclusions.clear();
168 0 : _exclusions.push_back(Exclusion::weighted<O>(xmin, xmax, 1, a0, 0, 0, 0, 0, false));
169 0 : _exclusions.front().open = true;
170 : #if !defined GRAPHITE2_NTRACING
171 : _dbgs.clear();
172 : #endif
173 0 : }
174 :
175 : inline
176 0 : void Zones::exclude(float xmin, float xmax) {
177 0 : remove(xmin, xmax);
178 0 : }
179 :
180 : template<zones_t O>
181 : inline
182 0 : void Zones::weighted(float xmin, float xmax, float f, float a0,
183 : float m, float xi, float ai, float c, bool nega) {
184 0 : insert(Exclusion::weighted<O>(xmin, xmax, f, a0, m, xi, ai, c, nega));
185 0 : }
186 :
187 : inline
188 0 : void Zones::weightedAxis(int axis, float xmin, float xmax, float f, float a0,
189 : float m, float xi, float ai, float c, bool nega) {
190 0 : if (axis < 2)
191 0 : weighted<XY>(xmin, xmax, f, a0, m, xi, ai, c, nega);
192 : else
193 0 : weighted<SD>(xmin, xmax, f, a0, m, xi, ai, c, nega);
194 0 : }
195 :
196 : #if !defined GRAPHITE2_NTRACING
197 : inline
198 : void Zones::addDebug(Exclusion *e) {
199 : if (_dbg)
200 : _dbgs.push_back(Debug(e, false, _dbg));
201 : }
202 :
203 : inline
204 : void Zones::removeDebug(float pos, float posm) {
205 : if (_dbg)
206 : {
207 : Exclusion e(pos, posm, 0, 0, 0);
208 : _dbgs.push_back(Debug(&e, true, _dbg));
209 : }
210 : }
211 : #endif
212 :
213 : template<>
214 : inline
215 0 : Zones::Exclusion Zones::Exclusion::weighted<XY>(float xmin, float xmax, float f, float a0,
216 : float m, float xi, GR_MAYBE_UNUSED float ai, float c, GR_MAYBE_UNUSED bool nega) {
217 : return Exclusion(xmin, xmax,
218 : m + f,
219 : m * xi,
220 0 : m * xi * xi + f * a0 * a0 + c);
221 : }
222 :
223 : template<>
224 : inline
225 0 : Zones::Exclusion Zones::Exclusion::weighted<SD>(float xmin, float xmax, float f, float a0,
226 : float m, float xi, float ai,float c, bool nega) {
227 0 : float xia = nega ? xi - ai : xi + ai;
228 : return Exclusion(xmin, xmax,
229 0 : 0.25f * (m + 2.f * f),
230 0 : 0.25f * m * xia,
231 0 : 0.25f * (m * xia * xia + 2.f * f * a0 * a0) + c);
232 : }
233 :
234 : } // end of namespace graphite2
|