Map textFontStyle=1 (faux bold) to PSD

- TypeLayer mode: StyleSheetData.FauxBold=true for bold text layers
- Rasterized mode: render with stroke width for faux bold
Verified: 50/54 text layers get FauxBold, stroke rendering thickens glyphs.
This commit is contained in:
AskaEth committed 2026-08-27 10:49:57 +08:00
1 parent c6a24a4fdb
commit 39c27504d4
1 file changed
+13 -4
+13 -4
View File
@@ -38,7 +38,8 @@ except ImportError: # pragma: no cover
# Optional TypeLayer (editable text) support
try:
from psd_tools.psd.tagged_blocks import TypeToolObjectSetting
from psd_tools.psd.engine_data import (String, Float, Integer, Dict, List)
from psd_tools.psd.engine_data import (String, Float, Integer, Bool,
Dict, List)
_TYSHA = True
except ImportError: # pragma: no cover
_TYSHA = False
@@ -331,13 +332,17 @@ def render_text(ly: dict, cw: int, ch: int) -> Optional[Tuple[Image.Image, Tuple
th = len(lines) * line_h + size * 0.25 # slack so the last line never clips
# --- render at natural size, centered on the layer box ---
raw_w, raw_h = max(1, int(round(tw))), max(1, int(round(th)))
# faux bold (textFontStyle=1) via stroke width
stroke_w = max(1, int(size / 40)) if ly.get("textFontStyle") == "1" else 0
pad = stroke_w # room for the stroke so glyphs don't clip
raw_w, raw_h = max(1, int(round(tw)) + 2 * pad), max(1, int(round(th)) + 2 * pad)
img = Image.new("RGBA", (raw_w, raw_h), (0, 0, 0, 0))
draw = ImageDraw.Draw(img)
for i, ln in enumerate(lines):
x = 0
x = pad
for ch_ in ln:
draw.text((x, int(round(i * line_h))), ch_, font=font, fill=fill)
draw.text((x, pad + int(round(i * line_h))), ch_, font=font,
fill=fill, stroke_width=stroke_w, stroke_fill=fill)
x += char_advance(ch_) + ls
# center on the boundingRect. Narrow-profile fonts (Source Han
@@ -512,6 +517,10 @@ def build_type_layer_tysh(ly: dict, font_ps: str) -> bytes:
Float(b / 255.0), Float(a / 255.0)])
ssd["FillColor"] = fc
# bold / italic (textFontStyle: 1 = faux bold)
if ly.get("textFontStyle") == "1":
ssd["FauxBold"] = Bool(True)
res["FontSet"][0]["Name"] = String(font_ps)
l, t, rr, bb = bounding_rect(ly)