Open arialcrime opened 7 years ago
Hi,
Thanks for reporting.
Putting the (empty) value 0 in there is on purpose in order to make the masters compatible for interpolation. Both masters need to have any values, but part of the plugin’s job is to fill these up for you. At least that was the idea.
What would you exactly expect to happen on that particular example? What do you mean with »standard value of the class«? Do you mean it shouldn’t come up with 0 but a certain value that the other master has set for that exception?
Did I address all your questions?
Hi Mark,
Thanks for the quick reply. The basic idea of the plugin makes sense, and adding zero pairs which do not exist in a master is also very helpful to ensure master compatibility.
In the particular case, /T is kerned to a class of g-like shapes (value = -90) with the exception of /gcircumflex (value = -20) in one master. The other master also included kerning between /T and the group (-50), but does not have the exception.
The problem now is that instead of using the value from “/T to group” (-50) for the exception in the second master, it got zero as the value.
But maybe this goes beyond the concept of Kernschmelze being a helper to Kernkraft.
This has actually nothing to do with being a helper to Kernkraft. They can be used independently from each other.
Anyway, for your example it cannot use the value from “/T to group” (-50), because the source master doesn’t have a “/T to group” stored for /T/gcircumflex. Hence in the target master, it doesn’t find that combination in the kerning entires and puts the zero value there.
Kerning is stored in Glyphs in four different ways: Group—Group NonGroup—NonGroup NonGroup—Group Group—NonGroup While NonGroups are basically the exceptions. The script can only read and apply these.
Does this make sense? Or did I not understand your example properly?
Hi Mark,
we dealt with this at our end and are currently trying an alogrithm, that may be interesting for this issue:
for master_index, (master_id, kerning_data) in enumerate(this_font.kerning.iteritems()):
for left_side_raw, kerning_values in kerning_data.iteritems():
left_side = makeNiceName(this_font, left_side_raw) # Returns glyphname or classname
left_glyph = this_font.glyphs[left_side] if not left_side.startswith('@') else this_font.glyphs[left_side[7:]]
if left_side not in kerning_test_dict.keys():
# Rebuilding the kerning dict with readable names (no glyph ids)
kerning_test_dict[left_side] = {}
for right_side_raw, val in kerning_values.iteritems():
right_side = makeNiceName(this_font, right_side_raw)
# right_glyph is None when it is not a glyph, but a group
right_glyph = this_font.glyphs[right_side] if not right_side.startswith('@') else this_font.glyphs[right_side[7:]]
if right_side not in kerning_test_dict[left_side].keys():
# Rebuild the right side with own data structure
# Basically all masters will have their data at one place. Unlike the native glyphs app kerning dict
# At the beginning I set everything to None or 0.0. This may be overwritten later when there are actual values.
kerning_test_dict[left_side][right_side] = {
'current': [None for m in this_font.masters],
'recommended': [0.0 for m in this_font.masters],
'base_glyph': None,
'left_glyph': left_glyph.name,
}
# Use group kerning value as recommended value when it is present
if right_glyph and right_glyph.leftKerningKey:
group_val = this_font.kerningForPair(master_id, left_side, right_glyph.leftKerningKey)
kerning_test_dict[left_side][right_side]['recommended'] = [group_val for m in this_font.masters]
# Overwrite the None value with the actual value
kerning_test_dict[left_side][right_side]['current'][master_index] = val
# If a value is 0, it is interpreted as suspicious and I look into it
if val == 0:
# So check if the glyph has a left kerning group that is another glyph from the font
# Example: Ä has a 0 value but is part of the A group that has a value
if right_glyph.leftKerningGroup and this_font.glyphs[right_glyph.leftKerningGroup]:
# Get Kerningvalue the baseglyph of the group the (right) glyph was found
recommended_value = this_font.kerningForPair(master_id, left_side, this_font.glyphs[right_glyph.leftKerningGroup].leftKerningKey)
kerning_test_dict[left_side][right_side]['base_glyph'] = right_glyph.leftKerningGroup
if recommended_value < 10000: # it is 9.22337203685e+18 if there is no kerning for kerninggroup ...
# ... so only add a recommended value if there is a (realistic) value
kerning_test_dict[left_side][right_side]['recommended'][master_index] = recommended_value
elif right_glyph.name == right_glyph.leftKerningKey:
# Kerning should actually be 0 because glyph is in no group and has itself as kerning key
kerning_test_dict[left_side][right_side]['recommended'][master_index] = val
else:
# Overwrite recommended value with actual value
kerning_test_dict[left_side][right_side]['recommended'][master_index] = val
After this I go on with this kerning_test_dict
. But I guess you get the picture.
We are currently testing if this catches all problems. So let me know, if you see some issues with this snippet (or if you want to take a look at the whole script).
Hi.
Mark is on holiday until 4. March. Please be patient :-)
Thanks a lot!
on the way please excuse typos and briefness ralph
On 22 Feb 2017, at 16:37, Filip Axani notifications@github.com wrote:
Hi Mark,
we dealt with this at our end and are currently trying an alogrithm, that may be interesting for this issue:
for master_index, (master_id, kerning_data) in enumerate(this_font.kerning.iteritems()): for left_side_raw, kerning_values in kerning_data.iteritems(): left_side = makeNiceName(this_font, left_side_raw) # Returns glyphname or classname left_glyph = this_font.glyphs[left_side] if not left_side.startswith('@') else this_font.glyphs[left_side[7:]] if left_side not in kerning_test_dict.keys():
Rebuilding the kerning dict with readable names (no glyph ids)
kerning_test_dict[left_side] = {} for right_side_raw, val in kerning_values.iteritems(): right_side = makeNiceName(this_font, right_side_raw) # right_glyph is None when it is not a glyph, but a group right_glyph = this_font.glyphs[right_side] if not right_side.startswith('@') else this_font.glyphs[right_side[7:]] if right_side not in kerning_test_dict[left_side].keys(): # Rebuild the right side with own data structure # Basically all masters will have their data at one place. Unlike the native glyphs app kerning dict # At the beginning I set everything to None or 0.0. This may be overwritten later when there are actual values. kerning_test_dict[left_side][right_side] = { 'current': [None for m in this_font.masters], 'recommended': [0.0 for m in this_font.masters], 'base_glyph': None, 'left_glyph': left_glyph.name, } # Use group kerning value as recommended value when it is present if right_glyph and right_glyph.leftKerningKey: group_val = this_font.kerningForPair(master_id, left_side, right_glyph.leftKerningKey) kerning_test_dict[left_side][right_side]['recommended'] = [group_val for m in this_font.masters] # Overwrite the None value with the actual value kerning_test_dict[left_side][right_side]['current'][master_index] = val # If a value is 0, it is interpreted as suspicious and I look into it if val == 0: # So check if the glyph has a left kerning group that is another glyph from the font # Example: Ä has a 0 value but is part of the A group that has a value if right_glyph.leftKerningGroup and this_font.glyphs[right_glyph.leftKerningGroup]: # Get Kerningvalue the baseglyph of the group the (right) glyph was found recommended_value = this_font.kerningForPair(master_id, left_side, this_font.glyphs[right_glyph.leftKerningGroup].leftKerningKey) kerning_test_dict[left_side][right_side]['base_glyph'] = right_glyph.leftKerningGroup if recommended_value < 10000: # it is 9.22337203685e+18 if there is no kerning for kerninggroup ... # ... so only add a recommended value if there is a (realistic) value kerning_test_dict[left_side][right_side]['recommended'][master_index] = recommended_value elif right_glyph.name == right_glyph.leftKerningKey: # Kerning should actually be 0 because glyph is in no group and has itself as kerning key kerning_test_dict[left_side][right_side]['recommended'][master_index] = val else: # Overwrite recommended value with actual value kerning_test_dict[left_side][right_side]['recommended'][master_index] = val
After this I go on with this kerning_test_dict. But I guess you get the picture.
We are currently testing if this catches all problems. So let me know, if you see some issues with this snippet (or if you want to take a look at the whole script).
— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub, or mute the thread.
Hi @axani Filip,
Thanks for the proposal. I cannot wrap my head around the issue, since I still don’t really get the problem. If I don’t know the problem, I have difficulties to seek for / accept a solution. Can you please clarify what your attempt is? If I understand the mechanic, I am happy to merge your code.
Hello,
I have been using Kernschmelze (0.7) recently and came across the following problem: In a 2 master setup I had the same kerning groups in both. One of the masters also included an exception for one glyph that was missing in the other. After “schmelzing” the two, I ended up with an exception in the second master too, but instead of having the standard value of the class, it has the value 0.
Is this on purpose? How would I go about to end up with the correct value in the second master?
Thanks in advance!