Skip to content

Commit 28b7ba6

Browse files
committed
Improve behavior to be less error-prone
- paints border in magenta when anchors are incomplete - border becomes dotted when there are no anchors - don't place anchors when double-clicked outside current glyph - press shift to place anchors by 10 units - press shift + option to place anchors by 5 units - update i386 binary using vtool to be notarized without rejection
1 parent d20fa70 commit 28b7ba6

File tree

4 files changed

+65
-25
lines changed

4 files changed

+65
-25
lines changed
Binary file not shown.
Binary file not shown.

CJKAnchorPlacement.glyphsTool/Contents/Resources/plugin.py

+62-22
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import objc
44
from GlyphsApp import *
55
from GlyphsApp.plugins import *
6-
from AppKit import NSGraphicsContext, NSColor, NSMakeRect, NSInsetRect, NSMakePoint, NSAlternateKeyMask, NSBeep, NSNumberFormatter, NSValueTransformer
6+
from AppKit import NSApplication, NSGraphicsContext, NSColor, NSMakeRect, NSInsetRect, NSMakePoint, NSAlternateKeyMask, NSBeep, NSNumberFormatter, NSValueTransformer, NSEventTypeLeftMouseDown, NSEventTypeLeftMouseDragged, NSEventTypeMouseMoved, NSEventTypeLeftMouseUp, NSEventTypePressure, NSEventTypeTabletPoint
77
from Foundation import NSNotFound, NSNumber, NSMutableDictionary
88
import math
99
import collections
@@ -78,6 +78,9 @@ def apply_values_for_anchors(font, master, layer, lsb_value, rsb_value, tsb_valu
7878
else:
7979
delete_anchor(font, master, layer, 'BSB')
8080

81+
def round_to_grid(value, subdivision=1.0):
82+
return int(math.floor(value / subdivision + 0.5)) * subdivision if subdivision else value
83+
8184
def make_gray_color():
8285
return NSColor.colorWithDeviceRed_green_blue_alpha_(0.0 / 256.0, 0.0 / 256.0, 0.0 / 256.0, 0.25)
8386

@@ -87,7 +90,7 @@ def make_magenta_color():
8790
def make_cyan_color():
8891
return NSColor.colorWithDeviceRed_green_blue_alpha_(0.0 / 256.0, 159.0 / 256.0, 227.0 / 256.0, 1.0)
8992

90-
def draw_metrics_rect(font, master, layer, lsb_value, rsb_value, tsb_value, bsb_value):
93+
def draw_metrics_rect(font, master, layer, lsb_value, rsb_value, tsb_value, bsb_value, scale=1.0, dotted=False):
9194
vert_width = layer.vertWidth() if callable(layer.vertWidth) else layer.vertWidth
9295
if vert_width is None:
9396
vert_width = master.ascender - master.descender
@@ -99,8 +102,10 @@ def draw_metrics_rect(font, master, layer, lsb_value, rsb_value, tsb_value, bsb_
99102
y2 = descender + (bsb_value or 0.0)
100103

101104
path = NSBezierPath.bezierPathWithRect_(NSMakeRect(x1, y2, x2 - x1, y1 - y2))
102-
path.setLineWidth_(1.0)
103-
path.stroke()
105+
path.setLineWidth_(1.0 / scale)
106+
if dotted:
107+
path.setLineDash_count_phase_([path.lineWidth() * 3.0, path.lineWidth() * 3.0], 2, 0.0)
108+
path.stroke()
104109

105110
def guess_anchor_direction_and_calc_distance_from_edge(location, master, layer):
106111
vert_width = layer.vertWidth() if callable(layer.vertWidth) else layer.vertWidth
@@ -188,6 +193,9 @@ class CJKAnchorPlacementTool(SelectTool):
188193
@objc.python_method
189194
def start(self):
190195
self.needs_disable_update_anchors = False
196+
self.grid_subdivision = 1.0
197+
self.last_do_kerning = None
198+
self.last_do_spacing = None
191199

192200
@objc.python_method
193201
def settings(self):
@@ -212,15 +220,18 @@ def mouseDoubleDown_(self, event):
212220
font = layer.parent.parent
213221
master = font.masters[layer.associatedMasterId or layer.layerId]
214222
anchor_name, distance_from_edge = guess_anchor_direction_and_calc_distance_from_edge(location, master, layer)
215-
if anchor_name == 'LSB':
216-
self.LSBValue = distance_from_edge
217-
elif anchor_name == 'RSB':
218-
self.RSBValue = distance_from_edge
219-
elif anchor_name == 'TSB':
220-
self.TSBValue = distance_from_edge
221-
elif anchor_name == 'BSB':
222-
self.BSBValue = distance_from_edge
223-
223+
if distance_from_edge > 0.0:
224+
if anchor_name == 'LSB':
225+
self.LSBValue = distance_from_edge
226+
elif anchor_name == 'RSB':
227+
self.RSBValue = distance_from_edge
228+
elif anchor_name == 'TSB':
229+
self.TSBValue = distance_from_edge
230+
elif anchor_name == 'BSB':
231+
self.BSBValue = distance_from_edge
232+
return
233+
super(CJKAnchorPlacementTool, self).mouseDoubleDown_(event)
234+
224235
@LSBValue.setter
225236
def LSBValue(self, value):
226237
if self._LSBValue != value:
@@ -265,41 +276,70 @@ def update_anchors(self):
265276
apply_values_for_anchors(font, master, layer, self.LSBValue, self.RSBValue, self.TSBValue, self.BSBValue)
266277

267278
@objc.python_method
268-
def sync_values(self, font, master, layer):
279+
def sync_values(self, font, master, layer, needs_round=False):
269280
if layer:
270281
lsb_anchor = layer.anchors['LSB'] if layer.anchors else None
271282
rsb_anchor = layer.anchors['RSB'] if layer.anchors else None
272283
tsb_anchor = layer.anchors['TSB'] if layer.anchors else None
273284
bsb_anchor = layer.anchors['BSB'] if layer.anchors else None
274285
self.needs_disable_update_anchors = True
275286
if lsb_anchor:
276-
self.LSBValue = lsb_anchor.position.x
287+
self.LSBValue = round_to_grid(lsb_anchor.position.x, self.grid_subdivision if needs_round else None)
277288
else:
278289
self.LSBValue = None
279290
if rsb_anchor:
280-
self.RSBValue = layer.width - rsb_anchor.position.x
291+
self.RSBValue = round_to_grid(layer.width - rsb_anchor.position.x, self.grid_subdivision if needs_round else None)
281292
else:
282293
self.RSBValue = None
283294
if tsb_anchor and master:
284-
self.TSBValue = master.ascender - tsb_anchor.position.y
295+
self.TSBValue = round_to_grid(master.ascender - tsb_anchor.position.y, self.grid_subdivision if needs_round else None)
285296
else:
286297
self.TSBValue = None
287298
if bsb_anchor and master:
288-
self.BSBValue = -(master.descender - bsb_anchor.position.y)
299+
self.BSBValue = round_to_grid(-(master.descender - bsb_anchor.position.y), self.grid_subdivision if needs_round else None)
289300
else:
290301
self.BSBValue = None
291302
self.needs_disable_update_anchors = False
303+
if needs_round:
304+
self.update_anchors() # feedback if rounding is enabled
305+
306+
@objc.python_method
307+
def update_grid_subdivision(self, event):
308+
if event:
309+
flags = event.modifierFlags()
310+
if flags & NSShiftKeyMask:
311+
self.grid_subdivision = 10.0
312+
if flags & NSAlternateKeyMask:
313+
self.grid_subdivision *= 0.5
314+
else:
315+
self.grid_subdivision = 1.0
316+
else:
317+
self.grid_subdivision = 1.0
292318

293319
@objc.python_method
294320
def background(self, layer):
295321
font = layer.parent.parent
296322
master = font.masters[layer.associatedMasterId or layer.layerId]
297-
323+
event = NSApplication.sharedApplication().currentEvent()
324+
valid_event_types = (NSEventTypeLeftMouseDragged, NSEventTypeMouseMoved, NSEventTypeLeftMouseUp, NSEventTypePressure, NSEventTypeTabletPoint)
298325
arrange_anchors(font, master, layer)
299-
self.sync_values(font, master, layer)
326+
self.update_grid_subdivision(event)
327+
self.sync_values(font, master, layer, needs_round=event.type() in valid_event_types if event else False)
300328
with currentGraphicsContext() as ctx:
301-
make_cyan_color().setStroke()
302-
draw_metrics_rect(font, master, layer, self.LSBValue, self.RSBValue, self.TSBValue, self.BSBValue)
329+
dotted = False
330+
has_unbalanced_palt = sum((1 if value is None else 0 for value in (self.LSBValue, self.RSBValue))) == 1
331+
has_unbalanced_vpal = sum((1 if value is None else 0 for value in (self.TSBValue, self.BSBValue))) == 1
332+
if sum((1 if value is None else 0 for value in (self.LSBValue, self.RSBValue, self.TSBValue, self.BSBValue))) == 4:
333+
has_unbalanced_palt, has_unbalanced_vpal = None, None
334+
if has_unbalanced_palt is None and has_unbalanced_vpal is None:
335+
dotted = True
336+
make_cyan_color().setStroke()
337+
elif has_unbalanced_palt or has_unbalanced_vpal:
338+
make_magenta_color().setStroke()
339+
else:
340+
make_cyan_color().setStroke()
341+
scale = self.editViewController().graphicView().scale()
342+
draw_metrics_rect(font, master, layer, self.LSBValue, self.RSBValue, self.TSBValue, self.BSBValue, scale=scale, dotted=dotted)
303343

304344
@objc.python_method
305345
def __file__(self):

CJKAnchorPlacement.glyphsTool/Contents/_CodeSignature/CodeResources

+3-3
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
</data>
1515
<key>Resources/plugin.py</key>
1616
<data>
17-
6IQQ0XAU5v0Q93/ZX866dC5b6OU=
17+
KIJgddwP2E0BZMyWXnUB+520KmE=
1818
</data>
1919
<key>Resources/toolbar.ai</key>
2020
<data>
@@ -53,11 +53,11 @@
5353
<dict>
5454
<key>hash</key>
5555
<data>
56-
6IQQ0XAU5v0Q93/ZX866dC5b6OU=
56+
KIJgddwP2E0BZMyWXnUB+520KmE=
5757
</data>
5858
<key>hash2</key>
5959
<data>
60-
CvStjcnrvn7Sd1Px+wGJPwb33B1IBAbXgEE6TRkVYHY=
60+
FzufauSDJm/r2jgE6MgqxCnnGYSnk810dqKntpEMoKY=
6161
</data>
6262
</dict>
6363
<key>Resources/toolbar.ai</key>

0 commit comments

Comments
 (0)