summaryrefslogtreecommitdiffstats
path: root/gfx/graphite2/src/inc/Bidi.h
diff options
context:
space:
mode:
Diffstat (limited to 'gfx/graphite2/src/inc/Bidi.h')
-rw-r--r--gfx/graphite2/src/inc/Bidi.h126
1 files changed, 126 insertions, 0 deletions
diff --git a/gfx/graphite2/src/inc/Bidi.h b/gfx/graphite2/src/inc/Bidi.h
new file mode 100644
index 000000000..9593c7e14
--- /dev/null
+++ b/gfx/graphite2/src/inc/Bidi.h
@@ -0,0 +1,126 @@
+/* GRAPHITE2 LICENSING
+
+ Copyright 2013, SIL International
+ All rights reserved.
+
+ This library is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published
+ by the Free Software Foundation; either version 2.1 of License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should also have received a copy of the GNU Lesser General Public
+ License along with this library in the file named "LICENSE".
+ If not, write to the Free Software Foundation, 51 Franklin Street,
+ Suite 500, Boston, MA 02110-1335, USA or visit their web page on the
+ internet at http://www.fsf.org/licenses/lgpl.html.
+
+Alternatively, the contents of this file may be used under the terms of the
+Mozilla Public License (http://mozilla.org/MPL) or the GNU General Public
+License, as published by the Free Software Foundation, either version 2
+of the License or (at your option) any later version.
+*/
+#pragma once
+
+namespace graphite2
+{
+
+class BracketPair
+{
+public:
+ 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) {};
+ uint16 gid() const { return _gid; }
+ Slot *open() const { return _open; }
+ Slot *close() const { return _close; }
+ uint8 mask() const { return _mask; }
+ int8 before() const { return _before; }
+ BracketPair *parent() const { return _parent; }
+ void close(Slot *s) { _close = s; }
+ BracketPair *next() const { return _next; }
+ BracketPair *prev() const { return _prev; }
+ void next(BracketPair *n) { _next = n; }
+ void orin(uint8 m) { _mask |= m; }
+private:
+ Slot * _open; // Slot of opening paren
+ Slot * _close; // Slot of closing paren
+ BracketPair * _parent; // pair this pair is in or NULL
+ BracketPair * _next; // next pair along the string
+ BracketPair * _prev; // pair that closed last before we opened
+ uint16 _gid; // gid of closing paren
+ uint8 _mask; // bitmap (2 bits) of directions within the pair
+ int8 _before; // most recent strong type (L, R, OPP, CPP)
+};
+
+class BracketPairStack
+{
+public:
+ BracketPairStack(int s) : _stack(grzeroalloc<BracketPair>(s)), _ip(_stack - 1), _top(0), _last(0), _lastclose(0), _size(s) {}
+ ~BracketPairStack() { free(_stack); }
+
+public:
+ BracketPair *scan(uint16 gid);
+ void close(BracketPair *tos, Slot *s);
+ BracketPair *push(uint16 gid, Slot *pos, uint8 before, int prevopen);
+ void orin(uint8 mask);
+ void clear() { _ip = _stack - 1; _top = 0; _last = 0; _lastclose = 0; }
+ int size() const { return _size; }
+ BracketPair *start() const { return _stack; }
+
+ CLASS_NEW_DELETE
+
+private:
+
+ BracketPair *_stack; // start of storage
+ BracketPair *_ip; // where to add the next pair
+ BracketPair *_top; // current parent
+ BracketPair *_last; // end of next() chain
+ BracketPair *_lastclose; // last pair to close
+ int _size; // capacity
+};
+
+inline BracketPair *BracketPairStack::scan(uint16 gid)
+{
+ BracketPair *res = _top;
+ while (res >= _stack)
+ {
+ if (res->gid() == gid)
+ return res;
+ res = res->parent();
+ }
+ return 0;
+}
+
+inline void BracketPairStack::close(BracketPair *tos, Slot *s)
+{
+ for ( ; _last && _last != tos && !_last->close(); _last = _last->parent())
+ { }
+ tos->close(s);
+ _last->next(NULL);
+ _lastclose = tos;
+ _top = tos->parent();
+}
+
+inline BracketPair *BracketPairStack::push(uint16 gid, Slot *pos, uint8 before, int prevopen)
+{
+ if (++_ip - _stack < _size && _stack)
+ {
+ ::new (_ip) BracketPair(gid, pos, before, _top, prevopen ? _last : _lastclose);
+ if (_last) _last->next(_ip);
+ _last = _ip;
+ }
+ _top = _ip;
+ return _ip;
+}
+
+inline void BracketPairStack::orin(uint8 mask)
+{
+ BracketPair *t = _top;
+ for ( ; t; t = t->parent())
+ t->orin(mask);
+}
+
+}