117 строки
4.4 KiB
JavaScript
117 строки
4.4 KiB
JavaScript
/**
|
|
* Copyright (c) Microsoft Corporation.
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
// @ts-check
|
|
const xml2js = require('xml2js');
|
|
const fs = require('fs');
|
|
const path = require('path');
|
|
const { argv } = require('process');
|
|
|
|
// From https://source.chromium.org/chromium/chromium/src/+/main:chrome/browser/ui/prefs/prefs_tab_helper.cc;l=130;drc=62b77bef90de54f0136b51935fa2d5814a1b4da9
|
|
// and https://source.chromium.org/chromium/chromium/src/+/main:third_party/blink/renderer/platform/text/locale_to_script_mapping.cc;l=44;drc=befcb6de95fb8c88c162ce1f64111f6c17351b13
|
|
// note that some suffixes like _JAPANESE, _KOREAN don't have matching icu codes.
|
|
const codeToScriptName = new Map([
|
|
['ARABIC', 'arab'],
|
|
['CYRILLIC', 'cyrl'],
|
|
['GREEK', 'grek'],
|
|
['JAPANESE', 'jpan'],
|
|
['KOREAN', 'hang'],
|
|
['SIMPLIFIED_HAN', 'hans'],
|
|
['TRADITIONAL_HAN', 'hant'],
|
|
]);
|
|
|
|
const idToProtocol = new Map([
|
|
['IDS_STANDARD_FONT_FAMILY', 'standard'],
|
|
['IDS_SANS_SERIF_FONT_FAMILY','sansSerif'],
|
|
['IDS_SERIF_FONT_FAMILY', 'serif'],
|
|
['IDS_CURSIVE_FONT_FAMILY', 'cursive'],
|
|
['IDS_FANTASY_FONT_FAMILY', 'fantasy'],
|
|
['IDS_FIXED_FONT_FAMILY', 'fixed'],
|
|
]);
|
|
|
|
class ScriptFontFamilies {
|
|
scriptToFontFamilies = new Map();
|
|
|
|
setFont(scriptName, familyName, value) {
|
|
let fontFamilies = this.scriptToFontFamilies.get(scriptName);
|
|
if (!fontFamilies) {
|
|
fontFamilies = {};
|
|
this.scriptToFontFamilies.set(scriptName, fontFamilies);
|
|
}
|
|
fontFamilies[familyName] = value;
|
|
}
|
|
|
|
toJSON() {
|
|
const forScripts = Array.from(this.scriptToFontFamilies.entries()).filter(([name, _]) => !!name).map(([script, fontFamilies]) => ({ script, fontFamilies }));
|
|
return {
|
|
fontFamilies: this.scriptToFontFamilies.get(''),
|
|
forScripts: forScripts.length ? forScripts : undefined
|
|
};
|
|
}
|
|
}
|
|
|
|
if (argv.length < 3)
|
|
throw new Error('Expected path to "chromium/src" checkout as first argument')
|
|
|
|
// Upstream files location is https://chromium.googlesource.com/chromium/src/+/main/chrome/app/resources/locale_settings_linux.grd
|
|
const resourceDir = path.join(argv[2], 'chrome/app/resources/');
|
|
if (!fs.existsSync(resourceDir))
|
|
throw new Error(`Path ${resourceDir} does not exist`);
|
|
|
|
function parseXML(xml) {
|
|
let result;
|
|
xml2js.parseString(xml, {trim: true}, (err, r) => result = r);
|
|
return result;
|
|
}
|
|
|
|
const result = {};
|
|
for (const platform of ['linux', 'mac', 'win']) {
|
|
const f = path.join(resourceDir, `locale_settings_${platform}.grd`);
|
|
const xmlDataStr = fs.readFileSync(f);
|
|
let jsonObj = parseXML(xmlDataStr);
|
|
if (!jsonObj)
|
|
throw new Error('Failed to parse ' + f);
|
|
const fontFamilies = new ScriptFontFamilies();
|
|
const defaults = jsonObj.grit.release[0].messages[0].message;
|
|
defaults.forEach(e => {
|
|
const name = e['$']['name'];
|
|
let scriptName = '';
|
|
let familyName;
|
|
for (const id of idToProtocol.keys()) {
|
|
if (!name.startsWith(id))
|
|
continue;
|
|
familyName = idToProtocol.get(id);
|
|
if (name !== id) {
|
|
const suffix = name.substring(id.length + 1);
|
|
// We don't support this, see https://source.chromium.org/chromium/chromium/src/+/main:chrome/browser/ui/prefs/prefs_tab_helper.cc;l=384-390;drc=62b77bef90de54f0136b51935fa2d5814a1b4da9
|
|
if (suffix === 'ALT_WIN')
|
|
continue;
|
|
scriptName = codeToScriptName.get(suffix);
|
|
if (!scriptName)
|
|
throw new Error('NO Script name for: ' + suffix);
|
|
}
|
|
break;
|
|
}
|
|
// Skip things like IDS_NTP_FONT_FAMILY, IDS_MINIMUM_FONT_SIZE etc.
|
|
if (!familyName)
|
|
return;
|
|
fontFamilies.setFont(scriptName, familyName, e['_'])
|
|
});
|
|
result[platform] = fontFamilies.toJSON();
|
|
}
|
|
|
|
console.log(JSON.stringify(result, null, 2).replaceAll('"', `'`));
|