sl@0
|
1 |
/*
|
sl@0
|
2 |
*
|
sl@0
|
3 |
* (C) Copyright IBM Corp. 1998-2004 - All Rights Reserved
|
sl@0
|
4 |
*
|
sl@0
|
5 |
*/
|
sl@0
|
6 |
|
sl@0
|
7 |
#include "LETypes.h"
|
sl@0
|
8 |
#include "LEGlyphFilter.h"
|
sl@0
|
9 |
#include "OpenTypeTables.h"
|
sl@0
|
10 |
#include "GlyphSubstitutionTables.h"
|
sl@0
|
11 |
#include "MultipleSubstSubtables.h"
|
sl@0
|
12 |
#include "GlyphIterator.h"
|
sl@0
|
13 |
#include "LESwaps.h"
|
sl@0
|
14 |
|
sl@0
|
15 |
U_NAMESPACE_BEGIN
|
sl@0
|
16 |
|
sl@0
|
17 |
le_uint32 MultipleSubstitutionSubtable::process(GlyphIterator *glyphIterator, LEErrorCode& success,
|
sl@0
|
18 |
const LEGlyphFilter *filter) const
|
sl@0
|
19 |
{
|
sl@0
|
20 |
if (LE_FAILURE(success)) {
|
sl@0
|
21 |
return 0;
|
sl@0
|
22 |
}
|
sl@0
|
23 |
|
sl@0
|
24 |
LEGlyphID glyph = glyphIterator->getCurrGlyphID();
|
sl@0
|
25 |
|
sl@0
|
26 |
// If there's a filter, we only want to do the
|
sl@0
|
27 |
// substitution if the *input* glyphs doesn't
|
sl@0
|
28 |
// exist.
|
sl@0
|
29 |
//
|
sl@0
|
30 |
// FIXME: is this always the right thing to do?
|
sl@0
|
31 |
// FIXME: should this only be done for a non-zero
|
sl@0
|
32 |
// glyphCount?
|
sl@0
|
33 |
if (filter != NULL && filter->accept(glyph)) {
|
sl@0
|
34 |
return 0;
|
sl@0
|
35 |
}
|
sl@0
|
36 |
|
sl@0
|
37 |
le_int32 coverageIndex = getGlyphCoverage(glyph);
|
sl@0
|
38 |
le_uint16 seqCount = SWAPW(sequenceCount);
|
sl@0
|
39 |
|
sl@0
|
40 |
if (coverageIndex >= 0 && coverageIndex < seqCount) {
|
sl@0
|
41 |
Offset sequenceTableOffset = SWAPW(sequenceTableOffsetArray[coverageIndex]);
|
sl@0
|
42 |
const SequenceTable *sequenceTable = (const SequenceTable *) ((char *) this + sequenceTableOffset);
|
sl@0
|
43 |
le_uint16 glyphCount = SWAPW(sequenceTable->glyphCount);
|
sl@0
|
44 |
|
sl@0
|
45 |
if (glyphCount == 0) {
|
sl@0
|
46 |
glyphIterator->setCurrGlyphID(0xFFFF);
|
sl@0
|
47 |
return 1;
|
sl@0
|
48 |
} else if (glyphCount == 1) {
|
sl@0
|
49 |
TTGlyphID substitute = SWAPW(sequenceTable->substituteArray[0]);
|
sl@0
|
50 |
|
sl@0
|
51 |
if (filter != NULL && ! filter->accept(LE_SET_GLYPH(glyph, substitute))) {
|
sl@0
|
52 |
return 0;
|
sl@0
|
53 |
}
|
sl@0
|
54 |
|
sl@0
|
55 |
glyphIterator->setCurrGlyphID(substitute);
|
sl@0
|
56 |
return 1;
|
sl@0
|
57 |
} else {
|
sl@0
|
58 |
// If there's a filter, make sure all of the output glyphs
|
sl@0
|
59 |
// exist.
|
sl@0
|
60 |
if (filter != NULL) {
|
sl@0
|
61 |
for (le_int32 i = 0; i < glyphCount; i += 1) {
|
sl@0
|
62 |
TTGlyphID substitute = SWAPW(sequenceTable->substituteArray[i]);
|
sl@0
|
63 |
|
sl@0
|
64 |
if (! filter->accept(substitute)) {
|
sl@0
|
65 |
return 0;
|
sl@0
|
66 |
}
|
sl@0
|
67 |
}
|
sl@0
|
68 |
}
|
sl@0
|
69 |
|
sl@0
|
70 |
LEGlyphID *newGlyphs = glyphIterator->insertGlyphs(glyphCount, success);
|
sl@0
|
71 |
if (LE_FAILURE(success)) {
|
sl@0
|
72 |
return 0;
|
sl@0
|
73 |
}
|
sl@0
|
74 |
|
sl@0
|
75 |
le_int32 insert = 0, direction = 1;
|
sl@0
|
76 |
|
sl@0
|
77 |
if (glyphIterator->isRightToLeft()) {
|
sl@0
|
78 |
insert = glyphCount - 1;
|
sl@0
|
79 |
direction = -1;
|
sl@0
|
80 |
}
|
sl@0
|
81 |
|
sl@0
|
82 |
for (le_int32 i = 0; i < glyphCount; i += 1) {
|
sl@0
|
83 |
TTGlyphID substitute = SWAPW(sequenceTable->substituteArray[i]);
|
sl@0
|
84 |
|
sl@0
|
85 |
newGlyphs[insert] = LE_SET_GLYPH(glyph, substitute);
|
sl@0
|
86 |
insert += direction;
|
sl@0
|
87 |
}
|
sl@0
|
88 |
|
sl@0
|
89 |
return 1;
|
sl@0
|
90 |
}
|
sl@0
|
91 |
}
|
sl@0
|
92 |
|
sl@0
|
93 |
return 0;
|
sl@0
|
94 |
}
|
sl@0
|
95 |
|
sl@0
|
96 |
U_NAMESPACE_END
|