117 lines
		
	
	
		
			4.4 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
			
		
		
	
	
			117 lines
		
	
	
		
			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('"', `'`));
 |