├── .gitignore ├── releases └── sketch-sf-font-fixer.sketchplugin.1.0.zip ├── sketch-sf-font-fixer.sketchplugin └── Contents │ └── Sketch │ ├── manifest.json │ └── script.cocoascript ├── LICENSE ├── appcast.xml └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | -------------------------------------------------------------------------------- /releases/sketch-sf-font-fixer.sketchplugin.1.0.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kylehickinson/Sketch-SF-UI-Font-Fixer/HEAD/releases/sketch-sf-font-fixer.sketchplugin.1.0.zip -------------------------------------------------------------------------------- /sketch-sf-font-fixer.sketchplugin/Contents/Sketch/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "author" : "Kyle Hickinson", 3 | "commands" : [ 4 | { 5 | "script" : "script.cocoascript", 6 | "handler" : "onRun", 7 | "shortcut" : "cmd ctrl t", 8 | "name" : "Fix San Francisco Character Spacing", 9 | "identifier" : "fixSelectedLayers", 10 | }, 11 | ], 12 | "menu": { 13 | "isRoot": true, 14 | "items": [ 15 | "fixSelectedLayers", 16 | ] 17 | }, 18 | "appcast": "https://api.sketchpacks.com/v1/plugins/com.kylehickinson.sf-fix-fonts/appcast", 19 | "identifier" : "com.kylehickinson.sf-fix-fonts", 20 | "version" : "1.1", 21 | "description" : "A plugin which adjusts character spacing of SF UI Text/SF UI Display text layers based on its font size", 22 | "authorEmail" : "kyle.hickinson@gmail.com", 23 | "name" : "SF UI Font Fixer" 24 | } 25 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2014 Kyle Hickinson 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /appcast.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | SF UI Font Fixer 5 | https://raw.githubusercontent.com/kylehickinson/Sketch-SF-UI-Font-Fixer/master/appcast.xml 6 | A Sketch plugin that adjusts the character spacing on text layers using iOS 9's SF UI Text/SF UI Display fonts to what it would be when used in an iOS app. 7 | en 8 | 9 | Version 1.0 10 | 11 | A Sketch plugin that adjusts the character spacing on text layers using iOS 9's SF UI Text/Display fonts to what it would be when used in the app.

13 |

E.g. If you use SF UI Text at 16pt the script will set this layer's character spacing to -0.32.

14 | ]]> 15 |
16 | Thu, 01 Jun 2017 09:54:00 -0500 17 | 18 |
19 |
20 |
-------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Download from Sketchpacks.com](https://badges.sketchpacks.com/plugins/com.kylehickinson.sf-fix-fonts/version.svg)](https://api.sketchpacks.com/v1/plugins/com.kylehickinson.sf-fix-fonts/download) [![Compatible Sketch Version](https://badges.sketchpacks.com/plugins/com.kylehickinson.sf-fix-fonts/compatibility.svg)](https://sketchpacks.com/kylehickinson/Sketch-SF-UI-Font-Fixer) 2 | 3 | A Sketch plugin that adjusts the character spacing on text layers using iOS 9's SF UI Text/Display fonts to what it would be when used in the app. 4 | 5 | E.g. If you use SF UI Text at 16pt the script will set this layer's character spacing to -0.32. 6 | 7 | ### Why 8 | 9 | When you use `-[UIFont systemFontOfSize:]` or other system font related API's in iOS, iOS automatically adjusts the font's tracking based on the point size you're using (see Tracking Table: https://developer.apple.com/fonts/ or check out WWDC session 804 "Introducing the New System Fonts"). Since this happens at an API level and not a font level, Sketch has no way of determining its default character spacing. Scripting it is better than doing it manually every time ¯\\\_(ツ)\_/¯. 10 | 11 | Oddly enough official tracking table matches SF UI Text much better than SF UI Display. So SF UI Display's size to character spacing mapping is generated in a small iOS project. 12 | 13 | ### How 14 | 15 | Just select the text layers that have SF UI Text/Display fonts being used and run the script (Plugins > Fix SF UI Font Character Spacing), it will set the correct spacing based on the current font size. If you change that layer's font size you will need to re-run the script on that layer. 16 | 17 | ### Keyboard Shortcut 18 | 19 | `⌃⌘T`. (Ctrl+Cmd+T) If you want it to be something different you can technically edit the `manifest.json` file in the plugin. 20 | -------------------------------------------------------------------------------- /sketch-sf-font-fixer.sketchplugin/Contents/Sketch/script.cocoascript: -------------------------------------------------------------------------------- 1 | var adjustUITextFontForLayer = function(layer) { 2 | var fontSize = layer.fontSize(); 3 | 4 | var characterSpacings = { 6: 0.246, 5 | 7: 0.223, 6 | 8: 0.208, 7 | 9: 0.171, 8 | 10: 0.12, 9 | 11: 0.06, 10 | 12: 0, 11 | 13: -0.078, 12 | 14: -0.154, 13 | 15: -0.24, 14 | 16: -0.32, 15 | 17: -0.408, 16 | 18: -0.45, 17 | 19: -0.49 }; 18 | 19 | if (characterSpacings[fontSize] != nil) { 20 | [layer setCharacterSpacing:characterSpacings[fontSize]]; 21 | } 22 | }; 23 | 24 | var adjustUIDisplayFontForLayer = function(layer) { 25 | var fontSize = layer.fontSize(); 26 | 27 | var characterSpacings = { 20: 0.340402, 28 | 21: 0.326660, 29 | 22: 0.320731, 30 | 23: 0.324079, 31 | 24: 0.326451, 32 | 25: 0.327846, 33 | 26: 0.328265, 34 | 27: 0.327706, 35 | 28: 0.326172, 36 | 29: 0.323661, 37 | 30: 0.334821, 38 | 31: 0.330845, 39 | 32: 0.341518, 40 | 33: 0.336077, 41 | 34: 0.346261, 42 | 35: 0.339355, 43 | 36: 0.349051, 44 | 37: 0.340681, 45 | 38: 0.331334, 46 | 39: 0.340053, 47 | 40: 0.329241, 48 | 41: 0.337472, 49 | 42: 0.325195, 50 | 43: 0.332938, 51 | 44: 0.319196, 52 | 45: 0.304478, 53 | 46: 0.311244, 54 | 47: 0.295061, 55 | 48: 0.301339, 56 | 49: 0.283691, 57 | 50: 0.289481, 58 | 51: 0.270368, 59 | 52: 0.250279, 60 | 53: 0.255092, 61 | 54: 0.233538, 62 | 55: 0.237863, 63 | 56: 0.214844, 64 | 57: 0.218680, 65 | 58: 0.194196, 66 | 59: 0.168736, 67 | 60: 0.171596, 68 | 61: 0.144671, 69 | 62: 0.147042, 70 | 63: 0.118652, 71 | 64: 0.120536, 72 | 65: 0.090681, 73 | 66: 0.092076, 74 | 67: 0.060756, 75 | 68: 0.061663, 76 | 69: 0.062570, 77 | 70: 0.029297, 78 | 71: 0.029715, 79 | 72: 0.030134, 80 | 73: -0.005092, 81 | 74: -0.005162, 82 | 75: -0.041853, 83 | 76: -0.042411, 84 | 77: -0.042969, 85 | 78: -0.081613, 86 | 79: -0.082659, 87 | 80: -0.083705, 88 | 81: -0.084752 }; 89 | 90 | if (characterSpacings[fontSize] != nil) { 91 | [layer setCharacterSpacing:characterSpacings[fontSize]]; 92 | } 93 | }; 94 | 95 | var onRun = function(context) { 96 | var selectedLayers = context.selection; 97 | var loop = [selectedLayers objectEnumerator]; 98 | 99 | while (layer = [loop nextObject]) { 100 | if (layer.isKindOfClass(MSTextLayer)) { 101 | var fontName = layer.fontPostscriptName(); 102 | if (fontName.hasPrefix("SFUIText") || fontName.hasPrefix("SFProText")) { 103 | adjustUITextFontForLayer(layer); 104 | } 105 | if (fontName.hasPrefix("SFUIDisplay") || fontName.hasPrefix("SFProDisplay")) { 106 | adjustUIDisplayFontForLayer(layer); 107 | } 108 | } 109 | } 110 | }; --------------------------------------------------------------------------------