1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/graphite2/src/inc/Bidi.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,126 @@ 1.4 +/* GRAPHITE2 LICENSING 1.5 + 1.6 + Copyright 2013, SIL International 1.7 + All rights reserved. 1.8 + 1.9 + This library is free software; you can redistribute it and/or modify 1.10 + it under the terms of the GNU Lesser General Public License as published 1.11 + by the Free Software Foundation; either version 2.1 of License, or 1.12 + (at your option) any later version. 1.13 + 1.14 + This program is distributed in the hope that it will be useful, 1.15 + but WITHOUT ANY WARRANTY; without even the implied warranty of 1.16 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 1.17 + Lesser General Public License for more details. 1.18 + 1.19 + You should also have received a copy of the GNU Lesser General Public 1.20 + License along with this library in the file named "LICENSE". 1.21 + If not, write to the Free Software Foundation, 51 Franklin Street, 1.22 + Suite 500, Boston, MA 02110-1335, USA or visit their web page on the 1.23 + internet at http://www.fsf.org/licenses/lgpl.html. 1.24 + 1.25 +Alternatively, the contents of this file may be used under the terms of the 1.26 +Mozilla Public License (http://mozilla.org/MPL) or the GNU General Public 1.27 +License, as published by the Free Software Foundation, either version 2 1.28 +of the License or (at your option) any later version. 1.29 +*/ 1.30 +#pragma once 1.31 + 1.32 +namespace graphite2 1.33 +{ 1.34 + 1.35 +class BracketPair 1.36 +{ 1.37 +public: 1.38 + BracketPair(uint16 g, Slot *s, uint8 b, BracketPair *p, BracketPair *l) : _open(s), _close(0), _parent(p), _next(0), _prev(l), _gid(g), _mask(0), _before(b) {}; 1.39 + uint16 gid() const { return _gid; } 1.40 + Slot *open() const { return _open; } 1.41 + Slot *close() const { return _close; } 1.42 + uint8 mask() const { return _mask; } 1.43 + int8 before() const { return _before; } 1.44 + BracketPair *parent() const { return _parent; } 1.45 + void close(Slot *s) { _close = s; } 1.46 + BracketPair *next() const { return _next; } 1.47 + BracketPair *prev() const { return _prev; } 1.48 + void next(BracketPair *n) { _next = n; } 1.49 + void orin(uint8 m) { _mask |= m; } 1.50 +private: 1.51 + Slot * _open; // Slot of opening paren 1.52 + Slot * _close; // Slot of closing paren 1.53 + BracketPair * _parent; // pair this pair is in or NULL 1.54 + BracketPair * _next; // next pair along the string 1.55 + BracketPair * _prev; // pair that closed last before we opened 1.56 + uint16 _gid; // gid of closing paren 1.57 + uint8 _mask; // bitmap (2 bits) of directions within the pair 1.58 + int8 _before; // most recent strong type (L, R, OPP, CPP) 1.59 +}; 1.60 + 1.61 +class BracketPairStack 1.62 +{ 1.63 +public: 1.64 + BracketPairStack(int s) : _stack(grzeroalloc<BracketPair>(s)), _ip(_stack - 1), _top(0), _last(0), _lastclose(0), _size(s) {} 1.65 + ~BracketPairStack() { free(_stack); } 1.66 + 1.67 +public: 1.68 + BracketPair *scan(uint16 gid); 1.69 + void close(BracketPair *tos, Slot *s); 1.70 + BracketPair *push(uint16 gid, Slot *pos, uint8 before, int prevopen); 1.71 + void orin(uint8 mask); 1.72 + void clear() { _ip = _stack - 1; _top = 0; _last = 0; _lastclose = 0; } 1.73 + int size() const { return _size; } 1.74 + BracketPair *start() const { return _stack; } 1.75 + 1.76 + CLASS_NEW_DELETE 1.77 + 1.78 +private: 1.79 + 1.80 + BracketPair *_stack; // start of storage 1.81 + BracketPair *_ip; // where to add the next pair 1.82 + BracketPair *_top; // current parent 1.83 + BracketPair *_last; // end of next() chain 1.84 + BracketPair *_lastclose; // last pair to close 1.85 + int _size; // capacity 1.86 +}; 1.87 + 1.88 +inline BracketPair *BracketPairStack::scan(uint16 gid) 1.89 +{ 1.90 + BracketPair *res = _top; 1.91 + while (res >= _stack) 1.92 + { 1.93 + if (res->gid() == gid) 1.94 + return res; 1.95 + res = res->parent(); 1.96 + } 1.97 + return 0; 1.98 +} 1.99 + 1.100 +inline void BracketPairStack::close(BracketPair *tos, Slot *s) 1.101 +{ 1.102 + for ( ; _last && _last != tos && !_last->close(); _last = _last->parent()) 1.103 + { } 1.104 + tos->close(s); 1.105 + _last->next(NULL); 1.106 + _lastclose = tos; 1.107 + _top = tos->parent(); 1.108 +} 1.109 + 1.110 +inline BracketPair *BracketPairStack::push(uint16 gid, Slot *pos, uint8 before, int prevopen) 1.111 +{ 1.112 + if (++_ip - _stack < _size && _stack) 1.113 + { 1.114 + ::new (_ip) BracketPair(gid, pos, before, _top, prevopen ? _last : _lastclose); 1.115 + if (_last) _last->next(_ip); 1.116 + _last = _ip; 1.117 + } 1.118 + _top = _ip; 1.119 + return _ip; 1.120 +} 1.121 + 1.122 +inline void BracketPairStack::orin(uint8 mask) 1.123 +{ 1.124 + BracketPair *t = _top; 1.125 + for ( ; t; t = t->parent()) 1.126 + t->orin(mask); 1.127 +} 1.128 + 1.129 +}