12d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert// © 2016 and later: Unicode, Inc. and others.
22d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert// License & terms of use: http://www.unicode.org/copyright.html#License
3bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert/*
4bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert *******************************************************************************
5bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert * Copyright (C) 1998-2010, International Business Machines Corporation and    *
6bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert * others. All Rights Reserved.                                                *
7bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert *******************************************************************************
8bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert */
9bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubertpackage com.ibm.icu.dev.tool.layout;
10bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert
11bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubertimport java.util.Vector;
12bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert
13bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubertimport com.ibm.icu.impl.Utility;
14bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert
15bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubertpublic class ScriptRunModuleWriter extends ScriptModuleWriter
16bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert{
17bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert    public ScriptRunModuleWriter(ScriptData theScriptData)
18bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert    {
19bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        super(theScriptData, null);
20bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert    }
21bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert
22bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert    public void writeScriptRuns(String fileName)
23bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert    {
24bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        int minScript   = scriptData.getMinValue();
25bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        int maxScript   = scriptData.getMaxValue();
26bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        int recordCount = scriptData.getRecordCount();
27bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert
28bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        openFile(fileName);
29bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        writeHeader(null, includeFiles);
30bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        output.println(preamble);
31bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert
32bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        for (int record = 0; record < recordCount; record += 1) {
33bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            int script = scriptData.getRecord(record).scriptCode();
34bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert
35bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            output.print("    {0x");
36bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            output.print(Utility.hex(scriptData.getRecord(record).startChar(), 6));
37bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            output.print(", 0x");
38bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            output.print(Utility.hex(scriptData.getRecord(record).endChar(), 6));
39bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            output.print(", ");
40bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            output.print(scriptData.getTag(script));
41bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            output.print("ScriptCode}");
42bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            output.print((record == recordCount - 1) ? " " : ",");
43bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            output.print(" // ");
44bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            output.println(scriptData.getName(script));
45bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        }
46bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert
47bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        output.println(postamble);
48bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert
49bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        int power = 1 << Utility.highBit(recordCount);
50bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        int extra = recordCount - power;
51bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert
52bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        output.print("le_int32 ScriptRun::scriptRecordsPower = 0x");
53bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        output.print(Utility.hex(power, 4));
54bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        output.println(";");
55bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert
56bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert
57bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        output.print("le_int32 ScriptRun::scriptRecordsExtra = 0x");
58bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        output.print(Utility.hex(extra, 4));
59bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        output.println(";");
60bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert
61bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        Vector[] scriptRangeOffsets = new Vector[maxScript - minScript + 1];
62bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert
63bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        for (int script = minScript; script <= maxScript; script += 1) {
64bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            scriptRangeOffsets[script - minScript] = new Vector();
65bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        }
66bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert
67bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        for (int record = 0; record < recordCount; record += 1) {
68bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            scriptRangeOffsets[scriptData.getRecord(record).scriptCode() - minScript].addElement(new Integer(record));
69bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        }
70bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert
71bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        output.println();
72bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert
73bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        for (int script = minScript; script <= maxScript; script += 1) {
74bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            Vector offsets = scriptRangeOffsets[script - minScript];
75bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert
76bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            output.print("le_int16 ");
77bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            output.print(scriptData.getTag(script));
78bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            output.println("ScriptRanges[] = {");
79bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            output.print("    ");
80bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert
81bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            for (int offset = 0; offset < offsets.size(); offset += 1) {
82bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                Integer i = (Integer) offsets.elementAt(offset);
83bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert
84bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                output.print(i.intValue());
85bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                output.print(", ");
86bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            }
87bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert
88bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            output.println("-1");
89bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            output.println(postamble);
90bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        }
91bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert
92bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        output.println("le_int16 *ScriptRun::scriptRangeOffsets[] = {");
93bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert
94bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        for (int script = minScript; script <= maxScript; script += 1) {
95bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            output.print("    ");
96bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            output.print(scriptData.getTag(script));
97bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            output.print("ScriptRanges");
98bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            output.print(script == maxScript? "  " : ", ");
99bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            output.print("// ");
100bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            output.println(scriptData.getName(script));
101bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        }
102bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert
103bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        output.println(postamble);
104bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert
105bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        writeTrailer();
106bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        closeFile();
107bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert    }
108bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert
109bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert    private static final String[] includeFiles = {"LETypes.h", "LEScripts.h", "ScriptRun.h"};
110bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert
111bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert    private static final String preamble =
112bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert    "\n" +
113bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert    "ScriptRecord ScriptRun::scriptRecords[] = {";
114bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert
115bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert    private static final String postamble =
116bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert    "};\n";
117bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert}