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 "inc/List.h"
30 : #include "inc/Position.h"
31 : #include "inc/Intervals.h"
32 : #include "inc/debug.h"
33 :
34 : namespace graphite2 {
35 :
36 : class json;
37 : class Slot;
38 : class Segment;
39 :
40 : #define SLOTCOLSETUINTPROP(x, y) uint16 x() const { return _ ##x; } void y (uint16 v) { _ ##x = v; }
41 : #define SLOTCOLSETINTPROP(x, y) int16 x() const { return _ ##x; } void y (int16 v) { _ ##x = v; }
42 : #define SLOTCOLSETPOSITIONPROP(x, y) const Position &x() const { return _ ##x; } void y (const Position &v) { _ ##x = v; }
43 :
44 : // Slot attributes related to collision-fixing
45 : class SlotCollision
46 : {
47 : public:
48 : enum {
49 : // COLL_TESTONLY = 0, // default - test other glyphs for collision with this one, but don't move this one
50 : COLL_FIX = 1, // fix collisions involving this glyph
51 : COLL_IGNORE = 2, // ignore this glyph altogether
52 : COLL_START = 4, // start of range of possible collisions
53 : COLL_END = 8, // end of range of possible collisions
54 : COLL_KERN = 16, // collisions with this glyph are fixed by adding kerning space after it
55 : COLL_ISCOL = 32, // this glyph has a collision
56 : COLL_KNOWN = 64, // we've figured out what's happening with this glyph
57 : COLL_ISSPACE = 128, // treat this glyph as a space with regard to kerning
58 : COLL_TEMPLOCK = 256, // Lock glyphs that have been given priority positioning
59 : ////COLL_JUMPABLE = 128, // moving glyphs may jump this stationary glyph in any direction - DELETE
60 : ////COLL_OVERLAP = 256, // use maxoverlap to restrict - DELETE
61 : };
62 :
63 : // Behavior for the collision.order attribute. To GDL this is an enum, to us it's a bitfield, with only 1 bit set
64 : // Allows for easier inversion.
65 : enum {
66 : SEQ_ORDER_LEFTDOWN = 1,
67 : SEQ_ORDER_RIGHTUP = 2,
68 : SEQ_ORDER_NOABOVE = 4,
69 : SEQ_ORDER_NOBELOW = 8,
70 : SEQ_ORDER_NOLEFT = 16,
71 : SEQ_ORDER_NORIGHT = 32
72 : };
73 :
74 : SlotCollision(Segment *seg, Slot *slot);
75 : void initFromSlot(Segment *seg, Slot *slot);
76 :
77 0 : const Rect &limit() const { return _limit; }
78 0 : void setLimit(const Rect &r) { _limit = r; }
79 0 : SLOTCOLSETPOSITIONPROP(shift, setShift)
80 0 : SLOTCOLSETPOSITIONPROP(offset, setOffset)
81 0 : SLOTCOLSETPOSITIONPROP(exclOffset, setExclOffset)
82 0 : SLOTCOLSETUINTPROP(margin, setMargin)
83 0 : SLOTCOLSETUINTPROP(marginWt, setMarginWt)
84 0 : SLOTCOLSETUINTPROP(flags, setFlags)
85 0 : SLOTCOLSETUINTPROP(exclGlyph, setExclGlyph)
86 0 : SLOTCOLSETUINTPROP(seqClass, setSeqClass)
87 0 : SLOTCOLSETUINTPROP(seqProxClass, setSeqProxClass)
88 0 : SLOTCOLSETUINTPROP(seqOrder, setSeqOrder)
89 0 : SLOTCOLSETINTPROP(seqAboveXoff, setSeqAboveXoff)
90 0 : SLOTCOLSETUINTPROP(seqAboveWt, setSeqAboveWt)
91 0 : SLOTCOLSETINTPROP(seqBelowXlim, setSeqBelowXlim)
92 0 : SLOTCOLSETUINTPROP(seqBelowWt, setSeqBelowWt)
93 0 : SLOTCOLSETUINTPROP(seqValignHt, setSeqValignHt)
94 0 : SLOTCOLSETUINTPROP(seqValignWt, setSeqValignWt)
95 :
96 : float getKern(int dir) const;
97 : bool ignore() const;
98 :
99 : private:
100 : Rect _limit;
101 : Position _shift; // adjustment within the given pass
102 : Position _offset; // total adjustment for collisions
103 : Position _exclOffset;
104 : uint16 _margin;
105 : uint16 _marginWt;
106 : uint16 _flags;
107 : uint16 _exclGlyph;
108 : uint16 _seqClass;
109 : uint16 _seqProxClass;
110 : uint16 _seqOrder;
111 : int16 _seqAboveXoff;
112 : uint16 _seqAboveWt;
113 : int16 _seqBelowXlim;
114 : uint16 _seqBelowWt;
115 : uint16 _seqValignHt;
116 : uint16 _seqValignWt;
117 :
118 : }; // end of class SlotColllision
119 :
120 : struct BBox;
121 : struct SlantBox;
122 :
123 : class ShiftCollider
124 : {
125 : public:
126 : typedef std::pair<float, float> fpair;
127 : typedef Vector<fpair> vfpairs;
128 : typedef vfpairs::iterator ivfpairs;
129 :
130 : ShiftCollider(json *dbgout);
131 0 : ~ShiftCollider() throw() { };
132 :
133 : bool initSlot(Segment *seg, Slot *aSlot, const Rect &constraint,
134 : float margin, float marginMin, const Position &currShift,
135 : const Position &currOffset, int dir, GR_MAYBE_UNUSED json * const dbgout);
136 : bool mergeSlot(Segment *seg, Slot *slot, const SlotCollision *cinfo, const Position &currShift, bool isAfter,
137 : bool sameCluster, bool &hasCol, bool isExclusion, GR_MAYBE_UNUSED json * const dbgout);
138 : Position resolve(Segment *seg, bool &isCol, GR_MAYBE_UNUSED json * const dbgout);
139 : void addBox_slope(bool isx, const Rect &box, const BBox &bb, const SlantBox &sb, const Position &org, float weight, float m, bool minright, int mode);
140 : void removeBox(const Rect &box, const BBox &bb, const SlantBox &sb, const Position &org, int mode);
141 : const Position &origin() const { return _origin; }
142 :
143 : #if !defined GRAPHITE2_NTRACING
144 : void outputJsonDbg(json * const dbgout, Segment *seg, int axis);
145 : void outputJsonDbgStartSlot(json * const dbgout, Segment *seg);
146 : void outputJsonDbgEndSlot(json * const dbgout, Position resultPos, int bestAxis, bool isCol);
147 : void outputJsonDbgOneVector(json * const dbgout, Segment *seg, int axis, float tleft, float bestCost, float bestVal);
148 : void outputJsonDbgRawRanges(json * const dbgout, int axis);
149 : void outputJsonDbgRemovals(json * const dbgout, int axis, Segment *seg);
150 : #endif
151 :
152 : CLASS_NEW_DELETE;
153 :
154 : protected:
155 : Zones _ranges[4]; // possible movements in 4 directions (horizontally, vertically, diagonally);
156 : Slot * _target; // the glyph to fix
157 : Rect _limit;
158 : Position _currShift;
159 : Position _currOffset;
160 : Position _origin; // Base for all relative calculations
161 : float _margin;
162 : float _marginWt;
163 : float _len[4];
164 : uint16 _seqClass;
165 : uint16 _seqProxClass;
166 : uint16 _seqOrder;
167 :
168 : //bool _scraping[4];
169 :
170 : }; // end of class ShiftCollider
171 :
172 : inline
173 0 : ShiftCollider::ShiftCollider(GR_MAYBE_UNUSED json *dbgout)
174 : : _target(0),
175 : _margin(0.0),
176 : _marginWt(0.0),
177 : _seqClass(0),
178 : _seqProxClass(0),
179 0 : _seqOrder(0)
180 : {
181 : #if !defined GRAPHITE2_NTRACING
182 : for (int i = 0; i < 4; ++i)
183 : _ranges[i].setdebug(dbgout);
184 : #endif
185 0 : }
186 :
187 : class KernCollider
188 : {
189 : public:
190 : KernCollider(json *dbg);
191 0 : ~KernCollider() throw() { };
192 : bool initSlot(Segment *seg, Slot *aSlot, const Rect &constraint, float margin,
193 : const Position &currShift, const Position &offsetPrev, int dir,
194 : float ymin, float ymax, json * const dbgout);
195 : bool mergeSlot(Segment *seg, Slot *slot, const Position &currShift, float currSpace, int dir, json * const dbgout);
196 : Position resolve(Segment *seg, Slot *slot, int dir, json * const dbgout);
197 : void shift(const Position &mv, int dir);
198 :
199 : CLASS_NEW_DELETE;
200 :
201 : private:
202 : Slot * _target; // the glyph to fix
203 : Rect _limit;
204 : float _margin;
205 : Position _offsetPrev; // kern from a previous pass
206 : Position _currShift; // NOT USED??
207 : float _miny; // y-coordinates offset by global slot position
208 : float _maxy;
209 : Vector<float> _edges; // edges of horizontal slices
210 : float _sliceWidth; // width of each slice
211 : float _mingap;
212 : float _xbound; // max or min edge
213 :
214 : #if !defined GRAPHITE2_NTRACING
215 : // Debugging
216 : Segment * _seg;
217 : Vector<float> _nearEdges; // closest potential collision in each slice
218 : Vector<Slot*> _slotNear;
219 : #endif
220 : }; // end of class KernCollider
221 :
222 :
223 : inline
224 0 : float sqr(float x) {
225 0 : return x * x;
226 : }
227 :
228 : inline
229 0 : KernCollider::KernCollider(GR_MAYBE_UNUSED json *dbg)
230 : : _target(0),
231 : _margin(0.0f),
232 : _miny(-1e38f),
233 : _maxy(1e38f),
234 : _sliceWidth(0.0f),
235 : _mingap(0.0f),
236 0 : _xbound(0.0)
237 : {
238 : #if !defined GRAPHITE2_NTRACING
239 : _seg = 0;
240 : #endif
241 0 : };
242 :
243 : }; // end of namespace graphite2
244 :
|