2022-02-11 20:06:17 +03:00
/ * *
* 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' ] ,
2022-05-10 04:28:39 +03:00
[ 'IDS_PICTOGRAPH_FONT_FAMILY' , 'pictograph' ]
2022-02-11 20:06:17 +03:00
] ) ;
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 ( '"' , ` ' ` ) ) ;