Run textUber though computePaths.
|
@ -500,6 +500,60 @@ proc parseSvgFont*(buf: string): Typeface {.raises: [PixieError].} =
|
||||||
result = Typeface()
|
result = Typeface()
|
||||||
result.svgFont = svgfont.parseSvgFont(buf)
|
result.svgFont = svgfont.parseSvgFont(buf)
|
||||||
|
|
||||||
|
|
||||||
|
proc computePaths(
|
||||||
|
arrangement: Arrangement
|
||||||
|
): seq[Path] =
|
||||||
|
## Takes an Arrangement and computes Paths for drawing.
|
||||||
|
## Returns a seq of paths that match the Spans in the arrangement.
|
||||||
|
## If you only have one Span you should only get one Path.
|
||||||
|
var line: int
|
||||||
|
for spanIndex, (start, stop) in arrangement.spans:
|
||||||
|
var spanPath = Path()
|
||||||
|
let
|
||||||
|
font = arrangement.fonts[spanIndex]
|
||||||
|
underlineThickness = font.typeface.underlineThickness * font.scale
|
||||||
|
underlinePosition = font.typeface.underlinePosition * font.scale
|
||||||
|
strikeoutThickness = font.typeface.strikeoutThickness * font.scale
|
||||||
|
strikeoutPosition = font.typeface.strikeoutPosition * font.scale
|
||||||
|
for runeIndex in start .. stop:
|
||||||
|
let position = arrangement.positions[runeIndex]
|
||||||
|
|
||||||
|
let path = font.typeface.getGlyphPath(arrangement.runes[runeIndex])
|
||||||
|
path.transform(
|
||||||
|
translate(position) *
|
||||||
|
scale(vec2(font.scale))
|
||||||
|
)
|
||||||
|
|
||||||
|
var applyDecoration = true
|
||||||
|
if runeIndex == arrangement.lines[line][1]:
|
||||||
|
inc line
|
||||||
|
if arrangement.runes[runeIndex] == SP:
|
||||||
|
# Do not apply decoration to the space at end of lines
|
||||||
|
applyDecoration = false
|
||||||
|
|
||||||
|
if applyDecoration:
|
||||||
|
if font.underline:
|
||||||
|
path.rect(
|
||||||
|
arrangement.selectionRects[runeIndex].x,
|
||||||
|
position.y - underlinePosition + underlineThickness / 2,
|
||||||
|
arrangement.selectionRects[runeIndex].w,
|
||||||
|
underlineThickness,
|
||||||
|
font.typeface.isCCW()
|
||||||
|
)
|
||||||
|
if font.strikethrough:
|
||||||
|
path.rect(
|
||||||
|
arrangement.selectionRects[runeIndex].x,
|
||||||
|
position.y - strikeoutPosition,
|
||||||
|
arrangement.selectionRects[runeIndex].w,
|
||||||
|
strikeoutThickness,
|
||||||
|
font.typeface.isCCW()
|
||||||
|
)
|
||||||
|
|
||||||
|
spanPath.addPath(path)
|
||||||
|
|
||||||
|
result.add(spanPath)
|
||||||
|
|
||||||
proc textUber(
|
proc textUber(
|
||||||
target: Image | Mask,
|
target: Image | Mask,
|
||||||
arrangement: Arrangement,
|
arrangement: Arrangement,
|
||||||
|
@ -512,6 +566,7 @@ proc textUber(
|
||||||
stroke: static[bool] = false
|
stroke: static[bool] = false
|
||||||
) =
|
) =
|
||||||
var line: int
|
var line: int
|
||||||
|
let spanPaths = arrangement.computePaths()
|
||||||
for spanIndex, (start, stop) in arrangement.spans:
|
for spanIndex, (start, stop) in arrangement.spans:
|
||||||
let
|
let
|
||||||
font = arrangement.fonts[spanIndex]
|
font = arrangement.fonts[spanIndex]
|
||||||
|
@ -519,56 +574,15 @@ proc textUber(
|
||||||
underlinePosition = font.typeface.underlinePosition * font.scale
|
underlinePosition = font.typeface.underlinePosition * font.scale
|
||||||
strikeoutThickness = font.typeface.strikeoutThickness * font.scale
|
strikeoutThickness = font.typeface.strikeoutThickness * font.scale
|
||||||
strikeoutPosition = font.typeface.strikeoutPosition * font.scale
|
strikeoutPosition = font.typeface.strikeoutPosition * font.scale
|
||||||
for runeIndex in start .. stop:
|
|
||||||
let position = arrangement.positions[runeIndex]
|
|
||||||
|
|
||||||
let path = font.typeface.getGlyphPath(arrangement.runes[runeIndex])
|
let path = spanPaths[spanIndex]
|
||||||
path.transform(
|
|
||||||
translate(position) *
|
|
||||||
scale(vec2(font.scale))
|
|
||||||
)
|
|
||||||
|
|
||||||
var applyDecoration = true
|
when stroke:
|
||||||
if runeIndex == arrangement.lines[line][1]:
|
when type(target) is Image:
|
||||||
inc line
|
for paint in font.paints:
|
||||||
if arrangement.runes[runeIndex] == SP:
|
|
||||||
# Do not apply decoration to the space at end of lines
|
|
||||||
applyDecoration = false
|
|
||||||
|
|
||||||
if applyDecoration:
|
|
||||||
if font.underline:
|
|
||||||
path.rect(
|
|
||||||
arrangement.selectionRects[runeIndex].x,
|
|
||||||
position.y - underlinePosition + underlineThickness / 2,
|
|
||||||
arrangement.selectionRects[runeIndex].w,
|
|
||||||
underlineThickness,
|
|
||||||
font.typeface.isCCW()
|
|
||||||
)
|
|
||||||
if font.strikethrough:
|
|
||||||
path.rect(
|
|
||||||
arrangement.selectionRects[runeIndex].x,
|
|
||||||
position.y - strikeoutPosition,
|
|
||||||
arrangement.selectionRects[runeIndex].w,
|
|
||||||
strikeoutThickness,
|
|
||||||
font.typeface.isCCW()
|
|
||||||
)
|
|
||||||
|
|
||||||
when stroke:
|
|
||||||
when type(target) is Image:
|
|
||||||
for paint in font.paints:
|
|
||||||
target.strokePath(
|
|
||||||
path,
|
|
||||||
paint,
|
|
||||||
transform,
|
|
||||||
strokeWidth,
|
|
||||||
lineCap,
|
|
||||||
lineJoin,
|
|
||||||
miterLimit,
|
|
||||||
dashes
|
|
||||||
)
|
|
||||||
else: # target is Mask
|
|
||||||
target.strokePath(
|
target.strokePath(
|
||||||
path,
|
path,
|
||||||
|
paint,
|
||||||
transform,
|
transform,
|
||||||
strokeWidth,
|
strokeWidth,
|
||||||
lineCap,
|
lineCap,
|
||||||
|
@ -576,63 +590,31 @@ proc textUber(
|
||||||
miterLimit,
|
miterLimit,
|
||||||
dashes
|
dashes
|
||||||
)
|
)
|
||||||
else:
|
else: # target is Mask
|
||||||
when type(target) is Image:
|
target.strokePath(
|
||||||
for paint in font.paints:
|
path,
|
||||||
target.fillPath(path, paint, transform)
|
transform,
|
||||||
else: # target is Mask
|
strokeWidth,
|
||||||
target.fillPath(path, transform)
|
lineCap,
|
||||||
|
lineJoin,
|
||||||
|
miterLimit,
|
||||||
|
dashes
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
when type(target) is Image:
|
||||||
|
for paint in font.paints:
|
||||||
|
#echo transform
|
||||||
|
target.fillPath(path, paint, transform)
|
||||||
|
else: # target is Mask
|
||||||
|
target.fillPath(path, transform)
|
||||||
|
|
||||||
proc computeBounds*(
|
proc computeBounds*(
|
||||||
arrangement: Arrangement,
|
arrangement: Arrangement,
|
||||||
transform = mat3()
|
transform = mat3()
|
||||||
): Rect =
|
): Rect =
|
||||||
var
|
var fullPath = newPath()
|
||||||
fullPath = newPath()
|
for path in arrangement.computePaths():
|
||||||
line: int
|
fullPath.addPath(path)
|
||||||
for spanIndex, (start, stop) in arrangement.spans:
|
|
||||||
let
|
|
||||||
font = arrangement.fonts[spanIndex]
|
|
||||||
underlineThickness = font.typeface.underlineThickness * font.scale
|
|
||||||
underlinePosition = font.typeface.underlinePosition * font.scale
|
|
||||||
strikeoutThickness = font.typeface.strikeoutThickness * font.scale
|
|
||||||
strikeoutPosition = font.typeface.strikeoutPosition * font.scale
|
|
||||||
for runeIndex in start .. stop:
|
|
||||||
let position = arrangement.positions[runeIndex]
|
|
||||||
|
|
||||||
let path = font.typeface.getGlyphPath(arrangement.runes[runeIndex])
|
|
||||||
path.transform(
|
|
||||||
translate(position) *
|
|
||||||
scale(vec2(font.scale))
|
|
||||||
)
|
|
||||||
|
|
||||||
var applyDecoration = true
|
|
||||||
if runeIndex == arrangement.lines[line][1]:
|
|
||||||
inc line
|
|
||||||
if arrangement.runes[runeIndex] == SP:
|
|
||||||
# Do not apply decoration to the space at end of lines
|
|
||||||
applyDecoration = false
|
|
||||||
|
|
||||||
if applyDecoration:
|
|
||||||
if font.underline:
|
|
||||||
path.rect(
|
|
||||||
arrangement.selectionRects[runeIndex].x,
|
|
||||||
position.y - underlinePosition + underlineThickness / 2,
|
|
||||||
arrangement.selectionRects[runeIndex].w,
|
|
||||||
underlineThickness,
|
|
||||||
font.typeface.isCCW()
|
|
||||||
)
|
|
||||||
if font.strikethrough:
|
|
||||||
path.rect(
|
|
||||||
arrangement.selectionRects[runeIndex].x,
|
|
||||||
position.y - strikeoutPosition,
|
|
||||||
arrangement.selectionRects[runeIndex].w,
|
|
||||||
strikeoutThickness,
|
|
||||||
font.typeface.isCCW()
|
|
||||||
)
|
|
||||||
|
|
||||||
fullPath.addPath(path)
|
|
||||||
|
|
||||||
fullPath.transform(transform)
|
fullPath.transform(transform)
|
||||||
fullPath.computeBounds()
|
fullPath.computeBounds()
|
||||||
|
|
||||||
|
|
Before Width: | Height: | Size: 7.3 KiB After Width: | Height: | Size: 7.3 KiB |
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 20 KiB |
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 20 KiB |
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 19 KiB |
Before Width: | Height: | Size: 72 KiB After Width: | Height: | Size: 72 KiB |
Before Width: | Height: | Size: 73 KiB After Width: | Height: | Size: 73 KiB |
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 20 KiB |
Before Width: | Height: | Size: 72 KiB After Width: | Height: | Size: 72 KiB |
Before Width: | Height: | Size: 72 KiB After Width: | Height: | Size: 72 KiB |
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 20 KiB |
Before Width: | Height: | Size: 72 KiB After Width: | Height: | Size: 72 KiB |
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 22 KiB |
Before Width: | Height: | Size: 84 KiB After Width: | Height: | Size: 84 KiB |
Before Width: | Height: | Size: 85 KiB After Width: | Height: | Size: 85 KiB |
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 22 KiB |
Before Width: | Height: | Size: 84 KiB After Width: | Height: | Size: 84 KiB |
Before Width: | Height: | Size: 85 KiB After Width: | Height: | Size: 85 KiB |
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 14 KiB |
Before Width: | Height: | Size: 8.4 KiB After Width: | Height: | Size: 8.4 KiB |
Before Width: | Height: | Size: 8 KiB After Width: | Height: | Size: 8 KiB |
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 18 KiB |
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 18 KiB |
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 18 KiB |
Before Width: | Height: | Size: 67 KiB After Width: | Height: | Size: 67 KiB |
Before Width: | Height: | Size: 67 KiB After Width: | Height: | Size: 67 KiB |
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 19 KiB |
Before Width: | Height: | Size: 70 KiB After Width: | Height: | Size: 70 KiB |
Before Width: | Height: | Size: 71 KiB After Width: | Height: | Size: 71 KiB |
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 18 KiB |
Before Width: | Height: | Size: 71 KiB After Width: | Height: | Size: 71 KiB |
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 20 KiB |
Before Width: | Height: | Size: 74 KiB After Width: | Height: | Size: 74 KiB |
Before Width: | Height: | Size: 77 KiB After Width: | Height: | Size: 77 KiB |
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 20 KiB |
Before Width: | Height: | Size: 74 KiB After Width: | Height: | Size: 74 KiB |
Before Width: | Height: | Size: 76 KiB After Width: | Height: | Size: 76 KiB |
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 17 KiB |
Before Width: | Height: | Size: 8 KiB After Width: | Height: | Size: 8 KiB |
Before Width: | Height: | Size: 7.8 KiB After Width: | Height: | Size: 7.8 KiB |