Skip to content

Commit 28ca081

Browse files
authored
Merge pull request #2 from morisawa-inc/less-error-prone-interaction
2 parents d575b45 + 3eb4fde commit 28ca081

File tree

4 files changed

+66
-24
lines changed

4 files changed

+66
-24
lines changed
Binary file not shown.
Binary file not shown.

CJKAnchorPlacement.glyphsTool/Contents/Resources/plugin.py

+63-21
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,15 @@
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, NSLeftMouseDown, NSLeftMouseUp, NSMouseMoved, NSLeftMouseDragged
7+
78
from Foundation import NSNotFound, NSNumber, NSMutableDictionary
89
import math
910
import collections
1011
import contextlib
1112

13+
VALID_EVENT_TYPES = (NSLeftMouseDown, NSLeftMouseUp, NSMouseMoved, NSLeftMouseDragged)
14+
1215
@contextlib.contextmanager
1316
def currentGraphicsContext(context=None):
1417
context = context or NSGraphicsContext.currentContext()
@@ -78,6 +81,9 @@ def apply_values_for_anchors(font, master, layer, lsb_value, rsb_value, tsb_valu
7881
else:
7982
delete_anchor(font, master, layer, 'BSB')
8083

84+
def round_to_grid(value, subdivision=1.0):
85+
return int(math.floor(value / subdivision + 0.5)) * subdivision if subdivision else value
86+
8187
def make_gray_color():
8288
return NSColor.colorWithDeviceRed_green_blue_alpha_(0.0 / 256.0, 0.0 / 256.0, 0.0 / 256.0, 0.25)
8389

@@ -87,7 +93,7 @@ def make_magenta_color():
8793
def make_cyan_color():
8894
return NSColor.colorWithDeviceRed_green_blue_alpha_(0.0 / 256.0, 159.0 / 256.0, 227.0 / 256.0, 1.0)
8995

90-
def draw_metrics_rect(font, master, layer, lsb_value, rsb_value, tsb_value, bsb_value):
96+
def draw_metrics_rect(font, master, layer, lsb_value, rsb_value, tsb_value, bsb_value, scale=1.0, dotted=False):
9197
vert_width = layer.vertWidth() if callable(layer.vertWidth) else layer.vertWidth
9298
if vert_width is None:
9399
vert_width = master.ascender - master.descender
@@ -99,8 +105,10 @@ def draw_metrics_rect(font, master, layer, lsb_value, rsb_value, tsb_value, bsb_
99105
y2 = descender + (bsb_value or 0.0)
100106

101107
path = NSBezierPath.bezierPathWithRect_(NSMakeRect(x1, y2, x2 - x1, y1 - y2))
102-
path.setLineWidth_(1.0)
103-
path.stroke()
108+
path.setLineWidth_(1.0 / scale)
109+
if dotted:
110+
path.setLineDash_count_phase_([path.lineWidth() * 3.0, path.lineWidth() * 3.0], 2, 0.0)
111+
path.stroke()
104112

105113
def guess_anchor_direction_and_calc_distance_from_edge(location, master, layer):
106114
vert_width = layer.vertWidth() if callable(layer.vertWidth) else layer.vertWidth
@@ -189,6 +197,9 @@ class CJKAnchorPlacementTool(SelectTool):
189197
@objc.python_method
190198
def start(self):
191199
self.needs_disable_update_anchors = False
200+
self.grid_subdivision = 1.0
201+
self.last_do_kerning = None
202+
self.last_do_spacing = None
192203

193204
@objc.python_method
194205
def settings(self):
@@ -217,14 +228,17 @@ def mouseDoubleDown_(self, event):
217228
font = layer.parent.parent
218229
master = font.masters[layer.associatedMasterId or layer.layerId]
219230
anchor_name, distance_from_edge = guess_anchor_direction_and_calc_distance_from_edge(location, master, layer)
220-
if anchor_name == 'LSB':
221-
self.LSBValue = distance_from_edge
222-
elif anchor_name == 'RSB':
223-
self.RSBValue = distance_from_edge
224-
elif anchor_name == 'TSB':
225-
self.TSBValue = distance_from_edge
226-
elif anchor_name == 'BSB':
227-
self.BSBValue = distance_from_edge
231+
if distance_from_edge > 0.0:
232+
if anchor_name == 'LSB':
233+
self.LSBValue = distance_from_edge
234+
elif anchor_name == 'RSB':
235+
self.RSBValue = distance_from_edge
236+
elif anchor_name == 'TSB':
237+
self.TSBValue = distance_from_edge
238+
elif anchor_name == 'BSB':
239+
self.BSBValue = distance_from_edge
240+
return
241+
objc.super(CJKAnchorPlacementTool, self).mouseDoubleDown_(event)
228242

229243
@LSBValue.setter
230244
def LSBValue(self, value):
@@ -270,41 +284,69 @@ def update_anchors(self):
270284
apply_values_for_anchors(font, master, layer, self.LSBValue, self.RSBValue, self.TSBValue, self.BSBValue)
271285

272286
@objc.python_method
273-
def sync_values(self, font, master, layer):
287+
def sync_values(self, font, master, layer, needs_round=False):
274288
if layer:
275289
lsb_anchor = layer.anchors['LSB'] if layer.anchors else None
276290
rsb_anchor = layer.anchors['RSB'] if layer.anchors else None
277291
tsb_anchor = layer.anchors['TSB'] if layer.anchors else None
278292
bsb_anchor = layer.anchors['BSB'] if layer.anchors else None
279293
self.needs_disable_update_anchors = True
280294
if lsb_anchor:
281-
self.LSBValue = lsb_anchor.position.x
295+
self.LSBValue = round_to_grid(lsb_anchor.position.x, self.grid_subdivision if needs_round else None)
282296
else:
283297
self.LSBValue = None
284298
if rsb_anchor:
285-
self.RSBValue = layer.width - rsb_anchor.position.x
299+
self.RSBValue = round_to_grid(layer.width - rsb_anchor.position.x, self.grid_subdivision if needs_round else None)
286300
else:
287301
self.RSBValue = None
288302
if tsb_anchor and master:
289-
self.TSBValue = master.ascender - tsb_anchor.position.y
303+
self.TSBValue = round_to_grid(master.ascender - tsb_anchor.position.y, self.grid_subdivision if needs_round else None)
290304
else:
291305
self.TSBValue = None
292306
if bsb_anchor and master:
293-
self.BSBValue = -(master.descender - bsb_anchor.position.y)
307+
self.BSBValue = round_to_grid(-(master.descender - bsb_anchor.position.y), self.grid_subdivision if needs_round else None)
294308
else:
295309
self.BSBValue = None
296310
self.needs_disable_update_anchors = False
311+
if needs_round:
312+
self.update_anchors() # feedback if rounding is enabled
313+
314+
@objc.python_method
315+
def update_grid_subdivision(self, event):
316+
if event:
317+
flags = event.modifierFlags()
318+
if flags & NSShiftKeyMask:
319+
self.grid_subdivision = 10.0
320+
if flags & NSAlternateKeyMask:
321+
self.grid_subdivision *= 0.5
322+
else:
323+
self.grid_subdivision = 1.0
324+
else:
325+
self.grid_subdivision = 1.0
297326

298327
@objc.python_method
299328
def background(self, layer):
300329
font = layer.parent.parent
301330
master = font.masters[layer.associatedMasterId or layer.layerId]
302-
331+
event = NSApplication.sharedApplication().currentEvent()
303332
arrange_anchors(font, master, layer)
304-
self.sync_values(font, master, layer)
333+
self.update_grid_subdivision(event)
334+
self.sync_values(font, master, layer, needs_round=event.type() in VALID_EVENT_TYPES if event else False)
305335
with currentGraphicsContext() as ctx:
306-
make_cyan_color().setStroke()
307-
draw_metrics_rect(font, master, layer, self.LSBValue, self.RSBValue, self.TSBValue, self.BSBValue)
336+
dotted = False
337+
has_unbalanced_palt = sum((1 if value is None else 0 for value in (self.LSBValue, self.RSBValue))) == 1
338+
has_unbalanced_vpal = sum((1 if value is None else 0 for value in (self.TSBValue, self.BSBValue))) == 1
339+
if sum((1 if value is None else 0 for value in (self.LSBValue, self.RSBValue, self.TSBValue, self.BSBValue))) == 4:
340+
has_unbalanced_palt, has_unbalanced_vpal = None, None
341+
if has_unbalanced_palt is None and has_unbalanced_vpal is None:
342+
dotted = True
343+
make_cyan_color().setStroke()
344+
elif has_unbalanced_palt or has_unbalanced_vpal:
345+
make_magenta_color().setStroke()
346+
else:
347+
make_cyan_color().setStroke()
348+
scale = self.editViewController().graphicView().scale()
349+
draw_metrics_rect(font, master, layer, self.LSBValue, self.RSBValue, self.TSBValue, self.BSBValue, scale=scale, dotted=dotted)
308350

309351
@objc.python_method
310352
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+
C0dV8JTKRYujsIbGxQoHOHewQvA=
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+
C0dV8JTKRYujsIbGxQoHOHewQvA=
5757
</data>
5858
<key>hash2</key>
5959
<data>
60-
CvStjcnrvn7Sd1Px+wGJPwb33B1IBAbXgEE6TRkVYHY=
60+
ysOzDH+jDFSj+BMCJtqpRUL1K1PJy9DTABx2FfzxClI=
6161
</data>
6262
</dict>
6363
<key>Resources/toolbar.ai</key>

0 commit comments

Comments
 (0)