Skip to content

Commit 0545a28

Browse files
committed
Fix the bevel of Saga creatures' bottom textbox in Borderless Enhanced template
1 parent f724938 commit 0545a28

3 files changed

Lines changed: 129 additions & 11 deletions

File tree

py/utils/layer_fx.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
from typing import TypedDict
2+
3+
from photoshop.api import ActionDescriptor, ActionReference
4+
from photoshop.api._artlayer import ArtLayer
5+
from photoshop.api._layerSet import LayerSet
6+
7+
from src import APP
8+
9+
sID, cID = APP.stringIDToTypeID, APP.charIDToTypeID
10+
11+
12+
class StrokeDetails(TypedDict):
13+
size: int
14+
15+
16+
def get_stroke_details(layer: ArtLayer | LayerSet) -> StrokeDetails | None:
17+
APP.activeDocument.activeLayer = layer
18+
19+
ref = ActionReference()
20+
ref.putEnumerated(cID("Lyr "), cID("Ordn"), cID("Trgt"))
21+
desc: ActionDescriptor = APP.executeActionGet(ref)
22+
23+
layer_effects_id = sID("layerEffects")
24+
if not desc.hasKey(layer_effects_id):
25+
return
26+
27+
layer_effects: ActionDescriptor = desc.getObjectValue(layer_effects_id)
28+
29+
frame_fx_id = sID("frameFX")
30+
if not layer_effects.hasKey(frame_fx_id):
31+
return
32+
33+
frame_fx: ActionDescriptor = layer_effects.getObjectValue(frame_fx_id)
34+
35+
return {"size": frame_fx.getInteger(sID("size"))}

py/utils/mask.py

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
from typing import Iterable
2+
3+
from photoshop.api import ElementPlacement, RasterizeType
4+
from photoshop.api._artlayer import ArtLayer
5+
from photoshop.api._layerSet import LayerSet
6+
7+
from src import APP
8+
from src.helpers.adjustments import create_color_layer
9+
from src.helpers.colors import rgb_white
10+
from src.helpers.layers import merge_layers
11+
from src.helpers.masks import create_mask, enter_mask_channel, enter_rgb_channel
12+
from src.helpers.selection import select_canvas
13+
14+
from ..helpers import copy, paste
15+
16+
17+
# TODO fix the original function in Proxyshop
18+
def copy_to_mask(
19+
target: ArtLayer | LayerSet,
20+
source: ArtLayer | LayerSet | None = None,
21+
):
22+
docref = APP.activeDocument
23+
if source:
24+
docref.activeLayer = source
25+
docsel = docref.selection
26+
select_canvas(docref)
27+
copy()
28+
docsel.deselect()
29+
30+
docref.activeLayer = target
31+
create_mask()
32+
enter_mask_channel()
33+
# The pasting threw an error in the original function for some reason
34+
# even though the operation succeeded in Photoshop
35+
paste()
36+
enter_rgb_channel()
37+
38+
39+
def create_mask_from(apply_to: ArtLayer | LayerSet, layers: Iterable[ArtLayer]) -> None:
40+
background = create_color_layer(rgb_white(), clipped=False)
41+
layers_to_merge: list[ArtLayer] = [background]
42+
for layer in layers:
43+
duplicate = layer.duplicate(background, ElementPlacement.PlaceBefore)
44+
duplicate.visible = True
45+
layers_to_merge.append(duplicate)
46+
merged = merge_layers(layers_to_merge)
47+
merged.rasterize(RasterizeType.EntireLayer)
48+
copy_to_mask(apply_to, merged)
49+
merged.remove()

py/vertical_mod.py

Lines changed: 45 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
from src.utils.adobe import LayerObjectTypes, ReferenceLayer
2020

2121
from .helpers import LAYER_NAMES, get_numeric_setting
22+
from .utils.layer_fx import get_stroke_details
23+
from .utils.mask import create_mask_from
2224
from .utils.path import create_shape_layer, get_shape_dimensions
2325
from .uxp.shape import ShapeOperation, merge_shapes
2426
from .uxp.text import create_text_layer_with_path
@@ -112,16 +114,33 @@ def load_expansion_symbol(self) -> None:
112114

113115
def create_shapes_for_vertical_creature(self) -> None:
114116
if ref_textbox := getLayer(LAYERS.TALL, (self.textbox_group, LAYERS.SHAPE)):
117+
pinlines_stroke = (
118+
get_stroke_details(self.pinlines_group) if self.pinlines_group else None
119+
)
120+
pinlines_stroke_size = pinlines_stroke["size"] if pinlines_stroke else 0
115121
ref_textbox_dims = get_shape_dimensions(ref_textbox)
116-
textbox_top = ref_textbox_dims["bottom"] - self.textbox_height
122+
textbox_bottom = ref_textbox_dims["bottom"] - pinlines_stroke_size
123+
textbox_top = textbox_bottom - self.textbox_height
117124

118125
# Build bottom textbox
119126
self.bottom_textbox_shape = create_shape_layer(
120127
(
121-
{"x": ref_textbox_dims["left"], "y": textbox_top},
122-
{"x": ref_textbox_dims["right"], "y": textbox_top},
123-
{"x": ref_textbox_dims["right"], "y": ref_textbox_dims["bottom"]},
124-
{"x": ref_textbox_dims["left"], "y": ref_textbox_dims["bottom"]},
128+
{
129+
"x": ref_textbox_dims["left"] + pinlines_stroke_size,
130+
"y": textbox_top,
131+
},
132+
{
133+
"x": ref_textbox_dims["right"] - pinlines_stroke_size,
134+
"y": textbox_top,
135+
},
136+
{
137+
"x": ref_textbox_dims["right"] - pinlines_stroke_size,
138+
"y": textbox_bottom,
139+
},
140+
{
141+
"x": ref_textbox_dims["left"] + pinlines_stroke_size,
142+
"y": textbox_bottom,
143+
},
125144
),
126145
relative_layer=ref_textbox,
127146
placement=ElementPlacement.PlaceAfter,
@@ -153,6 +172,7 @@ def create_shapes_for_vertical_creature(self) -> None:
153172
pinlines_top = (
154173
ref_textbox_pinlines_dims["bottom"]
155174
- self.textbox_height
175+
- 2 * pinlines_stroke_size
156176
- (ref_textbox_pinlines_dims["height"] - ref_textbox_dims["height"])
157177
)
158178

@@ -559,13 +579,15 @@ def textbox_positioning(self) -> None:
559579
if (
560580
self.has_extra_textbox
561581
and (
562-
ref_textbox_tall := getLayer(LAYERS.TALL, self.textbox_reference_group)
582+
ref_textbox_pinlines := getLayer(
583+
LAYERS.TALL, (self.pinlines_group, LAYERS.SHAPE, LAYERS.TEXTBOX)
584+
)
563585
)
564-
and self.textbox_bottom_reference
586+
and self.bottom_textbox_pinlines_shape
565587
):
566588
delta = (
567-
get_shape_dimensions(self.textbox_bottom_reference)["top"]
568-
- get_shape_dimensions(ref_textbox_tall)["top"]
589+
get_shape_dimensions(self.bottom_textbox_pinlines_shape)["top"]
590+
- get_shape_dimensions(ref_textbox_pinlines)["top"]
569591
)
570592

571593
# Shift typeline text
@@ -577,8 +599,20 @@ def textbox_positioning(self) -> None:
577599
self.typeline_pinline_shape.translate(0, delta)
578600

579601
# Shift typeline box
580-
if isinstance(self.twins_shape, list):
581-
self.twins_shape[1].translate(0, delta)
602+
if isinstance(self.twins_shape, list) and isinstance(
603+
(typeline_box := self.twins_shape[1]), ArtLayer
604+
):
605+
typeline_box.translate(0, delta)
606+
607+
# Create mask for pinlines
608+
if (
609+
isinstance((name_box := self.twins_shape[0]), ArtLayer)
610+
and self.bottom_textbox_shape
611+
):
612+
create_mask_from(
613+
self.pinlines_group,
614+
(name_box, typeline_box, self.bottom_textbox_shape),
615+
)
582616

583617
# Shift expansion symbol
584618
if CFG.symbol_enabled and self.expansion_symbol_layer:

0 commit comments

Comments
 (0)