1
0
mirror of https://github.com/roytam1/UXP.git synced 2026-05-26 13:58:49 +00:00

Update graphite2 lib to 1.3.10

(from 1.3.8)
This commit is contained in:
wolfbeast
2017-06-20 19:05:56 +02:00
committed by Roy Tam
parent 9ef2b80564
commit 4f027a0024
11 changed files with 32 additions and 1799 deletions
+31
View File
@@ -1,3 +1,34 @@
1.3.10
. Address floating point build parameters to give consistent positioning results across platforms
. Various bug fixes
1.3.9
. Add Collision COLL_ISSPACE to allow for visible spaces in collision avoidance
. Add segment and pass direction information to tracing output
. Bug fix rule length testing in 32-bit
. Increase slanted margin distances for collision avoidance
. Change kerning algorithm to simple outline expansion. Seems to make no visible difference.
. Add trace2svg to test tools
1.3.8
. Various bug fixes arising from fuzzing
. Fix regression that stopped piglatin from working
. Make collision avoidance kerning give more regular results
. Minor modification to clustering algorithm to handle variable width chars
1.3.7
. Bug fixes
. Start to deprecate SegCache. This will be going away in a later release.
1.3.6
. Bug fixes
1.3.5
. Bug fixes
. Security bug fix
. Fix ARM misalignment problem
. Track latest cmake
1.3.4
. Transition from Mercurial to Git
. Bug fixes
-55
View File
@@ -1,55 +0,0 @@
/* GRAPHITE2 LICENSING
Copyright 2010, 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
#include <graphite2/Types.h>
#include <stdio.h>
typedef enum {
GRLOG_NONE = 0x0,
GRLOG_FACE = 0x01,
GRLOG_SEGMENT = 0x02,
GRLOG_PASS = 0x04,
GRLOG_CACHE = 0x08,
GRLOG_OPCODE = 0x80,
GRLOG_ALL = 0xFF
} GrLogMask;
// If startGraphiteLogging returns true, logging is enabled and the FILE handle
// will be closed by graphite when stopGraphiteLogging is called.
#ifdef __cplusplus
extern "C"
{
#endif
GR2_API bool graphite_start_logging(FILE * logFile, GrLogMask mask); //may not do anthing if disabled in the implementation of the engine.
GR2_API void graphite_stop_logging();
#ifdef __cplusplus
}
#endif
-826
View File
@@ -1,826 +0,0 @@
/* GRAPHITE2 LICENSING
Copyright 2011, 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.
*/
#include "inc/Main.h"
#include "inc/Slot.h"
#include "inc/Segment.h"
#include "inc/Bidi.h"
using namespace graphite2;
enum DirCode { // Hungarian: dirc
Unk = -1,
N = 0, // other neutrals (default) - ON
L = 1, // left-to-right, strong - L
R = 2, // right-to-left, strong - R
AL = 3, // Arabic letter, right-to-left, strong, AR
EN = 4, // European number, left-to-right, weak - EN
EUS = 5, // European separator, left-to-right, weak - ES
ET = 6, // European number terminator, left-to-right, weak - ET
AN = 7, // Arabic number, left-to-right, weak - AN
CUS = 8, // Common number separator, left-to-right, weak - CS
WS = 9, // white space, neutral - WS
BN = 10, // boundary neutral - BN
LRO = 11, // LTR override
RLO = 12, // RTL override
LRE = 13, // LTR embedding
RLE = 14, // RTL embedding
PDF = 15, // pop directional format
NSM = 16, // non-space mark
LRI = 17, // LRI isolate
RLI = 18, // RLI isolate
FSI = 19, // FSI isolate
PDI = 20, // pop isolate
OPP = 21, // opening paired parenthesis
CPP = 22, // closing paired parenthesis
ON = N
};
enum DirMask {
WSflag = int8(1 << 7), // keep track of WS for eos handling
WSMask = int8(~(1 << 7))
};
inline uint8 BaseClass(Slot *s) { return s->getBidiClass() & WSMask; }
unsigned int bidi_class_map[] = { 0, 1, 2, 5, 4, 8, 9, 3, 7, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0 };
// Algorithms based on Unicode reference standard code. Thanks Asmus Freitag.
void resolveWeak(Slot *start, int sos, int eos);
void resolveNeutrals(Slot *s, int baseLevel, int sos, int eos);
void processParens(Slot *s, Segment *seg, uint8 aMirror, int level, BracketPairStack &stack);
inline int calc_base_level(Slot *s)
{
int count = 0;
for ( ; s; s = s->next())
{
int cls = s->getBidiClass();
if (count)
{
switch(cls)
{
case LRI :
case RLI :
case FSI :
++count;
break;
case PDI :
--count;
}
}
else
{
switch(cls)
{
case L :
return 0;
case R :
case AL :
return 1;
case LRI :
case RLI :
case FSI :
++count;
}
}
}
return 0;
}
// inline or not?
void do_resolves(Slot *start, int level, int sos, int eos, int &bmask, Segment *seg, uint8 aMirror, BracketPairStack &stack)
{
if (bmask & 0x1F1178)
resolveWeak(start, sos, eos);
if (bmask & 0x200000)
processParens(start, seg, aMirror, level, stack);
if (bmask & 0x7E0361)
resolveNeutrals(start, level, sos, eos);
bmask = 0;
}
enum maxs
{
MAX_LEVEL = 125,
};
// returns where we are up to in processing
Slot *process_bidi(Slot *start, int level, int prelevel, int &nextLevel, int dirover, int isol, int &cisol, int &isolerr, int &embederr, int init, Segment *seg, uint8 aMirror, BracketPairStack &bstack)
{
int bmask = 0;
Slot *s = start;
Slot *slast = start;
Slot *scurr = 0;
Slot *stemp;
int lnextLevel = nextLevel;
int newLevel;
int empty = 1;
for ( ; s; s = s ? s->next() : s)
{
int cls = s->getBidiClass();
bmask |= (1 << cls);
s->setBidiLevel(level);
// we keep s->prev() pointing backwards for PDI repeating
switch (cls)
{
case BN :
if (slast == s) slast = s->next(); // ignore if at front of text
continue;
case LRE :
case LRO :
case RLE :
case RLO :
switch (cls)
{
case LRE :
case LRO :
newLevel = level + (level & 1 ? 1 : 2);
break;
case RLE :
case RLO :
newLevel = level + (level & 1 ? 2 : 1);
break;
}
s->setBidiClass(BN);
if (isolerr || newLevel > MAX_LEVEL || embederr)
{
if (!isolerr) ++embederr;
break;
}
stemp = scurr;
if (scurr)
scurr->prev(0); // don't include control in string
lnextLevel = newLevel;
scurr = s;
s->setBidiLevel(newLevel); // to make it vanish
// recurse for the new subsequence. A sequence only contains text at the same level
s = process_bidi(s->next(), newLevel, level, lnextLevel, cls < LRE, 0, cisol, isolerr, embederr, 0, seg, aMirror, bstack);
// s points at PDF or end of sequence
// try to keep extending the run and not process it until we have to
if (lnextLevel != level || !s) // if the subsequence really had something in it, or we are at the end of the run
{
if (slast != scurr) // process the run now, don't try to extend it
{
// process text preceeding embedding
do_resolves(slast, level, (prelevel > level ? prelevel : level) & 1, lnextLevel & 1, bmask, seg, aMirror, bstack);
empty = 0;
nextLevel = level;
}
else if (lnextLevel != level) // the subsequence had something
{
empty = 0; // so we aren't empty either
nextLevel = lnextLevel; // but since we really are empty, pass back our level from the subsequence
}
if (s) // if still more to process
{
prelevel = lnextLevel; // future text starts out with sos of the higher subsequence
lnextLevel = level; // and eos is our level
}
slast = s ? s->next() : s;
}
else if (stemp)
stemp->prev(s);
break;
case PDF :
s->setBidiClass(BN);
s->prev(0); // unstitch us since we skip final stitching code when we return
if (isol || isolerr || init) // boundary error conditions
break;
if (embederr)
{
--embederr;
break;
}
if (slast != s)
{
scurr->prev(0); // if slast, then scurr. Terminate before here
do_resolves(slast, level, level & 1, level & 1, bmask, seg, aMirror, bstack);
empty = 0;
}
if (empty)
{
nextLevel = prelevel; // no contents? set our level to that of parent
s->setBidiLevel(prelevel);
}
return s;
case FSI :
case LRI :
case RLI :
switch (cls)
{
case FSI :
if (calc_base_level(s->next()))
newLevel = level + (level & 1 ? 2 : 1);
else
newLevel = level + (level & 1 ? 1 : 2);
break;
case LRI :
newLevel = level + (level & 1 ? 1 : 2);
break;
case RLI :
newLevel = level + (level & 1 ? 2 : 1);
break;
}
if (newLevel > MAX_LEVEL || isolerr)
{
++isolerr;
s->setBidiClass(ON | WSflag);
break;
}
++cisol;
if (scurr) scurr->prev(s);
scurr = s; // include FSI
lnextLevel = newLevel;
// recurse for the new sub sequence
s = process_bidi(s->next(), newLevel, newLevel, lnextLevel, 0, 1, cisol, isolerr, embederr, 0, seg, aMirror, bstack);
// s points at PDI
if (s)
{
bmask |= 1 << BaseClass(s); // include the PDI in the mask
s->setBidiLevel(level); // reset its level to our level
}
lnextLevel = level;
break;
case PDI :
if (isolerr)
{
--isolerr;
s->setBidiClass(ON | WSflag);
break;
}
if (init || !cisol)
{
s->setBidiClass(ON | WSflag);
break;
}
embederr = 0;
if (!isol) // we are in an embedded subsequence, we have to return through all those
{
if (empty) // if empty, reset the level to tell embedded parent
nextLevel = prelevel;
return s->prev(); // keep working up the stack pointing at this PDI until we get to an isolate entry
}
else // we are terminating an isolate sequence
{
if (slast != s) // process any remaining content in this subseqence
{
scurr->prev(0);
do_resolves(slast, level, prelevel & 1, level & 1, bmask, seg, aMirror, bstack);
}
--cisol; // pop the isol sequence from the stack
return s;
}
default :
if (dirover)
s->setBidiClass((level & 1 ? R : L) | (WSflag * (cls == WS)));
}
if (s) s->prev(0); // unstitch us
if (scurr) // stitch in text for processing
scurr->prev(s);
scurr = s; // add us to text to process
}
if (slast != s)
{
do_resolves(slast, level, (level > prelevel ? level : prelevel) & 1, lnextLevel & 1, bmask, seg, aMirror, bstack);
empty = 0;
}
if (empty || isol)
nextLevel = prelevel;
return s;
}
// === RESOLVE WEAK TYPES ================================================
enum bidi_state // possible states
{
xa, // arabic letter
xr, // right leter
xl, // left letter
ao, // arabic lett. foll by ON
ro, // right lett. foll by ON
lo, // left lett. foll by ON
rt, // ET following R
lt, // ET following L
cn, // EN, AN following AL
ra, // arabic number foll R
re, // european number foll R
la, // arabic number foll L
le, // european number foll L
ac, // CS following cn
rc, // CS following ra
rs, // CS,ES following re
lc, // CS following la
ls, // CS,ES following le
ret, // ET following re
let, // ET following le
} ;
const bidi_state stateWeak[][10] =
{
// N, L, R, AN, EN, AL,NSM, CS, ES, ET,
{ /*xa*/ ao, xl, xr, cn, cn, xa, xa, ao, ao, ao, /* arabic letter */ },
{ /*xr*/ ro, xl, xr, ra, re, xa, xr, ro, ro, rt, /* right letter */ },
{ /*xl*/ lo, xl, xr, la, le, xa, xl, lo, lo, lt, /* left letter */ },
{ /*ao*/ ao, xl, xr, cn, cn, xa, ao, ao, ao, ao, /* arabic lett. foll by ON*/ },
{ /*ro*/ ro, xl, xr, ra, re, xa, ro, ro, ro, rt, /* right lett. foll by ON */ },
{ /*lo*/ lo, xl, xr, la, le, xa, lo, lo, lo, lt, /* left lett. foll by ON */ },
{ /*rt*/ ro, xl, xr, ra, re, xa, rt, ro, ro, rt, /* ET following R */ },
{ /*lt*/ lo, xl, xr, la, le, xa, lt, lo, lo, lt, /* ET following L */ },
{ /*cn*/ ao, xl, xr, cn, cn, xa, cn, ac, ao, ao, /* EN, AN following AL */ },
{ /*ra*/ ro, xl, xr, ra, re, xa, ra, rc, ro, rt, /* arabic number foll R */ },
{ /*re*/ ro, xl, xr, ra, re, xa, re, rs, rs,ret, /* european number foll R */ },
{ /*la*/ lo, xl, xr, la, le, xa, la, lc, lo, lt, /* arabic number foll L */ },
{ /*le*/ lo, xl, xr, la, le, xa, le, ls, ls,let, /* european number foll L */ },
{ /*ac*/ ao, xl, xr, cn, cn, xa, ao, ao, ao, ao, /* CS following cn */ },
{ /*rc*/ ro, xl, xr, ra, re, xa, ro, ro, ro, rt, /* CS following ra */ },
{ /*rs*/ ro, xl, xr, ra, re, xa, ro, ro, ro, rt, /* CS,ES following re */ },
{ /*lc*/ lo, xl, xr, la, le, xa, lo, lo, lo, lt, /* CS following la */ },
{ /*ls*/ lo, xl, xr, la, le, xa, lo, lo, lo, lt, /* CS,ES following le */ },
{ /*ret*/ ro, xl, xr, ra, re, xa,ret, ro, ro,ret, /* ET following re */ },
{ /*let*/ lo, xl, xr, la, le, xa,let, lo, lo,let, /* ET following le */ },
};
enum bidi_action // possible actions
{
// primitives
IX = 0x100, // increment
XX = 0xF, // no-op
// actions
xxx = (XX << 4) + XX, // no-op
xIx = IX + xxx, // increment run
xxN = (XX << 4) + ON, // set current to N
xxE = (XX << 4) + EN, // set current to EN
xxA = (XX << 4) + AN, // set current to AN
xxR = (XX << 4) + R, // set current to R
xxL = (XX << 4) + L, // set current to L
Nxx = (ON << 4) + 0xF, // set run to neutral
Axx = (AN << 4) + 0xF, // set run to AN
ExE = (EN << 4) + EN, // set run to EN, set current to EN
NIx = (ON << 4) + 0xF + IX, // set run to N, increment
NxN = (ON << 4) + ON, // set run to N, set current to N
NxR = (ON << 4) + R, // set run to N, set current to R
NxE = (ON << 4) + EN, // set run to N, set current to EN
AxA = (AN << 4) + AN, // set run to AN, set current to AN
NxL = (ON << 4) + L, // set run to N, set current to L
LxL = (L << 4) + L, // set run to L, set current to L
};
const bidi_action actionWeak[][10] =
{
// N,.. L, R, AN, EN, AL, NSM, CS,..ES, ET,
{ /*xa*/ xxx, xxx, xxx, xxx, xxA, xxR, xxR, xxN, xxN, xxN, /* arabic letter */ },
{ /*xr*/ xxx, xxx, xxx, xxx, xxE, xxR, xxR, xxN, xxN, xIx, /* right leter */ },
{ /*xl*/ xxx, xxx, xxx, xxx, xxL, xxR, xxL, xxN, xxN, xIx, /* left letter */ },
{ /*ao*/ xxx, xxx, xxx, xxx, xxA, xxR, xxN, xxN, xxN, xxN, /* arabic lett. foll by ON */ },
{ /*ro*/ xxx, xxx, xxx, xxx, xxE, xxR, xxN, xxN, xxN, xIx, /* right lett. foll by ON */ },
{ /*lo*/ xxx, xxx, xxx, xxx, xxL, xxR, xxN, xxN, xxN, xIx, /* left lett. foll by ON */ },
{ /*rt*/ Nxx, Nxx, Nxx, Nxx, ExE, NxR, xIx, NxN, NxN, xIx, /* ET following R */ },
{ /*lt*/ Nxx, Nxx, Nxx, Nxx, LxL, NxR, xIx, NxN, NxN, xIx, /* ET following L */ },
{ /*cn*/ xxx, xxx, xxx, xxx, xxA, xxR, xxA, xIx, xxN, xxN, /* EN, AN following AL */ },
{ /*ra*/ xxx, xxx, xxx, xxx, xxE, xxR, xxA, xIx, xxN, xIx, /* arabic number foll R */ },
{ /*re*/ xxx, xxx, xxx, xxx, xxE, xxR, xxE, xIx, xIx, xxE, /* european number foll R */ },
{ /*la*/ xxx, xxx, xxx, xxx, xxL, xxR, xxA, xIx, xxN, xIx, /* arabic number foll L */ },
{ /*le*/ xxx, xxx, xxx, xxx, xxL, xxR, xxL, xIx, xIx, xxL, /* european number foll L */ },
{ /*ac*/ Nxx, Nxx, Nxx, Axx, AxA, NxR, NxN, NxN, NxN, NxN, /* CS following cn */ },
{ /*rc*/ Nxx, Nxx, Nxx, Axx, NxE, NxR, NxN, NxN, NxN, NIx, /* CS following ra */ },
{ /*rs*/ Nxx, Nxx, Nxx, Nxx, ExE, NxR, NxN, NxN, NxN, NIx, /* CS,ES following re */ },
{ /*lc*/ Nxx, Nxx, Nxx, Axx, NxL, NxR, NxN, NxN, NxN, NIx, /* CS following la */ },
{ /*ls*/ Nxx, Nxx, Nxx, Nxx, LxL, NxR, NxN, NxN, NxN, NIx, /* CS,ES following le */ },
{ /*ret*/xxx, xxx, xxx, xxx, xxE, xxR, xxE, xxN, xxN, xxE, /* ET following re */ },
{ /*let*/xxx, xxx, xxx, xxx, xxL, xxR, xxL, xxN, xxN, xxL, /* ET following le */ },
};
inline uint8 GetDeferredType(bidi_action a) { return (a >> 4) & 0xF; }
inline uint8 GetResolvedType(bidi_action a) { return a & 0xF; }
inline DirCode EmbeddingDirection(int l) { return l & 1 ? R : L; }
// Neutrals
enum neutral_action
{
// action to resolve previous input
nL = L, // resolve EN to L
En = 3 << 4, // resolve neutrals run to embedding level direction
Rn = R << 4, // resolve neutrals run to strong right
Ln = L << 4, // resolved neutrals run to strong left
In = (1<<8), // increment count of deferred neutrals
LnL = (1<<4)+L, // set run and EN to L
};
// ->prev() here means ->next()
void SetDeferredRunClass(Slot *s, Slot *sRun, int nval)
{
if (!sRun || s == sRun) return;
for (Slot *p = sRun; p != s; p = p->prev())
if (p->getBidiClass() == WS) p->setBidiClass(nval | WSflag);
else if (BaseClass(p) != BN) p->setBidiClass(nval | (p->getBidiClass() & WSflag));
}
void SetThisDeferredRunClass(Slot *s, Slot *sRun, int nval)
{
if (!sRun) return;
for (Slot *p = sRun, *e = s->prev(); p != e; p = p->prev())
if (p->getBidiClass() == WS) p->setBidiClass(nval | WSflag);
else if (BaseClass(p) != BN) p->setBidiClass(nval | (p->getBidiClass() & WSflag));
}
void resolveWeak(Slot *start, int sos, int eos)
{
int state = (sos & 1) ? xr : xl;
int cls;
Slot *s = start;
Slot *sRun = NULL;
Slot *sLast = s;
for ( ; s; s = s->prev())
{
sLast = s;
cls = BaseClass(s);
switch (cls)
{
case BN :
if (s == start) start = s->prev(); // skip initial BNs for NSM resolving
continue;
case LRI :
case RLI :
case FSI :
case PDI :
{
Slot *snext = s->prev();
if (snext && snext->getBidiClass() == NSM)
snext->setBidiClass(ON);
s->setBidiClass(ON | WSflag);
}
break;
case NSM :
if (s == start)
{
cls = EmbeddingDirection(sos);
s->setBidiClass(cls);
}
break;
}
bidi_action action = actionWeak[state][bidi_class_map[cls]];
int clsRun = GetDeferredType(action);
if (clsRun != XX)
{
SetDeferredRunClass(s, sRun, clsRun);
sRun = NULL;
}
int clsNew = GetResolvedType(action);
if (clsNew != XX)
s->setBidiClass(clsNew);
if (!sRun && (IX & action))
sRun = s;
state = stateWeak[state][bidi_class_map[cls]];
}
cls = EmbeddingDirection(eos);
int clsRun = GetDeferredType(actionWeak[state][bidi_class_map[cls]]);
if (clsRun != XX)
SetThisDeferredRunClass(sLast, sRun, clsRun);
}
void processParens(Slot *s, Segment *seg, uint8 aMirror, int level, BracketPairStack &stack)
{
uint8 mask = 0;
int8 lastDir = -1;
BracketPair *p;
for ( ; s; s = s->prev()) // walk the sequence
{
uint16 ogid = seg->glyphAttr(s->gid(), aMirror) || s->gid();
int cls = BaseClass(s);
switch(cls)
{
case OPP :
stack.orin(mask);
stack.push(ogid, s, lastDir, lastDir != CPP);
mask = 0;
lastDir = OPP;
break;
case CPP :
stack.orin(mask);
p = stack.scan(s->gid());
if (!p) break;
mask = 0;
stack.close(p, s);
lastDir = CPP;
break;
case L :
lastDir = L;
mask |= 1;
break;
case R :
case AL :
case AN :
case EN :
lastDir = R;
mask |= 2;
}
}
if (stack.size())
{
for (p = stack.start(); p; p =p->next()) // walk the stack
{
if (p->close() && p->mask())
{
int dir = (level & 1) + 1;
if (p->mask() & dir)
{ }
else if (p->mask() & (1 << (~level & 1))) // if inside has strong other embedding
{
int ldir = p->before();
if ((p->before() == OPP || p->before() == CPP) && p->prev())
{
for (BracketPair *q = p->prev(); q; q = q->prev())
{
ldir = q->open()->getBidiClass();
if (ldir < 3) break;
ldir = q->before();
if (ldir < 3) break;
}
if (ldir > 2) ldir = 0;
}
if (ldir > 0 && (ldir - 1) != (level & 1)) // is dir given opp. to level dir (ldir == R or L)
dir = (~level & 1) + 1;
}
p->open()->setBidiClass(dir);
p->close()->setBidiClass(dir);
}
}
stack.clear();
}
}
int GetDeferredNeutrals(int action, int level)
{
action = (action >> 4) & 0xF;
if (action == (En >> 4))
return EmbeddingDirection(level);
else
return action;
}
int GetResolvedNeutrals(int action)
{
return action & 0xF;
}
// state values
enum neutral_state
{
// new temporary class
r, // R and characters resolved to R
l, // L and characters resolved to L
rn, // N preceded by right
ln, // N preceded by left
a, // AN preceded by left (the abbrev 'la' is used up above)
na, // N preceeded by a
} ;
const uint8 neutral_class_map[] = { 0, 1, 2, 0, 4, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
const int actionNeutrals[][5] =
{
// cls= N, L, R, AN, EN, state =
{ In, 0, 0, 0, 0, }, // r right
{ In, 0, 0, 0, L, }, // l left
{ In, En, Rn, Rn, Rn, }, // rn N preceded by right
{ In, Ln, En, En, LnL, }, // ln N preceded by left
{ In, 0, 0, 0, L, }, // a AN preceded by left
{ In, En, Rn, Rn, En, }, // na N preceded by a
} ;
const int stateNeutrals[][5] =
{
// cls= N, L, R, AN, EN state =
{ rn, l, r, r, r, }, // r right
{ ln, l, r, a, l, }, // l left
{ rn, l, r, r, r, }, // rn N preceded by right
{ ln, l, r, a, l, }, // ln N preceded by left
{ na, l, r, a, l, }, // a AN preceded by left
{ na, l, r, a, l, }, // na N preceded by la
} ;
void resolveNeutrals(Slot *s, int baseLevel, int sos, int eos)
{
int state = (sos & 1) ? r : l;
int cls;
Slot *sRun = NULL;
Slot *sLast = s;
int level = baseLevel;
for ( ; s; s = s->prev())
{
sLast = s;
cls = BaseClass(s);
switch (cls)
{
case BN :
continue;
case LRI :
case RLI :
case FSI :
s->setBidiClass(BN | WSflag);
continue;
default :
int action = actionNeutrals[state][neutral_class_map[cls]];
int clsRun = GetDeferredNeutrals(action, level);
if (clsRun != N)
{
SetDeferredRunClass(s, sRun, clsRun);
sRun = NULL;
}
int clsNew = GetResolvedNeutrals(action);
if (clsNew != N)
s->setBidiClass(clsNew);
if (!sRun && (action & In))
sRun = s;
state = stateNeutrals[state][neutral_class_map[cls]];
}
}
cls = EmbeddingDirection(eos);
int clsRun = GetDeferredNeutrals(actionNeutrals[state][neutral_class_map[cls]], level);
if (clsRun != N)
SetThisDeferredRunClass(sLast, sRun, clsRun);
}
const int addLevel[][4] =
{
// cls = L, R, AN, EN level =
/* even */ { 0, 1, 2, 2, }, // EVEN
/* odd */ { 1, 0, 1, 1, }, // ODD
};
void resolveImplicit(Slot *s, Segment *seg, uint8 aMirror)
{
bool rtl = seg->dir() & 1;
int level = rtl;
Slot *slast = 0;
for ( ; s; s = s->next())
{
int cls = BaseClass(s);
s->prev(slast); // restitch the prev() side of the doubly linked list
slast = s;
if (cls == AN)
cls = AL; // use AL value as the index for AN, no property change
if (cls < 5 && cls > 0)
{
level = s->getBidiLevel();
level += addLevel[level & 1][cls - 1];
s->setBidiLevel(level);
}
if (aMirror)
{
int hasChar = seg->glyphAttr(s->gid(), aMirror + 1);
if ( ((level & 1) && (!(seg->dir() & 4) || !hasChar))
|| ((rtl ^ (level & 1)) && (seg->dir() & 4) && hasChar) )
{
unsigned short g = seg->glyphAttr(s->gid(), aMirror);
if (g) s->setGlyph(seg, g);
}
}
}
}
void resolveWhitespace(int baseLevel, Slot *s)
{
for ( ; s; s = s->prev())
{
int8 cls = s->getBidiClass();
if (cls == WS || (cls & WSflag))
s->setBidiLevel(baseLevel);
else if (cls != BN)
break;
}
}
/*
Stitch two spans together to make another span (with ends tied together).
If the level is odd then swap the order of the two spans
*/
inline
Slot * join(int level, Slot * a, Slot * b)
{
if (!a) return b;
if (level & 1) { Slot * const t = a; a = b; b = t; }
Slot * const t = b->prev();
a->prev()->next(b); b->prev(a->prev()); // splice middle
t->next(a); a->prev(t); // splice ends
return a;
}
/*
Given the first slot in a run of slots with the same bidi level, turn the run
into it's own little doubly linked list ring (a span) with the two ends joined together.
If the run is rtl then reverse its direction.
Returns the first slot after the span
*/
Slot * span(Slot * & cs, const bool rtl)
{
Slot * r = cs, * re = cs; cs = cs->next();
if (rtl)
{
Slot * t = r->next(); r->next(r->prev()); r->prev(t);
for (int l = r->getBidiLevel(); cs && (l == cs->getBidiLevel() || cs->getBidiClass() == BN); cs = cs->prev())
{
re = cs;
t = cs->next(); cs->next(cs->prev()); cs->prev(t);
}
r->next(re);
re->prev(r);
r = re;
}
else
{
for (int l = r->getBidiLevel(); cs && (l == cs->getBidiLevel() || cs->getBidiClass() == BN); cs = cs->next())
re = cs;
r->prev(re);
re->next(r);
}
if (cs) cs->prev(0);
return r;
}
inline int getlevel(const Slot *cs, const int level)
{
while (cs && cs->getBidiClass() == BN)
{ cs = cs->next(); }
if (cs)
return cs->getBidiLevel();
else
return level;
}
Slot *resolveOrder(Slot * & cs, const bool reordered, const int level)
{
Slot * r = 0;
int ls;
while (cs && level <= (ls = getlevel(cs, level) - reordered))
{
r = join(level, r, level < ls
? resolveOrder(/* updates */cs, reordered, level+1) // find span of heighest level
: span(/* updates */cs, level & 1));
}
return r;
}
-149
View File
@@ -1,149 +0,0 @@
/* GRAPHITE2 LICENSING
Copyright 2010, 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.
*/
#include "inc/GlyphFaceCache.h"
#include "graphite2/Font.h"
#include "inc/Face.h" //for the tags
#include "inc/Endian.h"
using namespace graphite2;
/*virtual*/ bool GlyphFaceCacheHeader::initialize(const Face & face, const bool dumb_font) //return result indicates success. Do not use if failed.
{
if ((m_pLoca = face.getTable(Tag::loca, &m_lLoca)) == NULL) return false;
if ((m_pHead = face.getTable(Tag::head)) == NULL) return false;
if ((m_pGlyf = face.getTable(Tag::glyf, &m_lGlyf)) == NULL) return false;
if ((m_pHmtx = face.getTable(Tag::hmtx, &m_lHmtx)) == NULL) return false;
if ((m_pHHea = face.getTable(Tag::hhea)) == NULL) return false;
const void* pMaxp = face.getTable(Tag::maxp);
if (pMaxp == NULL) return false;
m_nGlyphs = m_nGlyphsWithGraphics = (unsigned short)TtfUtil::GlyphCount(pMaxp);
if (TtfUtil::LocaLookup(m_nGlyphs-1, m_pLoca, m_lLoca, m_pHead) == size_t(-1))
return false; // This will fail if m_nGlyphs is wildly out of range.
if (!dumb_font)
{
if ((m_pGlat = face.getTable(Tag::Glat, &m_lGlat)) == NULL) return false;
m_fGlat = be::peek<uint32>(m_pGlat);
size_t lGloc;
if ((m_pGloc = face.getTable(Tag::Gloc, &lGloc)) == NULL) return false;
if (lGloc < 6) return false;
int version = be::read<uint32>(m_pGloc);
if (version != 0x00010000) return false;
const uint16 locFlags = be::read<uint16>(m_pGloc);
m_numAttrs = be::read<uint16>(m_pGloc);
if (m_numAttrs > 0x1000) return false; // is this hard limit appropriate?
if (locFlags & 1)
{
m_locFlagsUse32Bit = true;
m_nGlyphsWithAttributes = (unsigned short)((lGloc - 12) / 4);
}
else
{
m_locFlagsUse32Bit = false;
m_nGlyphsWithAttributes = (unsigned short)((lGloc - 10) / 2);
}
if (m_nGlyphsWithAttributes > m_nGlyphs)
m_nGlyphs = m_nGlyphsWithAttributes;
}
return true;
}
GlyphFaceCache* GlyphFaceCache::makeCache(const GlyphFaceCacheHeader& hdr)
{
return new (hdr) GlyphFaceCache(hdr);
}
GlyphFaceCache::GlyphFaceCache(const GlyphFaceCacheHeader& hdr)
: GlyphFaceCacheHeader(hdr)
{
unsigned int nGlyphs = numGlyphs();
for (unsigned int i = 0; i < nGlyphs; i++)
{
*glyphPtrDirect(i) = NULL;
}
}
GlyphFaceCache::~GlyphFaceCache()
{
unsigned int nGlyphs = numGlyphs();
int deltaPointers = (*glyphPtrDirect(nGlyphs-1u) - *glyphPtrDirect(0u));
if ((nGlyphs > 0u) && (deltaPointers == static_cast<int>(nGlyphs - 1)))
{
for (unsigned int i=0 ; i<nGlyphs; ++i)
{
GlyphFace *p = *glyphPtrDirect(i);
assert (p);
p->~GlyphFace();
}
free (*glyphPtrDirect(0));
}
else
{
for (unsigned int i=0 ; i<nGlyphs; ++i)
{
GlyphFace *p = *glyphPtrDirect(i);
if (p)
{
p->~GlyphFace();
free(p);
}
}
}
}
void GlyphFaceCache::loadAllGlyphs()
{
unsigned int nGlyphs = numGlyphs();
// size_t sparse_size = 0;
GlyphFace * glyphs = gralloc<GlyphFace>(nGlyphs);
for (unsigned short glyphid = 0; glyphid < nGlyphs; glyphid++)
{
GlyphFace **p = glyphPtrDirect(glyphid);
*p = &(glyphs[glyphid]);
new(*p) GlyphFace(*this, glyphid);
// sparse_size += (*p)->m_attrs._sizeof();
}
// const size_t flat_size = nGlyphs*(sizeof(uint16*) + sizeof(uint16)*numAttrs());
// assert(sparse_size <= flat_size);
}
/*virtual*/ const GlyphFace *GlyphFaceCache::glyph(unsigned short glyphid) const //result may be changed by subsequent call with a different glyphid
{
GlyphFace **p = glyphPtrDirect(glyphid);
if (*p)
return *p;
*p = (GlyphFace*)malloc(sizeof(GlyphFace));
new(*p) GlyphFace(*this, glyphid);
return *p;
}
-31
View File
@@ -1,31 +0,0 @@
/* GRAPHITE2 LICENSING
Copyright 2011, 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.
*/
#include "inc/Rule.h"
#include "inc/Segment.h"
using namespace graphite2;
-219
View File
@@ -1,219 +0,0 @@
/* GRAPHITE2 LICENSING
Copyright 2010, 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.
*/
#include <cstring>
#include <cstdarg>
#include "Main.h"
#include "XmlTraceLog.h"
using namespace graphite2;
#ifndef DISABLE_TRACING
/*static*/ XmlTraceLog XmlTraceLog::sm_NullLog(NULL, NULL, GRLOG_NONE);
XmlTraceLog * XmlTraceLog::sLog = &sm_NullLog;
XmlTraceLog::XmlTraceLog(FILE * file, const char * ns, GrLogMask logMask)
: m_file(file), m_depth(0), m_mask(logMask)
{
if (!m_file) return;
int deep = 0;
#ifdef ENABLE_DEEP_TRACING
deep = 1;
#endif
fprintf(m_file, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<%s xmlns=\"%s\" mask=\"%x\" deep=\"%d\">",
xmlTraceLogElements[ElementTopLevel].mName, ns, logMask, deep);
m_elementStack[m_depth++] = ElementTopLevel;
m_elementEmpty = true;
m_inElement = false;
m_lastNodeText = false;
}
XmlTraceLog::~XmlTraceLog()
{
if (m_file && m_file != stdout && m_file != stderr)
{
assert(m_depth == 1);
while (m_depth > 0)
{
closeElement(m_elementStack[m_depth-1]);
}
fclose(m_file);
m_file = NULL;
}
}
void XmlTraceLog::addSingleElement(XmlTraceLogElement eId, const int value)
{
if (!m_file) return;
if (m_inElement)
{
if (xmlTraceLogElements[m_elementStack[m_depth-1]].mFlags & m_mask)
fprintf(m_file, ">");
}
if (xmlTraceLogElements[eId].mFlags & m_mask)
{
if (!m_lastNodeText)
{
fprintf(m_file, "\n");
for (size_t i = 0; i < m_depth; i++)
{
fprintf(m_file, " ");
}
}
fprintf(m_file, "<%s val=\"%d\"/>", xmlTraceLogElements[eId].mName, value);
}
m_inElement = false;
m_lastNodeText = false;
}
void XmlTraceLog::writeElementArray(XmlTraceLogElement eId, XmlTraceLogAttribute aId, int16 values [], size_t length)
{
if (!m_file) return;
if (xmlTraceLogElements[eId].mFlags & m_mask)
{
if(m_inElement && xmlTraceLogElements[m_elementStack[m_depth-1]].mFlags & m_mask)
{
fprintf(m_file, ">");
m_inElement = false;
}
// line break after 5 columns
for (size_t i = 0; i < length; i++)
{
if (i % 5 == 0)
{
fprintf(m_file, "\n");
for (size_t j = 0; j < m_depth; j++)
{
fprintf(m_file, " ");
}
}
fprintf(m_file, "<%s index=\"%d\" %s=\"%d\"/>", xmlTraceLogElements[eId].mName, int(i),
xmlTraceLogAttributes[aId], (int)values[i]);
}
}
}
void XmlTraceLog::writeText(const char * utf8)
{
if (!m_file) return;
if (m_inElement)
{
if (xmlTraceLogElements[m_elementStack[m_depth-1]].mFlags & m_mask)
{
fprintf(m_file, ">");
}
m_inElement = false;
}
if (xmlTraceLogElements[m_elementStack[m_depth-1]].mFlags & m_mask)
{
escapeIfNeeded(utf8);
}
m_lastNodeText = true;
}
void XmlTraceLog::writeUnicode(const uint32 code)
{
if (!m_file) return;
if (m_inElement)
{
if (xmlTraceLogElements[m_elementStack[m_depth-1]].mFlags & m_mask)
{
fprintf(m_file, ">");
}
m_inElement = false;
}
if (xmlTraceLogElements[m_elementStack[m_depth-1]].mFlags & m_mask)
{
fprintf(m_file, "&#x%02x;", code);
}
m_lastNodeText = true;
}
void XmlTraceLog::escapeIfNeeded(const char * data)
{
size_t length = strlen(data);
for (size_t i = 0; i < length; i++)
{
switch (data[i])
{
case '<':
fprintf(m_file, "&lt;");
break;
case '>':
fprintf(m_file, "&gt;");
break;
case '&':
fprintf(m_file, "&amp;");
break;
case '"':
fprintf(m_file, "&#34;");
break;
default:
fprintf(m_file, "%c", data[i]);
}
}
}
static const int MAX_MSG_LEN = 1024;
void XmlTraceLog::error(const char * msg, ...)
{
if (!m_file) return;
openElement(ElementError);
va_list args;
va_start(args, msg);
char buffer[MAX_MSG_LEN];
#ifndef NDEBUG
int len =
#endif
vsnprintf(buffer, MAX_MSG_LEN, msg, args);
assert(len + 1 < MAX_MSG_LEN);
writeText(buffer);
va_end(args);
closeElement(ElementError);
}
void XmlTraceLog::warning(const char * msg, ...)
{
if (!m_file) return;
openElement(ElementWarning);
va_list args;
va_start(args, msg);
char buffer[MAX_MSG_LEN];
#ifndef NDEBUG
int len =
#endif
vsnprintf(buffer, MAX_MSG_LEN, msg, args);
assert(len + 1 < MAX_MSG_LEN);
writeText(buffer);
va_end(args);
closeElement(ElementWarning);
}
#endif //!DISABLE_TRACING
-169
View File
@@ -1,169 +0,0 @@
/* GRAPHITE2 LICENSING
Copyright 2010, 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.
*/
#include "Main.h"
#include "XmlTraceLogTags.h"
using namespace graphite2;
#ifndef DISABLE_TRACING
// start this at same line number as in XmlTraceLogTags.h
const XmlTraceLogTag graphite2::xmlTraceLogElements[NumElements] = {
XmlTraceLogTag("Graphite2Log", GRLOG_ALL),
XmlTraceLogTag("Face", GRLOG_FACE | GRLOG_PASS),
XmlTraceLogTag("Glyphs", GRLOG_FACE),
XmlTraceLogTag("GlyphFace", GRLOG_FACE),
XmlTraceLogTag("Attr", GRLOG_FACE),
XmlTraceLogTag("Silf", GRLOG_FACE | GRLOG_PASS),
XmlTraceLogTag("SilfSub", GRLOG_FACE | GRLOG_PASS),
XmlTraceLogTag("Pass", GRLOG_FACE | GRLOG_PASS),
XmlTraceLogTag("Pseudo", GRLOG_FACE | GRLOG_PASS),
XmlTraceLogTag("ClassMap", GRLOG_FACE | GRLOG_PASS),
XmlTraceLogTag("LookupClass", GRLOG_FACE | GRLOG_PASS),
XmlTraceLogTag("Lookup", GRLOG_FACE | GRLOG_PASS),
XmlTraceLogTag("Range", GRLOG_PASS),
XmlTraceLogTag("RuleMap", GRLOG_PASS),
XmlTraceLogTag("Rule", GRLOG_PASS),
XmlTraceLogTag("StartState", GRLOG_PASS),
XmlTraceLogTag("StateTransitions", GRLOG_PASS),
XmlTraceLogTag("TR", GRLOG_PASS),
XmlTraceLogTag("TD", GRLOG_PASS),
XmlTraceLogTag("Constraint", GRLOG_PASS),
XmlTraceLogTag("Constraints", GRLOG_PASS),
XmlTraceLogTag("Actions", GRLOG_PASS),
XmlTraceLogTag("Action", GRLOG_PASS),
XmlTraceLogTag("Features", GRLOG_PASS),
XmlTraceLogTag("Feature", GRLOG_PASS),
XmlTraceLogTag("FeatureSetting", GRLOG_PASS),
XmlTraceLogTag("Segment", GRLOG_SEGMENT),
XmlTraceLogTag("Slot", GRLOG_SEGMENT),
XmlTraceLogTag("Text", GRLOG_SEGMENT),
XmlTraceLogTag("OpCode", GRLOG_OPCODE),
XmlTraceLogTag("TestRule", GRLOG_OPCODE),
XmlTraceLogTag("DoRule", GRLOG_OPCODE),
XmlTraceLogTag("RunPass", GRLOG_OPCODE),
XmlTraceLogTag("Params", GRLOG_OPCODE),
XmlTraceLogTag("Push", GRLOG_OPCODE),
XmlTraceLogTag("SubSeg", GRLOG_SEGMENT),
XmlTraceLogTag("SegCache", GRLOG_CACHE),
XmlTraceLogTag("SegCacheEntry", GRLOG_CACHE),
XmlTraceLogTag("Glyph", GRLOG_CACHE),
XmlTraceLogTag("PassResult", GRLOG_OPCODE),
XmlTraceLogTag("Error", GRLOG_ALL),
XmlTraceLogTag("Warning", GRLOG_ALL)
// Nothing corresponds to NumElements
};
// start this at same line number as in XmlTraceLogTags.h
const char * graphite2::xmlTraceLogAttributes[NumAttributes] = {
"index",
"version",
"major",
"minor",
"num",
"glyphId",
"advance",
"advanceX",
"advanceY",
"attrId",
"attrVal",
"compilerMajor",
"compilerMinor",
"numPasses",//AttrNumPasses,
"subPass",//AttrSubPass,
"posPass",//AttrPosPass,
"justPass",//AttrJustPass,
"bidiPass",//AttrBidiPass,
"preContext",//AttrPreContext,
"postContext",//AttrPostContext,
"pseudoGlyph",//AttrPseudoGlyph,
"breakWeight",//AttrBreakWeight,
"directionality",//AttrDirectionality,
"numJustLevels",//AttrNumJustLevels,
"numLigCompAttr",//AttrLigComp,
"numUserDefinedAttr",//AttrUserDefn,
"maxNumLigComp",//AttrNumLigComp,
"numCriticalFeatures",//AttrNumCritFeatures,
"numScripts",//AttrNumScripts
"lineBreakglyph",//,AttrLBGlyph,
"numPseudo",
"numClasses",
"numLinear",
"passId",//AttrPassId,
"flags",//AttrFlags,
"maxRuleLoop",//AttrMaxRuleLoop,
"maxRuleContext",//AttrMaxRuleContext,
"maxBackup",//AttrMaxBackup,
"numRules",//AttrNumRules,
"numRows",//AttrNumRows,
"numTransitionStates",//AttrNumTransition,
"numSuccessStates",//AttrNumSuccess,
"numColumns",//AttrNumColumns,
"numRanges",//AttrNumRanges,
"minPrecontext",//AttrMinPrecontext,
"maxPrecontext",//AttrMaxPrecontext,
"firstId",
"lastId",
"colId",
"successId",
"ruleId",
"contextLength",
"state",
"value",
"sortKey",
"precontext",
"action",
"actionCode",
"arg1",
"arg2",
"arg3",
"arg4",
"arg5",
"arg6",
"arg7",
"arg8",
"label",
"length",
"x",
"y",
"before",
"after",
"encoding",
"name",
"result",
"default",
"accessCount",
"lastAccess",
"misses"
};
#endif
-126
View File
@@ -1,126 +0,0 @@
/* 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);
}
}
-103
View File
@@ -1,103 +0,0 @@
/* GRAPHITE2 LICENSING
Copyright 2010, 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
#include "inc/GlyphFace.h"
#include "graphite2/Font.h"
namespace graphite2 {
class Segment;
class Face;
class FeatureVal;
class GlyphFaceCacheHeader
{
public:
bool initialize(const Face & face, const bool dumb_font); //return result indicates success. Do not use if failed.
unsigned short numGlyphs() const { return m_nGlyphs; }
unsigned short numAttrs() const { return m_numAttrs; }
private:
friend class Face;
friend class GlyphFace;
const byte* m_pHead,
* m_pHHea,
* m_pHmtx,
* m_pGlat,
* m_pGloc,
* m_pGlyf,
* m_pLoca;
size_t m_lHmtx,
m_lGlat,
m_lGlyf,
m_lLoca;
uint32 m_fGlat;
unsigned short m_numAttrs, // number of glyph attributes per glyph
m_nGlyphsWithGraphics, //i.e. boundary box and advance
m_nGlyphsWithAttributes,
m_nGlyphs; // number of glyphs in the font. Max of the above 2.
bool m_locFlagsUse32Bit;
};
class GlyphFaceCache : public GlyphFaceCacheHeader
{
public:
static GlyphFaceCache* makeCache(const GlyphFaceCacheHeader& hdr /*, EGlyphCacheStrategy requested */);
GlyphFaceCache(const GlyphFaceCacheHeader& hdr);
~GlyphFaceCache();
const GlyphFace *glyphSafe(unsigned short glyphid) const { return glyphid<numGlyphs()?glyph(glyphid):NULL; }
uint16 glyphAttr(uint16 gid, uint8 gattr) const { if (gattr>=numAttrs()) return 0; const GlyphFace*p=glyphSafe(gid); return p?p->getAttr(gattr):0; }
void * operator new (size_t s, const GlyphFaceCacheHeader& hdr)
{
return malloc(s + sizeof(GlyphFace*)*hdr.numGlyphs());
}
// delete in case an exception is thrown in constructor
void operator delete(void* p, const GlyphFaceCacheHeader& ) throw()
{
free(p);
}
const GlyphFace *glyph(unsigned short glyphid) const; //result may be changed by subsequent call with a different glyphid
void loadAllGlyphs();
CLASS_NEW_DELETE
private:
GlyphFace **glyphPtrDirect(unsigned short glyphid) const { return (GlyphFace **)((const char*)(this)+sizeof(GlyphFaceCache)+sizeof(GlyphFace*)*glyphid);}
private: //defensive
GlyphFaceCache(const GlyphFaceCache&);
GlyphFaceCache& operator=(const GlyphFaceCache&);
};
} // namespace graphite2
-119
View File
@@ -1,119 +0,0 @@
/* Copyright (c) 2012, Siyuan Fu <fusiyuan2010@gmail.com>
Copyright (c) 2015, SIL International
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
#pragma once
#include <cassert>
#include <cstddef>
#include <cstring>
#include <iterator>
//the code from LZ4
#if (GCC_VERSION >= 302) || (__INTEL_COMPILER >= 800) || defined(__clang__)
# define expect(expr,value) (__builtin_expect ((expr),(value)) )
#else
# define expect(expr,value) (expr)
#endif
#define likely(expr) expect((expr) != 0, 1)
#define unlikely(expr) expect((expr) != 0, 0)
////////////////////
namespace
{
#if defined(_MSC_VER)
typedef unsigned __int8 u8;
typedef unsigned __int16 u16;
typedef unsigned __int32 u32;
typedef unsigned __int64 u64;
#else
#include <stdint.h>
typedef uint8_t u8;
typedef uint16_t u16;
typedef uint32_t u32;
typedef uint64_t u64;
#endif
ptrdiff_t const MINMATCH = 4;
template<int S>
inline
void unaligned_copy(void * d, void const * s) {
::memcpy(d, s, S);
}
inline
u8 * memcpy_nooverlap(u8 * d, u8 const * s, size_t n) {
size_t const WS = sizeof(unsigned long);
u8 const * e = s + n;
do
{
unaligned_copy<WS>(d, s);
d += WS;
s += WS;
}
while (s < e);
d-=(s-e);
return d;
}
inline
u8 * memcpy_nooverlap_surpass(u8 * d, u8 const * s, size_t n) {
size_t const WS = sizeof(unsigned long);
size_t wn = n/WS;
while (wn--)
{
unaligned_copy<WS>(d, s);
d += WS;
s += WS;
}
n &= WS-1;
while (n--) {*d++ = *s++; }
return d;
}
inline
u8 * memcpy_(u8 * d, u8 const * s, size_t n) {
if (likely(d>s+sizeof(unsigned long)))
return memcpy_nooverlap(d,s,n);
else while (n--) *d++ = *s++;
return d;
}
} // end of anonymous namespace
+1 -2
View File
@@ -1,4 +1,4 @@
# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
# vim: set filetype=python:
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
@@ -23,7 +23,6 @@ else:
# This should contain all of the _SOURCES from files.mk, except *_machine.cpp
UNIFIED_SOURCES += [
'Bidi.cpp',
'CachedFace.cpp',
'CmapCache.cpp',
'Code.cpp',