1*e5825d3bSAndroid Build Coastguard Worker#!/usr/bin/python 2*e5825d3bSAndroid Build Coastguard Worker# coding=UTF-8 3*e5825d3bSAndroid Build Coastguard Worker# 4*e5825d3bSAndroid Build Coastguard Worker# Copyright 2014 Google Inc. All rights reserved. 5*e5825d3bSAndroid Build Coastguard Worker# 6*e5825d3bSAndroid Build Coastguard Worker# Licensed under the Apache License, Version 2.0 (the "License"); 7*e5825d3bSAndroid Build Coastguard Worker# you may not use this file except in compliance with the License. 8*e5825d3bSAndroid Build Coastguard Worker# You may obtain a copy of the License at 9*e5825d3bSAndroid Build Coastguard Worker# 10*e5825d3bSAndroid Build Coastguard Worker# http://www.apache.org/licenses/LICENSE-2.0 11*e5825d3bSAndroid Build Coastguard Worker# 12*e5825d3bSAndroid Build Coastguard Worker# Unless required by applicable law or agreed to in writing, software 13*e5825d3bSAndroid Build Coastguard Worker# distributed under the License is distributed on an "AS IS" BASIS, 14*e5825d3bSAndroid Build Coastguard Worker# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15*e5825d3bSAndroid Build Coastguard Worker# See the License for the specific language governing permissions and 16*e5825d3bSAndroid Build Coastguard Worker# limitations under the License. 17*e5825d3bSAndroid Build Coastguard Worker 18*e5825d3bSAndroid Build Coastguard Worker"""Create a curated subset of NotoSansSymbols for Android.""" 19*e5825d3bSAndroid Build Coastguard Worker 20*e5825d3bSAndroid Build Coastguard Worker__author__ = '[email protected] (Roozbeh Pournader)' 21*e5825d3bSAndroid Build Coastguard Worker 22*e5825d3bSAndroid Build Coastguard Workerimport contextlib 23*e5825d3bSAndroid Build Coastguard Workerimport os 24*e5825d3bSAndroid Build Coastguard Workerimport sys 25*e5825d3bSAndroid Build Coastguard Workerimport tempfile 26*e5825d3bSAndroid Build Coastguard Worker 27*e5825d3bSAndroid Build Coastguard Workerfrom fontTools import ttLib 28*e5825d3bSAndroid Build Coastguard Workerfrom pathlib import PurePosixPath 29*e5825d3bSAndroid Build Coastguard Worker 30*e5825d3bSAndroid Build Coastguard Workerfrom nototools import subset 31*e5825d3bSAndroid Build Coastguard Workerfrom nototools import unicode_data 32*e5825d3bSAndroid Build Coastguard Worker 33*e5825d3bSAndroid Build Coastguard Worker# Unicode blocks that we want to include in the font 34*e5825d3bSAndroid Build Coastguard WorkerBLOCKS_TO_INCLUDE = """ 35*e5825d3bSAndroid Build Coastguard Worker20D0..20FF; Combining Diacritical Marks for Symbols 36*e5825d3bSAndroid Build Coastguard Worker2100..214F; Letterlike Symbols 37*e5825d3bSAndroid Build Coastguard Worker2190..21FF; Arrows 38*e5825d3bSAndroid Build Coastguard Worker2200..22FF; Mathematical Operators 39*e5825d3bSAndroid Build Coastguard Worker2300..23FF; Miscellaneous Technical 40*e5825d3bSAndroid Build Coastguard Worker2400..243F; Control Pictures 41*e5825d3bSAndroid Build Coastguard Worker2440..245F; Optical Character Recognition 42*e5825d3bSAndroid Build Coastguard Worker2460..24FF; Enclosed Alphanumerics 43*e5825d3bSAndroid Build Coastguard Worker2500..257F; Box Drawing 44*e5825d3bSAndroid Build Coastguard Worker2580..259F; Block Elements 45*e5825d3bSAndroid Build Coastguard Worker25A0..25FF; Geometric Shapes 46*e5825d3bSAndroid Build Coastguard Worker2600..26FF; Miscellaneous Symbols 47*e5825d3bSAndroid Build Coastguard Worker2700..27BF; Dingbats 48*e5825d3bSAndroid Build Coastguard Worker27C0..27EF; Miscellaneous Mathematical Symbols-A 49*e5825d3bSAndroid Build Coastguard Worker27F0..27FF; Supplemental Arrows-A 50*e5825d3bSAndroid Build Coastguard Worker2800..28FF; Braille Patterns 51*e5825d3bSAndroid Build Coastguard Worker2900..297F; Supplemental Arrows-B 52*e5825d3bSAndroid Build Coastguard Worker2980..29FF; Miscellaneous Mathematical Symbols-B 53*e5825d3bSAndroid Build Coastguard Worker2A00..2AFF; Supplemental Mathematical Operators 54*e5825d3bSAndroid Build Coastguard Worker2B00..2BFF; Miscellaneous Symbols and Arrows 55*e5825d3bSAndroid Build Coastguard Worker4DC0..4DFF; Yijing Hexagram Symbols 56*e5825d3bSAndroid Build Coastguard Worker10140..1018F; Ancient Greek Numbers 57*e5825d3bSAndroid Build Coastguard Worker10190..101CF; Ancient Symbols 58*e5825d3bSAndroid Build Coastguard Worker101D0..101FF; Phaistos Disc 59*e5825d3bSAndroid Build Coastguard Worker1D000..1D0FF; Byzantine Musical Symbols 60*e5825d3bSAndroid Build Coastguard Worker1D100..1D1FF; Musical Symbols 61*e5825d3bSAndroid Build Coastguard Worker1D200..1D24F; Ancient Greek Musical Notation 62*e5825d3bSAndroid Build Coastguard Worker1D300..1D35F; Tai Xuan Jing Symbols 63*e5825d3bSAndroid Build Coastguard Worker1D360..1D37F; Counting Rod Numerals 64*e5825d3bSAndroid Build Coastguard Worker1D400..1D7FF; Mathematical Alphanumeric Symbols 65*e5825d3bSAndroid Build Coastguard Worker1F000..1F02F; Mahjong Tiles 66*e5825d3bSAndroid Build Coastguard Worker1F030..1F09F; Domino Tiles 67*e5825d3bSAndroid Build Coastguard Worker1F0A0..1F0FF; Playing Cards 68*e5825d3bSAndroid Build Coastguard Worker1F700..1F77F; Alchemical Symbols 69*e5825d3bSAndroid Build Coastguard Worker""" 70*e5825d3bSAndroid Build Coastguard Worker 71*e5825d3bSAndroid Build Coastguard Worker# One-off characters to be included. At the moment, this is the Bitcoin sign 72*e5825d3bSAndroid Build Coastguard Worker# (since it's not supported in Roboto yet, and the Japanese TV symbols of 73*e5825d3bSAndroid Build Coastguard Worker# Unicode 9. 74*e5825d3bSAndroid Build Coastguard WorkerONE_OFF_ADDITIONS = { 75*e5825d3bSAndroid Build Coastguard Worker 0x20BF, # ₿ BITCOIN SIGN 76*e5825d3bSAndroid Build Coastguard Worker 0x1F19B, # SQUARED THREE D 77*e5825d3bSAndroid Build Coastguard Worker 0x1F19C, # SQUARED SECOND SCREEN 78*e5825d3bSAndroid Build Coastguard Worker 0x1F19D, # SQUARED TWO K;So;0;L;;;;;N;;;;; 79*e5825d3bSAndroid Build Coastguard Worker 0x1F19E, # SQUARED FOUR K;So;0;L;;;;;N;;;;; 80*e5825d3bSAndroid Build Coastguard Worker 0x1F19F, # SQUARED EIGHT K;So;0;L;;;;;N;;;;; 81*e5825d3bSAndroid Build Coastguard Worker 0x1F1A0, # SQUARED FIVE POINT ONE;So;0;L;;;;;N;;;;; 82*e5825d3bSAndroid Build Coastguard Worker 0x1F1A1, # SQUARED SEVEN POINT ONE;So;0;L;;;;;N;;;;; 83*e5825d3bSAndroid Build Coastguard Worker 0x1F1A2, # SQUARED TWENTY-TWO POINT TWO;So;0;L;;;;;N;;;;; 84*e5825d3bSAndroid Build Coastguard Worker 0x1F1A3, # SQUARED SIXTY P;So;0;L;;;;;N;;;;; 85*e5825d3bSAndroid Build Coastguard Worker 0x1F1A4, # SQUARED ONE HUNDRED TWENTY P;So;0;L;;;;;N;;;;; 86*e5825d3bSAndroid Build Coastguard Worker 0x1F1A5, # SQUARED LATIN SMALL LETTER D;So;0;L;;;;;N;;;;; 87*e5825d3bSAndroid Build Coastguard Worker 0x1F1A6, # SQUARED HC;So;0;L;;;;;N;;;;; 88*e5825d3bSAndroid Build Coastguard Worker 0x1F1A7, # SQUARED HDR;So;0;L;;;;;N;;;;; 89*e5825d3bSAndroid Build Coastguard Worker 0x1F1A8, # SQUARED HI-RES;So;0;L;;;;;N;;;;; 90*e5825d3bSAndroid Build Coastguard Worker 0x1F1A9, # SQUARED LOSSLESS;So;0;L;;;;;N;;;;; 91*e5825d3bSAndroid Build Coastguard Worker 0x1F1AA, # SQUARED SHV;So;0;L;;;;;N;;;;; 92*e5825d3bSAndroid Build Coastguard Worker 0x1F1AB, # SQUARED UHD;So;0;L;;;;;N;;;;; 93*e5825d3bSAndroid Build Coastguard Worker 0x1F1AC, # SQUARED VOD;So;0;L;;;;;N;;;;; 94*e5825d3bSAndroid Build Coastguard Worker 0x1F23B, # SQUARED CJK UNIFIED IDEOGRAPH-914D 95*e5825d3bSAndroid Build Coastguard Worker} 96*e5825d3bSAndroid Build Coastguard Worker 97*e5825d3bSAndroid Build Coastguard Worker# letter-based characters, provided by Roboto 98*e5825d3bSAndroid Build Coastguard WorkerLETTERLIKE_CHARS_IN_ROBOTO = { 99*e5825d3bSAndroid Build Coastguard Worker 0x2100, # ℀ ACCOUNT OF 100*e5825d3bSAndroid Build Coastguard Worker 0x2101, # ℁ ADDRESSED TO THE SUBJECT 101*e5825d3bSAndroid Build Coastguard Worker 0x2103, # ℃ DEGREE CELSIUS 102*e5825d3bSAndroid Build Coastguard Worker 0x2105, # ℅ CARE OF 103*e5825d3bSAndroid Build Coastguard Worker 0x2106, # ℆ CADA UNA 104*e5825d3bSAndroid Build Coastguard Worker 0x2109, # ℉ DEGREE FAHRENHEIT 105*e5825d3bSAndroid Build Coastguard Worker 0x2113, # ℓ SCRIPT SMALL L 106*e5825d3bSAndroid Build Coastguard Worker 0x2116, # № NUMERO SIGN 107*e5825d3bSAndroid Build Coastguard Worker 0x2117, # ℗ SOUND RECORDING COPYRIGHT 108*e5825d3bSAndroid Build Coastguard Worker 0x211E, # ℞ PRESCRIPTION TAKE 109*e5825d3bSAndroid Build Coastguard Worker 0x211F, # ℟ RESPONSE 110*e5825d3bSAndroid Build Coastguard Worker 0x2120, # ℠ SERVICE MARK 111*e5825d3bSAndroid Build Coastguard Worker 0x2121, # ℡ TELEPHONE SIGN 112*e5825d3bSAndroid Build Coastguard Worker 0x2122, # ™ TRADE MARK SIGN 113*e5825d3bSAndroid Build Coastguard Worker 0x2123, # ℣ VERSICLE 114*e5825d3bSAndroid Build Coastguard Worker 0x2125, # ℥ OUNCE SIGN 115*e5825d3bSAndroid Build Coastguard Worker 0x2126, # Ω OHM SIGN 116*e5825d3bSAndroid Build Coastguard Worker 0x212A, # K KELVIN SIGN 117*e5825d3bSAndroid Build Coastguard Worker 0x212B, # Å ANGSTROM SIGN 118*e5825d3bSAndroid Build Coastguard Worker 0x212E, # ℮ ESTIMATED SYMBOL 119*e5825d3bSAndroid Build Coastguard Worker 0x2132, # Ⅎ TURNED CAPITAL F 120*e5825d3bSAndroid Build Coastguard Worker 0x213B, # ℻ FACSIMILE SIGN 121*e5825d3bSAndroid Build Coastguard Worker 0x214D, # ⅍ AKTIESELSKAB 122*e5825d3bSAndroid Build Coastguard Worker 0x214F, # ⅏ SYMBOL FOR SAMARITAN SOURCE 123*e5825d3bSAndroid Build Coastguard Worker} 124*e5825d3bSAndroid Build Coastguard Worker 125*e5825d3bSAndroid Build Coastguard WorkerDEFAULT_EMOJI = unicode_data.get_presentation_default_emoji() 126*e5825d3bSAndroid Build Coastguard Worker 127*e5825d3bSAndroid Build Coastguard WorkerEMOJI_ADDITIONS_FILE = os.path.join( 128*e5825d3bSAndroid Build Coastguard Worker os.path.dirname(__file__), os.path.pardir, os.path.pardir, 129*e5825d3bSAndroid Build Coastguard Worker 'unicode', 'additions', 'emoji-data.txt') 130*e5825d3bSAndroid Build Coastguard Worker 131*e5825d3bSAndroid Build Coastguard Worker 132*e5825d3bSAndroid Build Coastguard Worker# Characters we have decided we are doing as emoji-style in Android, 133*e5825d3bSAndroid Build Coastguard Worker# despite UTR#51's recommendation 134*e5825d3bSAndroid Build Coastguard Workerdef get_android_emoji(): 135*e5825d3bSAndroid Build Coastguard Worker """Return additional Android default emojis.""" 136*e5825d3bSAndroid Build Coastguard Worker android_emoji = set() 137*e5825d3bSAndroid Build Coastguard Worker with open(EMOJI_ADDITIONS_FILE) as emoji_additions: 138*e5825d3bSAndroid Build Coastguard Worker data = unicode_data._parse_semicolon_separated_data( 139*e5825d3bSAndroid Build Coastguard Worker emoji_additions.read()) 140*e5825d3bSAndroid Build Coastguard Worker for codepoint, prop in data: 141*e5825d3bSAndroid Build Coastguard Worker if prop == 'Emoji_Presentation': 142*e5825d3bSAndroid Build Coastguard Worker android_emoji.add(int(codepoint, 16)) 143*e5825d3bSAndroid Build Coastguard Worker return android_emoji 144*e5825d3bSAndroid Build Coastguard Worker 145*e5825d3bSAndroid Build Coastguard Workerdef rename_postscript_name(source_font, target_font, new_name): 146*e5825d3bSAndroid Build Coastguard Worker """Rename the post script name to given one""" 147*e5825d3bSAndroid Build Coastguard Worker with contextlib.closing(ttLib.TTFont(source_font)) as ttf: 148*e5825d3bSAndroid Build Coastguard Worker nameTable = ttf['name'] 149*e5825d3bSAndroid Build Coastguard Worker for name in nameTable.names: 150*e5825d3bSAndroid Build Coastguard Worker if (name.nameID == 6 and name.platformID == 3 and name.platEncID == 1 151*e5825d3bSAndroid Build Coastguard Worker and name.langID == 0x0409): 152*e5825d3bSAndroid Build Coastguard Worker name.string = new_name 153*e5825d3bSAndroid Build Coastguard Worker ttf.save(target_font) 154*e5825d3bSAndroid Build Coastguard Worker 155*e5825d3bSAndroid Build Coastguard Workerdef main(argv): 156*e5825d3bSAndroid Build Coastguard Worker """Subset the Noto Symbols font. 157*e5825d3bSAndroid Build Coastguard Worker 158*e5825d3bSAndroid Build Coastguard Worker The first argument is the source file name, and the second argument is 159*e5825d3bSAndroid Build Coastguard Worker the target file name. 160*e5825d3bSAndroid Build Coastguard Worker """ 161*e5825d3bSAndroid Build Coastguard Worker 162*e5825d3bSAndroid Build Coastguard Worker target_coverage = set() 163*e5825d3bSAndroid Build Coastguard Worker # Add all characters in BLOCKS_TO_INCLUDE 164*e5825d3bSAndroid Build Coastguard Worker for first, last, _ in unicode_data._parse_code_ranges(BLOCKS_TO_INCLUDE): 165*e5825d3bSAndroid Build Coastguard Worker target_coverage.update(range(first, last+1)) 166*e5825d3bSAndroid Build Coastguard Worker 167*e5825d3bSAndroid Build Coastguard Worker # Add one-off characters 168*e5825d3bSAndroid Build Coastguard Worker target_coverage |= ONE_OFF_ADDITIONS 169*e5825d3bSAndroid Build Coastguard Worker # Remove characters preferably coming from Roboto 170*e5825d3bSAndroid Build Coastguard Worker target_coverage -= LETTERLIKE_CHARS_IN_ROBOTO 171*e5825d3bSAndroid Build Coastguard Worker # Remove characters that are supposed to default to emoji 172*e5825d3bSAndroid Build Coastguard Worker android_emoji = get_android_emoji() 173*e5825d3bSAndroid Build Coastguard Worker target_coverage -= DEFAULT_EMOJI | android_emoji 174*e5825d3bSAndroid Build Coastguard Worker 175*e5825d3bSAndroid Build Coastguard Worker # Remove dentistry symbols, as their main use appears to be for CJK: 176*e5825d3bSAndroid Build Coastguard Worker # http://www.unicode.org/L2/L2000/00098-n2195.pdf 177*e5825d3bSAndroid Build Coastguard Worker target_coverage -= set(range(0x23BE, 0x23CC+1)) 178*e5825d3bSAndroid Build Coastguard Worker 179*e5825d3bSAndroid Build Coastguard Worker # Remove COMBINING ENCLOSING KEYCAP. It's needed for Android's color emoji 180*e5825d3bSAndroid Build Coastguard Worker # mechanism to work properly. 181*e5825d3bSAndroid Build Coastguard Worker target_coverage.remove(0x20E3) 182*e5825d3bSAndroid Build Coastguard Worker 183*e5825d3bSAndroid Build Coastguard Worker source_file_name = argv[1] 184*e5825d3bSAndroid Build Coastguard Worker target_file_name = argv[2] 185*e5825d3bSAndroid Build Coastguard Worker 186*e5825d3bSAndroid Build Coastguard Worker tmp = tempfile.NamedTemporaryFile() 187*e5825d3bSAndroid Build Coastguard Worker subset.subset_font( 188*e5825d3bSAndroid Build Coastguard Worker source_file_name, 189*e5825d3bSAndroid Build Coastguard Worker tmp.name, 190*e5825d3bSAndroid Build Coastguard Worker include=target_coverage) 191*e5825d3bSAndroid Build Coastguard Worker 192*e5825d3bSAndroid Build Coastguard Worker # Use given file name as the PostScript name. 193*e5825d3bSAndroid Build Coastguard Worker postScriptName = PurePosixPath(target_file_name).stem 194*e5825d3bSAndroid Build Coastguard Worker rename_postscript_name(tmp.name, target_file_name, postScriptName) 195*e5825d3bSAndroid Build Coastguard Worker 196*e5825d3bSAndroid Build Coastguard Worker second_subset_coverage = DEFAULT_EMOJI | android_emoji 197*e5825d3bSAndroid Build Coastguard Worker second_subset_file_name = argv[3] 198*e5825d3bSAndroid Build Coastguard Worker subset.subset_font( 199*e5825d3bSAndroid Build Coastguard Worker source_file_name, 200*e5825d3bSAndroid Build Coastguard Worker tmp.name, 201*e5825d3bSAndroid Build Coastguard Worker include=second_subset_coverage) 202*e5825d3bSAndroid Build Coastguard Worker 203*e5825d3bSAndroid Build Coastguard Worker # Use given file name as the PostScript name. 204*e5825d3bSAndroid Build Coastguard Worker postScriptName = PurePosixPath(second_subset_file_name).stem 205*e5825d3bSAndroid Build Coastguard Worker rename_postscript_name(tmp.name, second_subset_file_name, postScriptName) 206*e5825d3bSAndroid Build Coastguard Worker 207*e5825d3bSAndroid Build Coastguard Workerif __name__ == '__main__': 208*e5825d3bSAndroid Build Coastguard Worker main(sys.argv) 209