lorp / samsa Goto Github PK
View Code? Open in Web Editor NEWVariable font inspector
Home Page: https://lorp.github.io/samsa/
License: Apache License 2.0
Variable font inspector
Home Page: https://lorp.github.io/samsa/
License: Apache License 2.0
Hi Lawrence and/or dev team,
When using Samsa (the version hosted on axis-praxis.org) to test OTVARs with several FeatureVariationRecords with intersecting conditions, Samsa's behaviour seems not to be according to spec.
The spec says: Feature variation records must be ordered in the order of precedence for the condition sets. During processing, the feature variation records will be read, and the corresponding condition sets tested, in the order in which they occur. If the condition set for a given record does not match the runtime context, then the next record is checked. The first feature variation record for which the condition set matches the runtime context will be considered as a candidate: if the version of the FeatureTableSubstitution table is supported, then this feature variation record will be used, and no additional feature variation records will be considered.
(https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#featVarTbl)
This means that only one FeatureVariationRecord can ever be active for all glyphs in the font depending on slider placement. So, if you have two glyph substitutions, glyph A with condition X and glyph B with condition Y, if condition X is true, condition Y isn't checked when drawing glyph B by InDesign, Chrome and other software that (claims to) support OTVARs. But Samsa seems to carry on down the pecking order of FeatureVariationRecords until it finds one relevant for the current glyph.
With options for:
e.g. by representative glyph(s)
It would be great to see how the MVAR table is modifying a font's attributes across each axis range or for each instance. The changes may be animatable using css?
Offer a toggle on the current glyph to see the graphical effect. It should be particularly useful for corner masters.
It could be useful to offer disabling delta sets on a whole font, via command line or GUI. We can’t use the id of the delta set (the same master is not guaranteed to have the same delta set id in each glyph), so we must use a filter on the tuple. Disabling a delta set by tuple through a whole font on the command line could use an argument such as --disable-delta-set "<tuple-filter>"
where tuple-filter
specifies the tuple in full, e.g. [1,1]
to delete a corner tuple, or [0.755 0.877 0.901]
to remove an intermediate tuple.
Care needs to be taken that adding a "disabled" check does not affect export time on the default case, fonts with all delta sets active.
Toggling of delta sets on a single glyph, with immediate visual feedback, was implemented in the 2017 version of Samsa.
This issue tracks what needs to be fixed in exported static TTFs before they can be used for production. Fixed subissues are marked as checked. New subissues may be added to the list.
rvrn
feature variations)OS/2
table and other font-wide metrics)cvt
table, turns variable hinting into static hinting)head
table)Note: The static TTF instances generated by Samsa-GUI and Samsa-CLI both use the SamsaFont.exportInstance() method in samsa-core.js, so binaries are identical.
The TODO at
Line 1795 in 42f44ad
In some versions of macOS Safari, the left-hand column of panels scrolls back to the top when the user interacts with controls. The app is only usable when the left column is scrolled to the top.
The column is <div id="controls">
, and its CSS includes overflow-y: scroll
. It may be relevant that some of the interactions (though not all) cause a height change to the whole column, although such a change should not trigger a scroll to top.
Versions affected include Safari 12.1.2 on macOS 14.4.6. Before the test machine was upgraded from macOS 10.14 to 10.14.6 the problem was not observed.
The issue is not observed in macOS 10.15.5, nor in Firefox or Chrome.
Note: This was a feature of the original Samsa UI.
Currently, the "drop font here" target is very small. This means, in part, that it's easy for new users to drop a font on the main white area, which does nothing but gives them a "download" (in Chrome).
It would be much nicer if this had a bigger drop area, more similar to existing UI patterns on sites like WakamaiFondue or other typical drag-n-drop upload screens:
Ideally, this has a few features:
Thanks for an awesome tool!
Making static fonts uses two different functions, depending on whether we are reading the VF from a file (in which case we use SamsaVF_compileBinaryForInstance() or if we read from memory (we use makeStaticFont()). The SamsaVF_compileBinaryForInstance() function is more recent and we should move all of makeStaticFont’s logic into that function.
It would be great if we can load google fonts or upload custom fonts to Samsa.
Composite glyphs are being read into the glyph structure correctly. But other parts are lacking:
Thank you for your great tool! When trying Inter variable font from here: https://github.com/rsms/inter/blob/v3.14/docs/font-files/Inter.var.otf
I get this:
Uncaught TypeError: Cannot read property 'axisOrdering' of undefined
at (index):1504
at Array.forEach (<anonymous>)
at SamsaFont.vfLoaded [as callback] ((index):1490)
at SamsaFont.parse (samsa-core.js:797)
at new SamsaFont (samsa-core.js:2560)
at FileReader.reader.onload ((index):3382)
(anonymous) @ (index):1504
vfLoaded @ (index):1490
SamsaFont.parse @ samsa-core.js:797
SamsaFont @ samsa-core.js:2560
reader.onload @ (index):3382
load (async)
(anonymous) @ (index):3377
I have a font which needs format 4 Axis value tables since the font contains multiple axes. In order to use this format, the STAT table must be v2.
I've attached the font.
Inconsolata[wdth,wght].ttf.zip
Just an fyi to others, MS Office doesn't support v2 either.
The smallest unit amount is 1/16384 in 2.14 normalized values, and 1/65536 in 16.16 user values.
Reported by @mekkablue. Although the transformation matrix for each component is parsed, it is not used when converting the glyph to SVG. Need a decompose() method that converts any composite glyph to a simple glyph, whether variations have been applied or not.
How would you feel about me porting this over to typescript to be easier to grok?
While checking various implementations I found that the Microsoft STAT implementation for STAT Axis value table Format 2 assumes inclusive ranges (I think? DirectWrite doesn't expose controls to access arbitrary coordinates). So, for example, an Axis value table with nominal/min/max of 400/350/450 includes the max value 450 in the range. Samsa and Adobe apps assume exclusive so the range effectively ends at 449. I believe this needs clarification in the spec first and implementations should be updated to follow.
Currently the Tuple Variations panel presents as "IUP" the number of points that are not touched. This is incorrect, as points on contours that are not touched at all are not IUP, and nor are phantom points. There are actually 4 categories of points, regarding IUP status:
When dropping another font into Samsa, it’s info gets added to the existing info on the left instead of the panel removing the old data first.
As an "inspector" tool, it would be helpful to know which version of a STAT table/record I am seeing :)
Example, RobotoExtremo-VF.ttf:
<TTGlyph name="etilde" xMin="85" yMin="-30" xMax="1008" yMax="1446">
<component glyphName="e" x="0" y="0" flags="0x204"/>
<component glyphName="tildecomb" x="32" y="-11" flags="0x4"/>
</TTGlyph>
.
.
.
<TTGlyph name="tildecomb" xMin="156" yMin="1190" xMax="911" yMax="1457">
<component glyphName="tilde" x="0" y="0" flags="0x204"/>
</TTGlyph>
I was working on the assumption that macOS still did not handle such fonts. However, that bug seems to be fixed, so we must fix it in Samsa.
The panel for the Glyphs palette is too long for navigation. In animation mode is difficult to focus on the glyph being verified to advance to another glyph.
Some ideas to propose:
• Glyphs with components could be grouped
• The panel could be located as a floating window or located in another area of the interface, by example the bottom. Which would allow a wider palette to display more glyphs per row
Many thanks for the nice work!
It would be nice to have an option to compose words. Would be very useful, especially on fonts with an opsz or more axes.
The IUP (interpolate untouched points) of point deltas should only need to be performed during parsing. This will mean more memory usage for those fonts which make use of IUP, but instantiation should be faster for all fonts.
This should not be difficult. But remember that animating multiple axes at once in general results in non-linear interpolation. However, if the tuples that affect an axis affect that axis and no other, then we retain piecewise linearity. Corner masters are a problem, so in a typical wght/wdth font with corner masters, the non-linearity issue means we cannot export faithful SVG animations of animating both axes at once.
And in time, allow the palettes to be saved in local storage.
Line 27 in 1cfe120
The CONFIG.isNode check is true when compiled in a typescript environment. This creates issues, so I'm temporarily going to create a samsa-core-browser.js that removes the node check.
Make it optional so output is faster. Currently checksums are zeroed, and these fonts seem to perform fine in most places.
Filename: append "-" and the current instance name to the current filename.
Name table: edit at least nameIDs 2 (Font Subfamily name), 5 (version), 6 (PostScript name), 17 (Typographic Subfamily).
While using Samsa (thanks a lot for this handy tool!) I came across 2 small things that I wanted to share.
In the Axes section I can select and edit the values on the very right, but putting something else in there and hitting Enter does not do anything. Should it?
Working on a 4 axes font the Instances section gets a bit difficult to handle with half the values disappearing to the right. Sure, I can get to them by scrolling. Maybe it would be really nice if there’s a little more space for the sidebar?
Optional when parsing a font. (For many operations outside of the GUI we don’t need to parse them, just copy the post
table intact.)
@mekkablue reports “the width indicators in Samsa seem to catch only the first component”.
The SVG animation exporter currently ignores the ‘fvar’ and ‘avar’ tables, so all the deltas are timed according to the -1, 0, +1 normalized scale. This results in animations with min at t=0, default at t=0.5, and max and t=1. Axes in many fonts have their default closer to min than to max, so current behaviour results in unexpected timing behaviour.
If not, choose glyph id 0.
The x and y axes should be assignable to any axis. Develop so that multiple axes can be assigned to one Cartesian axis, so multiple axes can be moved in unison.
Please either
put the font menu at the top, or
do not open all the windows above it when a font is selected.
it disappears.
thanks
I've noticed Samsa is including an elided Axis Value in the STAT's composed name field for a VF family which consists of two fonts, Roman and Italic.
If I ttx the font, I can see the Axis Value is elided (I know this Axis Value should't be a format 2)
<AxisIndex value="1"/>
<Flags value="2"/>
<ValueNameID value="271"/> <!-- Roman -->
<NominalValue value="0.0"/>
<RangeMinValue value="0.0"/>
<RangeMaxValue value="0.0"/>
</AxisValue>
Hi, I noticed that the ttf that samsa generates from an instance doesn't contains the space character (32) anymore.
I reverted to an older commit (adfc0f0) and it worked there.
Hope it can help !
Just noticed while watching the presentation.
This is a pretty cool tool. I'm impressed with the amount of features given you've written this yourself.
Whilst inspecting a font, I noticed some components appear off.
I've attached the font and the gid you want to inspect is 138
Currently, many areas in the sidebar have no padding, which makes them slightly stressful to look at and use, especially if the window is full screen and these are right on the edge of my clickable area.
A very simple and effective improvement would be adding padding: 0.5 rem
to the divs inside each panel:
This is actually achievable with just a couple lines of CSS:
.panel>div {
padding: 0.25rem 0.75rem; /* 4px of space at top & bottom, 12px space on left & right */
box-sizing: border-box; /* prevents width of div from exceed width of parent */
}
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.