morepretty

This commit is contained in:
Ryan Oldenburg 2022-01-20 20:09:24 -06:00
parent be57c71c3c
commit a3c2444339
3 changed files with 42 additions and 20 deletions

View file

@ -129,12 +129,11 @@ proc decodePpm*(data: string): Image {.raises: [PixieError].} =
failInvalid() failInvalid()
result = newImage(header.width, header.height) result = newImage(header.width, header.height)
result.data = ( result.data =
if header.version == "P3": if header.version == "P3":
decodeP3Data(data[header.dataOffset .. ^1], header.maxVal) decodeP3Data(data[header.dataOffset .. ^1], header.maxVal)
else: else:
decodeP6Data(data[header.dataOffset .. ^1], header.maxVal) decodeP6Data(data[header.dataOffset .. ^1], header.maxVal)
)
proc encodePpm*(image: Image): string {.raises: [].} = proc encodePpm*(image: Image): string {.raises: [].} =
## Encodes an image into the PPM file format (version P6). ## Encodes an image into the PPM file format (version P6).

View file

@ -2126,7 +2126,9 @@ proc getGlyphId(opentype: OpenType, rune: Rune): uint16 =
proc hasGlyph*(opentype: OpenType, rune: Rune): bool = proc hasGlyph*(opentype: OpenType, rune: Rune): bool =
rune in opentype.cmap.runeToGlyphId rune in opentype.cmap.runeToGlyphId
proc parseGlyfGlyph(opentype: OpenType, glyphId: uint16): Path {.raises: [PixieError], gcsafe.} proc parseGlyfGlyph(
opentype: OpenType, glyphId: uint16
): Path {.raises: [PixieError], gcsafe.}
proc parseGlyphPath( proc parseGlyphPath(
buf: string, offset, numberOfContours: int buf: string, offset, numberOfContours: int

View file

@ -837,27 +837,37 @@ proc drawUber(
when type(a) is Image: when type(a) is Image:
when type(b) is Image: when type(b) is Image:
for q in [0, 4, 8, 12]: for q in [0, 4, 8, 12]:
let sourceVec = mm_loadu_si128(b.data[b.dataIndex(sx + q, sy)].addr) let
if mm_movemask_epi8(mm_cmpeq_epi8(sourceVec, mm_setzero_si128())) != 0xffff: sourceVec = mm_loadu_si128(b.data[b.dataIndex(sx + q, sy)].addr)
if (mm_movemask_epi8(mm_cmpeq_epi8(sourceVec, vec255)) and 0x8888) == 0x8888: eqZer0 = mm_cmpeq_epi8(sourceVec, mm_setzero_si128())
if mm_movemask_epi8(eqZer0) != 0xffff:
let eq255 = mm_cmpeq_epi8(sourceVec, vec255)
if (mm_movemask_epi8(eq255) and 0x8888) == 0x8888:
mm_storeu_si128(a.data[a.dataIndex(x + q, y)].addr, sourceVec) mm_storeu_si128(a.data[a.dataIndex(x + q, y)].addr, sourceVec)
else: else:
let backdropVec = mm_loadu_si128(a.data[a.dataIndex(x + q, y)].addr) let
backdropIdx = a.dataIndex(x + q, y)
backdropVec = mm_loadu_si128(a.data[backdropIdx].addr)
mm_storeu_si128( mm_storeu_si128(
a.data[a.dataIndex(x + q, y)].addr, a.data[backdropIdx].addr,
blendNormalInlineSimd(backdropVec, sourceVec) blendNormalInlineSimd(backdropVec, sourceVec)
) )
else: # b is a Mask else: # b is a Mask
var values = mm_loadu_si128(b.data[b.dataIndex(sx, sy)].addr) var values = mm_loadu_si128(b.data[b.dataIndex(sx, sy)].addr)
for q in [0, 4, 8, 12]: for q in [0, 4, 8, 12]:
let sourceVec = unpackAlphaValues(values) let
if mm_movemask_epi8(mm_cmpeq_epi8(sourceVec, mm_setzero_si128())) != 0xffff: sourceVec = unpackAlphaValues(values)
if (mm_movemask_epi8(mm_cmpeq_epi8(sourceVec, vec255)) and 0x8888) == 0x8888: eqZer0 = mm_cmpeq_epi8(sourceVec, mm_setzero_si128())
if mm_movemask_epi8(eqZer0) != 0xffff:
let eq255 = mm_cmpeq_epi8(sourceVec, vec255)
if (mm_movemask_epi8(eq255) and 0x8888) == 0x8888:
discard discard
else: else:
let backdropVec = mm_loadu_si128(a.data[a.dataIndex(x + q, y)].addr) let
backdropIdx = a.dataIndex(x + q, y)
backdropVec = mm_loadu_si128(a.data[backdropIdx].addr)
mm_storeu_si128( mm_storeu_si128(
a.data[a.dataIndex(x + q, y)].addr, a.data[backdropIdx].addr,
blendNormalInlineSimd(backdropVec, sourceVec) blendNormalInlineSimd(backdropVec, sourceVec)
) )
# Shuffle 32 bits off for the next iteration # Shuffle 32 bits off for the next iteration
@ -885,9 +895,14 @@ proc drawUber(
when type(a) is Image: when type(a) is Image:
when type(b) is Image: when type(b) is Image:
for q in [0, 4, 8, 12]: for q in [0, 4, 8, 12]:
let sourceVec = mm_loadu_si128(b.data[b.dataIndex(sx + q, sy)].addr) let
if mm_movemask_epi8(mm_cmpeq_epi8(sourceVec, mm_setzero_si128())) == 0xffff: sourceVec = mm_loadu_si128(b.data[b.dataIndex(sx + q, sy)].addr)
mm_storeu_si128(a.data[a.dataIndex(x + q, y)].addr, mm_setzero_si128()) eqZer0 = mm_cmpeq_epi8(sourceVec, mm_setzero_si128())
if mm_movemask_epi8(eqZer0) == 0xffff:
mm_storeu_si128(
a.data[a.dataIndex(x + q, y)].addr,
mm_setzero_si128()
)
elif mm_movemask_epi8(mm_cmpeq_epi8(sourceVec, vec255)) != 0xffff: elif mm_movemask_epi8(mm_cmpeq_epi8(sourceVec, vec255)) != 0xffff:
let backdropVec = mm_loadu_si128(a.data[a.dataIndex(x + q, y)].addr) let backdropVec = mm_loadu_si128(a.data[a.dataIndex(x + q, y)].addr)
mm_storeu_si128( mm_storeu_si128(
@ -897,10 +912,16 @@ proc drawUber(
else: # b is a Mask else: # b is a Mask
var values = mm_loadu_si128(b.data[b.dataIndex(sx, sy)].addr) var values = mm_loadu_si128(b.data[b.dataIndex(sx, sy)].addr)
for q in [0, 4, 8, 12]: for q in [0, 4, 8, 12]:
let sourceVec = unpackAlphaValues(values) let
if mm_movemask_epi8(mm_cmpeq_epi8(sourceVec, mm_setzero_si128())) == 0xffff: sourceVec = unpackAlphaValues(values)
mm_storeu_si128(a.data[a.dataIndex(x + q, y)].addr, mm_setzero_si128()) eqZer0 = mm_cmpeq_epi8(sourceVec, mm_setzero_si128())
elif (mm_movemask_epi8(mm_cmpeq_epi8(sourceVec, vec255)) and 0x8888) != 0x8888: eq255 = mm_cmpeq_epi8(sourceVec, vec255)
if mm_movemask_epi8(eqZer0) == 0xffff:
mm_storeu_si128(
a.data[a.dataIndex(x + q, y)].addr,
mm_setzero_si128()
)
elif (mm_movemask_epi8(eq255) and 0x8888) != 0x8888:
let backdropVec = mm_loadu_si128(a.data[a.dataIndex(x + q, y)].addr) let backdropVec = mm_loadu_si128(a.data[a.dataIndex(x + q, y)].addr)
mm_storeu_si128( mm_storeu_si128(
a.data[a.dataIndex(x + q, y)].addr, a.data[a.dataIndex(x + q, y)].addr,