Collider.h (8722B)
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 const Rect &limit() const { return _limit; } 78 void setLimit(const Rect &r) { _limit = r; } 79 SLOTCOLSETPOSITIONPROP(shift, setShift) 80 SLOTCOLSETPOSITIONPROP(offset, setOffset) 81 SLOTCOLSETPOSITIONPROP(exclOffset, setExclOffset) 82 SLOTCOLSETUINTPROP(margin, setMargin) 83 SLOTCOLSETUINTPROP(marginWt, setMarginWt) 84 SLOTCOLSETUINTPROP(flags, setFlags) 85 SLOTCOLSETUINTPROP(exclGlyph, setExclGlyph) 86 SLOTCOLSETUINTPROP(seqClass, setSeqClass) 87 SLOTCOLSETUINTPROP(seqProxClass, setSeqProxClass) 88 SLOTCOLSETUINTPROP(seqOrder, setSeqOrder) 89 SLOTCOLSETINTPROP(seqAboveXoff, setSeqAboveXoff) 90 SLOTCOLSETUINTPROP(seqAboveWt, setSeqAboveWt) 91 SLOTCOLSETINTPROP(seqBelowXlim, setSeqBelowXlim) 92 SLOTCOLSETUINTPROP(seqBelowWt, setSeqBelowWt) 93 SLOTCOLSETUINTPROP(seqValignHt, setSeqValignHt) 94 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 ~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 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 _seqOrder(0) 180 { 181 #if !defined GRAPHITE2_NTRACING 182 for (int i = 0; i < 4; ++i) 183 _ranges[i].setdebug(dbgout); 184 #endif 185 } 186 187 class KernCollider 188 { 189 public: 190 KernCollider(json *dbg); 191 ~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 bool _hit; 214 215 #if !defined GRAPHITE2_NTRACING 216 // Debugging 217 Segment * _seg; 218 Vector<float> _nearEdges; // closest potential collision in each slice 219 Vector<Slot*> _slotNear; 220 #endif 221 }; // end of class KernCollider 222 223 224 inline 225 float sqr(float x) { 226 return x * x; 227 } 228 229 inline 230 KernCollider::KernCollider(GR_MAYBE_UNUSED json *dbg) 231 : _target(0), 232 _margin(0.0f), 233 _miny(-1e38f), 234 _maxy(1e38f), 235 _sliceWidth(0.0f), 236 _mingap(0.0f), 237 _xbound(0.0), 238 _hit(false) 239 { 240 #if !defined GRAPHITE2_NTRACING 241 _seg = 0; 242 #endif 243 }; 244 245 }; // end of namespace graphite2