Disable implicit text wrapping
This commit is contained in:
+14
-19
@@ -107,31 +107,18 @@ def object_box(obj: dict[str, Any], scale: float) -> tuple[int, int, int, int]:
|
||||
return x, y, max(1, w), max(1, h)
|
||||
|
||||
|
||||
def wrap_text(draw: ImageDraw.ImageDraw, text: str, font, max_width: int) -> list[str]:
|
||||
lines: list[str] = []
|
||||
for raw_line in text.splitlines() or [""]:
|
||||
current = ""
|
||||
for word in raw_line.split(" "):
|
||||
candidate = word if not current else f"{current} {word}"
|
||||
if draw.textbbox((0, 0), candidate, font=font)[2] <= max_width:
|
||||
current = candidate
|
||||
continue
|
||||
if current:
|
||||
lines.append(current)
|
||||
current = word
|
||||
if current:
|
||||
lines.append(current)
|
||||
return lines
|
||||
def text_lines(text: str) -> list[str]:
|
||||
return text.split("\n")
|
||||
|
||||
|
||||
def draw_text(draw: ImageDraw.ImageDraw, obj: dict[str, Any], scale: float) -> None:
|
||||
def draw_text(image: Image.Image, draw: ImageDraw.ImageDraw, obj: dict[str, Any], scale: float) -> None:
|
||||
x, y, w, h = object_box(obj, scale)
|
||||
text = str(obj.get("text", "Text"))
|
||||
font_size = scaled_mm_to_px(float(obj.get("fontSizeMm", 5)), scale)
|
||||
font = get_font(font_size, bool(obj.get("bold", False)))
|
||||
align = obj.get("align", "left")
|
||||
valign = obj.get("valign", "middle")
|
||||
lines = wrap_text(draw, text, font, w)
|
||||
lines = text_lines(text)
|
||||
boxes = [draw.textbbox((0, 0), line, font=font) for line in lines]
|
||||
line_heights = [box[3] - box[1] for box in boxes]
|
||||
gap = max(1, round(font_size * 0.15))
|
||||
@@ -150,7 +137,15 @@ def draw_text(draw: ImageDraw.ImageDraw, obj: dict[str, Any], scale: float) -> N
|
||||
cx = x + w - text_w
|
||||
else:
|
||||
cx = x
|
||||
draw.text((cx, cy - box[1]), line, font=font, fill=1)
|
||||
text_layer = Image.new("1", image.size, 0)
|
||||
text_draw = ImageDraw.Draw(text_layer)
|
||||
text_draw.text((cx, cy - box[1]), line, font=font, fill=1)
|
||||
clip = Image.new("1", image.size, 0)
|
||||
clip_draw = ImageDraw.Draw(clip)
|
||||
clip_draw.rectangle([x, y, x + w, y + h], fill=1)
|
||||
clipped = Image.new("1", image.size, 0)
|
||||
clipped.paste(text_layer, mask=clip)
|
||||
image.paste(1, mask=clipped)
|
||||
cy += line_h + gap
|
||||
|
||||
|
||||
@@ -283,7 +278,7 @@ def render_design_image(design: dict[str, Any]) -> Image.Image:
|
||||
continue
|
||||
obj_type = obj.get("type")
|
||||
if obj_type == "text" or obj_type == "symbol":
|
||||
draw_text(draw, obj, scale)
|
||||
draw_text(image, draw, obj, scale)
|
||||
elif obj_type == "shape":
|
||||
draw_shape(draw, obj, scale)
|
||||
elif obj_type == "line":
|
||||
|
||||
+4
-18
@@ -102,22 +102,8 @@ function clamp(value, min, max) {
|
||||
return Math.min(max, Math.max(min, value));
|
||||
}
|
||||
|
||||
function wrapCanvasText(text, maxWidthPx) {
|
||||
const lines = [];
|
||||
for (const rawLine of String(text || "").split("\n")) {
|
||||
let current = "";
|
||||
for (const word of rawLine.split(" ")) {
|
||||
const candidate = current ? `${current} ${word}` : word;
|
||||
if (ctx.measureText(candidate).width <= maxWidthPx) {
|
||||
current = candidate;
|
||||
continue;
|
||||
}
|
||||
if (current) lines.push(current);
|
||||
current = word;
|
||||
}
|
||||
lines.push(current);
|
||||
}
|
||||
return lines.length ? lines : [""];
|
||||
function canvasTextLines(text) {
|
||||
return String(text || "").split("\n");
|
||||
}
|
||||
|
||||
function textNaturalWidthMm(obj) {
|
||||
@@ -149,7 +135,7 @@ function objectContentEndMm(obj) {
|
||||
const { value } = objectFont(obj);
|
||||
ctx.save();
|
||||
ctx.font = value;
|
||||
const lines = wrapCanvasText(obj.text || "", mmToPx(obj.w));
|
||||
const lines = canvasTextLines(obj.text || "");
|
||||
const textWidthMm = Math.max(...lines.map((line) => pxToMm(ctx.measureText(line).width)), 0);
|
||||
ctx.restore();
|
||||
|
||||
@@ -255,7 +241,7 @@ function drawTextObject(obj) {
|
||||
ctx.font = font;
|
||||
ctx.textBaseline = "middle";
|
||||
ctx.textAlign = obj.align || "left";
|
||||
const lines = wrapCanvasText(obj.text || "", w);
|
||||
const lines = canvasTextLines(obj.text || "");
|
||||
const lineHeight = fontPx * 1.15;
|
||||
const total = lineHeight * lines.length;
|
||||
let cy = y + h / 2 - total / 2 + lineHeight / 2;
|
||||
|
||||
Reference in New Issue
Block a user