1ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/*
2ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *
3ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * (C) Copyright IBM Corp. 1998-2005 - All Rights Reserved
4ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *
5ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */
6ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
7ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "LETypes.h"
8ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "LEGlyphStorage.h"
9ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "CanonShaping.h"
10ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "GlyphDefinitionTables.h"
11ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "ClassDefinitionTables.h"
12ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
13ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_NAMESPACE_BEGIN
14ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
15ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid CanonShaping::sortMarks(le_int32 *indices, const le_int32 *combiningClasses, le_int32 index, le_int32 limit)
16ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
17ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    for (le_int32 j = index + 1; j < limit; j += 1) {
18ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        le_int32 i;
19ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        le_int32 v = indices[j];
20ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        le_int32 c = combiningClasses[v];
21ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
22ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        for (i = j - 1; i >= index; i -= 1) {
23ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if (c >= combiningClasses[indices[i]]) {
24ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                break;
25ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
26ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
27ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            indices[i + 1] = indices[i];
28ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
29ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
30ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        indices[i + 1] = v;
31ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
32ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
33ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
34ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid CanonShaping::reorderMarks(const LEUnicode *inChars, le_int32 charCount, le_bool rightToLeft,
35ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                                LEUnicode *outChars, LEGlyphStorage &glyphStorage)
36ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
37ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    const GlyphDefinitionTableHeader *gdefTable = (const GlyphDefinitionTableHeader *) glyphDefinitionTable;
38ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    const ClassDefinitionTable *classTable = gdefTable->getMarkAttachClassDefinitionTable();
39ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    le_int32 *combiningClasses = LE_NEW_ARRAY(le_int32, charCount);
40ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    le_int32 *indices = LE_NEW_ARRAY(le_int32, charCount);
41ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    LEErrorCode status = LE_NO_ERROR;
42ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    le_int32 i;
43ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
44ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    for (i = 0; i < charCount; i += 1) {
45ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        combiningClasses[i] = classTable->getGlyphClass((LEGlyphID) inChars[i]);
46ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        indices[i] = i;
47ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
48ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
49ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    for (i = 0; i < charCount; i += 1) {
50ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if (combiningClasses[i] != 0) {
51ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            le_int32 mark;
52ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
53ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            for (mark = i; mark < charCount; mark += 1) {
54ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                if (combiningClasses[mark] == 0) {
55ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    break;
56ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                }
57ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
58ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
59ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            sortMarks(indices, combiningClasses, i, mark);
60ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
61ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
62ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
63ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    le_int32 out = 0, dir = 1;
64ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
65ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (rightToLeft) {
66ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        out = charCount - 1;
67ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        dir = -1;
68ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
69ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
70ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    for (i = 0; i < charCount; i += 1, out += dir) {
71ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        le_int32 index = indices[i];
72ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
73ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        outChars[i] = inChars[index];
74ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        glyphStorage.setCharIndex(out, index, status);
75ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
76ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
77ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    LE_DELETE_ARRAY(indices);
78ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    LE_DELETE_ARRAY(combiningClasses);
79ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
80ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
81ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_NAMESPACE_END
82