Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
75 changes: 62 additions & 13 deletions l0/ASSFoundation/Section/Text.moon
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,10 @@ return (ASS, ASSFInst, yutilsMissingMsg, createASSClass, Functional, LineCollect
TextSection.getTextExtents = =>
return aegisub.text_extents @getStyleTable!, @value

TextSection.getTextMetrics = (calculateBounds) =>
TextSection.getTextMetrics = (calculateBounds, text = @value) =>
logger\assert Yutils, yutilsMissingMsg
fontObj, tagList = @getYutilsFont!
extents = fontObj.text_extents @value
extents = fontObj.text_extents text
metrics = fontObj.metrics!

-- make sure we convert uint64 (returned from ffi) to lua numbers here
Expand All @@ -50,21 +50,70 @@ return (ASS, ASSFInst, yutilsMissingMsg, createASSClass, Functional, LineCollect

local shape
if calculateBounds
shape = fontObj.text_to_shape @value
shape = fontObj.text_to_shape text
metrics.bounds = {Yutils.shape.bounding shape}
metrics.bounds.w = (metrics.bounds[3] or 0) - (metrics.bounds[1] or 0)
metrics.bounds.h = (metrics.bounds[4] or 0) - (metrics.bounds[2] or 0)

return metrics, tagList, shape

TextSection.getShape = (applyRotation = false) =>
metrics, tagList, shape = @getTextMetrics true
drawing, align = ASS.Draw.DrawingBase{str: shape}
align = tagList.tags.align\getSet!

with metrics -- fix position based on aligment
drawing\sub not align.left and (.width - .bounds.w) / (align.centerH and 2 or 1) or 0,
not align.top and (.height - .bounds.h) / (align.centerV and 2 or 1) or 0
TextSection.getShape = (applyRotation = false, applyScale = false) =>
tagList = @getEffectiveTags true, true, false
fs = tagList.tags.fontsize\getTagParams!
fscy = tagList.tags.scale_y\getTagParams!
align = tagList.tags.align\getSet!

-- Calculate the vertical offset for each line seperated by linebreak
_, breakCount = @value\gsub "\\N", ""
breakCount += 1
verticalOffset = (fs * fscy) / 100
offsetTable = [ (i-1)*verticalOffset for i = 1, breakCount ]

shape, longestWidth, xAlignOffset, metrics = "", 0, 0
sec = Functional.string.split @value, "\\N"
for i, text in ipairs sec
metrics, _, tempShape = @getTextMetrics true, text
drawing = ASS.Draw.DrawingBase{str: tempShape}

local xOffset, yOffset
-- Reconstruct the shape with proper vertical offset for each line
if align.bottom
yOffset = offsetTable[breakCount - i + 1]
elseif align.top
yOffset = offsetTable[i] * (-1)
else
yOffset = (offsetTable[breakCount - i + 1] - offsetTable[i])/2

-- Reconstruct the shape with proper horizontal offset for each line
-- However, this constructed shape will be offseted by the width or half of width (depending on alignment) of the longest line
-- So the whole shape will later have to be offseted by that amount
if align.left
xOffset = 0
longestWidth = 0
elseif align.right
xOffset = metrics.width
if xOffset > longestWidth
longestWidth = xOffset
xAlignOffset = metrics.bounds.w
else
xOffset = (metrics.width)/2
if xOffset > longestWidth
longestWidth = xOffset
xAlignOffset = metrics.bounds.w/2
drawing\sub xOffset, yOffset
shape ..= "#{drawing\getTagParams!} "

drawing = ASS.Draw.DrawingBase{str: shape}
with metrics
.bounds = { Yutils.shape.bounding shape}
.bounds.h = (.bounds[4] or 0) - (.bounds[2] or 0)
drawing\sub (-1) * xAlignOffset, not align.top and (.height - .bounds.h) / (align.centerV and 2 or 1) or 0

-- Scale the drawings based on fscx and fscy values
if applyScale
facX = 100/tagList.tags.scale_x\getTagParams!
facY = 100/tagList.tags.scale_y\getTagParams!
drawing\mul facX, facY

-- rotate shape
if applyRotation
Expand All @@ -73,8 +122,8 @@ return (ASS, ASSFInst, yutilsMissingMsg, createASSClass, Functional, LineCollect

return drawing

TextSection.convertToDrawing = (applyRotation) =>
shape = @getShape(applyRotation)
TextSection.convertToDrawing = =>
shape = @getShape false, true
@value, @contours, @scale = nil, shape.contours, shape.scale
setmetatable @, ASS.Section.Drawing
return @
Expand Down