gfx/graphite2/src/inc/Bidi.h

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

michael@0 1 /* GRAPHITE2 LICENSING
michael@0 2
michael@0 3 Copyright 2013, SIL International
michael@0 4 All rights reserved.
michael@0 5
michael@0 6 This library is free software; you can redistribute it and/or modify
michael@0 7 it under the terms of the GNU Lesser General Public License as published
michael@0 8 by the Free Software Foundation; either version 2.1 of License, or
michael@0 9 (at your option) any later version.
michael@0 10
michael@0 11 This program is distributed in the hope that it will be useful,
michael@0 12 but WITHOUT ANY WARRANTY; without even the implied warranty of
michael@0 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
michael@0 14 Lesser General Public License for more details.
michael@0 15
michael@0 16 You should also have received a copy of the GNU Lesser General Public
michael@0 17 License along with this library in the file named "LICENSE".
michael@0 18 If not, write to the Free Software Foundation, 51 Franklin Street,
michael@0 19 Suite 500, Boston, MA 02110-1335, USA or visit their web page on the
michael@0 20 internet at http://www.fsf.org/licenses/lgpl.html.
michael@0 21
michael@0 22 Alternatively, the contents of this file may be used under the terms of the
michael@0 23 Mozilla Public License (http://mozilla.org/MPL) or the GNU General Public
michael@0 24 License, as published by the Free Software Foundation, either version 2
michael@0 25 of the License or (at your option) any later version.
michael@0 26 */
michael@0 27 #pragma once
michael@0 28
michael@0 29 namespace graphite2
michael@0 30 {
michael@0 31
michael@0 32 class BracketPair
michael@0 33 {
michael@0 34 public:
michael@0 35 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) {};
michael@0 36 uint16 gid() const { return _gid; }
michael@0 37 Slot *open() const { return _open; }
michael@0 38 Slot *close() const { return _close; }
michael@0 39 uint8 mask() const { return _mask; }
michael@0 40 int8 before() const { return _before; }
michael@0 41 BracketPair *parent() const { return _parent; }
michael@0 42 void close(Slot *s) { _close = s; }
michael@0 43 BracketPair *next() const { return _next; }
michael@0 44 BracketPair *prev() const { return _prev; }
michael@0 45 void next(BracketPair *n) { _next = n; }
michael@0 46 void orin(uint8 m) { _mask |= m; }
michael@0 47 private:
michael@0 48 Slot * _open; // Slot of opening paren
michael@0 49 Slot * _close; // Slot of closing paren
michael@0 50 BracketPair * _parent; // pair this pair is in or NULL
michael@0 51 BracketPair * _next; // next pair along the string
michael@0 52 BracketPair * _prev; // pair that closed last before we opened
michael@0 53 uint16 _gid; // gid of closing paren
michael@0 54 uint8 _mask; // bitmap (2 bits) of directions within the pair
michael@0 55 int8 _before; // most recent strong type (L, R, OPP, CPP)
michael@0 56 };
michael@0 57
michael@0 58 class BracketPairStack
michael@0 59 {
michael@0 60 public:
michael@0 61 BracketPairStack(int s) : _stack(grzeroalloc<BracketPair>(s)), _ip(_stack - 1), _top(0), _last(0), _lastclose(0), _size(s) {}
michael@0 62 ~BracketPairStack() { free(_stack); }
michael@0 63
michael@0 64 public:
michael@0 65 BracketPair *scan(uint16 gid);
michael@0 66 void close(BracketPair *tos, Slot *s);
michael@0 67 BracketPair *push(uint16 gid, Slot *pos, uint8 before, int prevopen);
michael@0 68 void orin(uint8 mask);
michael@0 69 void clear() { _ip = _stack - 1; _top = 0; _last = 0; _lastclose = 0; }
michael@0 70 int size() const { return _size; }
michael@0 71 BracketPair *start() const { return _stack; }
michael@0 72
michael@0 73 CLASS_NEW_DELETE
michael@0 74
michael@0 75 private:
michael@0 76
michael@0 77 BracketPair *_stack; // start of storage
michael@0 78 BracketPair *_ip; // where to add the next pair
michael@0 79 BracketPair *_top; // current parent
michael@0 80 BracketPair *_last; // end of next() chain
michael@0 81 BracketPair *_lastclose; // last pair to close
michael@0 82 int _size; // capacity
michael@0 83 };
michael@0 84
michael@0 85 inline BracketPair *BracketPairStack::scan(uint16 gid)
michael@0 86 {
michael@0 87 BracketPair *res = _top;
michael@0 88 while (res >= _stack)
michael@0 89 {
michael@0 90 if (res->gid() == gid)
michael@0 91 return res;
michael@0 92 res = res->parent();
michael@0 93 }
michael@0 94 return 0;
michael@0 95 }
michael@0 96
michael@0 97 inline void BracketPairStack::close(BracketPair *tos, Slot *s)
michael@0 98 {
michael@0 99 for ( ; _last && _last != tos && !_last->close(); _last = _last->parent())
michael@0 100 { }
michael@0 101 tos->close(s);
michael@0 102 _last->next(NULL);
michael@0 103 _lastclose = tos;
michael@0 104 _top = tos->parent();
michael@0 105 }
michael@0 106
michael@0 107 inline BracketPair *BracketPairStack::push(uint16 gid, Slot *pos, uint8 before, int prevopen)
michael@0 108 {
michael@0 109 if (++_ip - _stack < _size && _stack)
michael@0 110 {
michael@0 111 ::new (_ip) BracketPair(gid, pos, before, _top, prevopen ? _last : _lastclose);
michael@0 112 if (_last) _last->next(_ip);
michael@0 113 _last = _ip;
michael@0 114 }
michael@0 115 _top = _ip;
michael@0 116 return _ip;
michael@0 117 }
michael@0 118
michael@0 119 inline void BracketPairStack::orin(uint8 mask)
michael@0 120 {
michael@0 121 BracketPair *t = _top;
michael@0 122 for ( ; t; t = t->parent())
michael@0 123 t->orin(mask);
michael@0 124 }
michael@0 125
michael@0 126 }

mercurial