blob: 928d24e644e9b84cb259568e68f1c383a09b58e9 [file] [log] [blame]
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// TODO(kojii): This file is compiled with $host_toolchain, which cannot find
// include files in platform/fonts. The build scripts should include this
// directory, and fix these #include's to "platform/fonts/...".
#include "CharacterPropertyDataGenerator.h"
#include "CharacterProperty.h"
#include <cassert>
#include <cstring>
#include <stdio.h>
#if !defined(USING_SYSTEM_ICU)
#define MUTEX_H // Prevent compile failure of utrie2.h on Windows
#include <utrie2.h>
#endif
#if defined(USING_SYSTEM_ICU)
static void generate(FILE*)
{
}
#else
using namespace blink;
const UChar32 kMaxCodepoint = 0x10FFFF;
#define ARRAY_LENGTH(a) (sizeof(a) / sizeof((a)[0]))
static void setRanges(CharacterProperty* values,
const UChar32* ranges, size_t length,
CharacterProperty value)
{
assert(length % 2 == 0);
const UChar32* end = ranges + length;
for (; ranges != end; ranges += 2) {
assert(ranges[0] <= ranges[1]
&& ranges[1] <= kMaxCodepoint);
for (UChar32 c = ranges[0]; c <= ranges[1]; c++)
values[c] |= value;
}
}
static void setValues(CharacterProperty* values,
const UChar32* begin, size_t length,
CharacterProperty value)
{
const UChar32* end = begin + length;
for (; begin != end; begin++) {
assert(*begin <= kMaxCodepoint);
values[*begin] |= value;
}
}
static void generateUTrieSerialized(FILE* fp, int32_t size, uint8_t* array)
{
fprintf(fp,
"#include <cstdint>\n\n"
"namespace blink {\n\n"
"int32_t serializedCharacterDataSize = %d;\n"
"uint8_t serializedCharacterData[] = {", size);
for (int32_t i = 0; i < size; ) {
fprintf(fp, "\n ");
for (int col = 0; col < 16 && i < size; col++, i++)
fprintf(fp, " 0x%02X,", array[i]);
}
fprintf(fp,
"\n};\n\n"
"} // namespace blink\n");
}
static void generate(FILE* fp)
{
// Create a value array of all possible code points.
const UChar32 size = kMaxCodepoint + 1;
CharacterProperty* values = new CharacterProperty[size];
memset(values, 0, sizeof(CharacterProperty) * size);
#define SET(name) \
setRanges(values, name##Ranges, ARRAY_LENGTH(name##Ranges), \
CharacterProperty::name); \
setValues(values, name##Array, ARRAY_LENGTH(name##Array), \
CharacterProperty::name);
SET(isCJKIdeographOrSymbol);
SET(isUprightInMixedVertical);
SET(isPotentialCustomElementNameChar);
// Create a trie from the value array.
UErrorCode error = U_ZERO_ERROR;
UTrie2* trie = utrie2_open(0, 0, &error);
assert(error == U_ZERO_ERROR);
UChar32 start = 0;
CharacterProperty value = values[0];
for (UChar32 c = 1;; c++) {
if (c < size && values[c] == value)
continue;
if (static_cast<uint32_t>(value)) {
utrie2_setRange32(trie, start, c - 1,
static_cast<uint32_t>(value), TRUE, &error);
assert(error == U_ZERO_ERROR);
}
if (c >= size)
break;
start = c;
value = values[start];
}
// Freeze and serialize the trie to a byte array.
utrie2_freeze(trie, UTrie2ValueBits::UTRIE2_16_VALUE_BITS, &error);
assert(error == U_ZERO_ERROR);
int32_t serializedSize = utrie2_serialize(trie, nullptr, 0, &error);
error = U_ZERO_ERROR;
uint8_t* serialized = new uint8_t[serializedSize];
serializedSize = utrie2_serialize(trie, serialized, serializedSize, &error);
assert(error == U_ZERO_ERROR);
generateUTrieSerialized(fp, serializedSize, serialized);
utrie2_close(trie);
}
#endif
int main(int argc, char** argv)
{
// Write the serialized array to the source file.
if (argc <= 1) {
generate(stdout);
} else {
FILE* fp = fopen(argv[1], "wb");
generate(fp);
fclose(fp);
}
return 0;
}