General code style clean up for vendor:nanovg

This commit is contained in:
gingerBill
2023-06-28 11:57:37 +01:00
parent 9e9f3c485b
commit ebed66d4ce
+93 -131
View File
@@ -311,7 +311,7 @@ CreateInternal :: proc(params: Params) -> (ctx: ^Context) {
// handle to the image needs to be set to the new generated texture // handle to the image needs to be set to the new generated texture
ctx.fs.callbackResize = proc(data: rawptr, w, h: int) { ctx.fs.callbackResize = proc(data: rawptr, w, h: int) {
ctx := cast(^Context) data ctx := (^Context)(data)
ctx.fontImages[0] = ctx.params.renderCreateTexture(ctx.params.userPtr, .Alpha, w, h, {}, ctx.fs.textureData) ctx.fontImages[0] = ctx.params.renderCreateTexture(ctx.params.userPtr, .Alpha, w, h, {}, ctx.fs.textureData)
} }
@@ -326,7 +326,7 @@ DeleteInternal :: proc(ctx: ^Context) {
__deletePathCache(ctx.cache) __deletePathCache(ctx.cache)
fontstash.Destroy(&ctx.fs) fontstash.Destroy(&ctx.fs)
for &image in ctx.fontImages { for image in ctx.fontImages {
if image != 0 { if image != 0 {
DeleteImage(ctx, image) DeleteImage(ctx, image)
} }
@@ -454,7 +454,7 @@ RGBA :: proc(r, g, b, a: u8) -> (res: Color) {
LerpRGBA :: proc(c0, c1: Color, u: f32) -> (cint: Color) { LerpRGBA :: proc(c0, c1: Color, u: f32) -> (cint: Color) {
clamped := clamp(u, 0.0, 1.0) clamped := clamp(u, 0.0, 1.0)
oneminu := 1.0 - clamped oneminu := 1.0 - clamped
for i in 0..<4 { for _, i in cint {
cint[i] = c0[i] * oneminu + c1[i] * clamped cint[i] = c0[i] * oneminu + c1[i] * clamped
} }
@@ -510,12 +510,9 @@ HSLA :: proc(hue, saturation, lightness: f32, a: u8) -> (col: Color) {
// hex to 0xAARRGGBB color // hex to 0xAARRGGBB color
ColorHex :: proc(color: u32) -> (res: Color) { ColorHex :: proc(color: u32) -> (res: Color) {
color := color color := color
res.b = f32(0x000000FF & color) / 255 res.b = f32(0x000000FF & color) / 255; color >>= 8
color = color >> 8 res.g = f32(0x000000FF & color) / 255; color >>= 8
res.g = f32(0x000000FF & color) / 255 res.r = f32(0x000000FF & color) / 255; color >>= 8
color = color >> 8
res.r = f32(0x000000FF & color) / 255
color = color >> 8
res.a = f32(0x000000FF & color) / 255 res.a = f32(0x000000FF & color) / 255
return return
} }
@@ -874,10 +871,10 @@ Scale :: proc(ctx: ^Context, x, y: f32) {
There should be space for 6 floats in the return buffer for the values a-f. There should be space for 6 floats in the return buffer for the values a-f.
*/ */
CurrentTransform :: proc(ctx: ^Context, xform: ^Matrix) { CurrentTransform :: proc(ctx: ^Context, xform: ^Matrix) {
state := __getState(ctx)
if xform == nil { if xform == nil {
return return
} }
state := __getState(ctx)
xform^ = state.xform xform^ = state.xform
} }
@@ -901,7 +898,7 @@ CreateImagePath :: proc(ctx: ^Context, filename: cstring, imageFlags: ImageFlags
return 0 return 0
} }
data := mem.slice_ptr(img, int(w) * int(h) * int(n)) data := img[:int(w) * int(h) * int(n)]
image := CreateImageRGBA(ctx, int(w), int(h), imageFlags, data) image := CreateImageRGBA(ctx, int(w), int(h), imageFlags, data)
stbi.image_free(img) stbi.image_free(img)
return image return image
@@ -919,8 +916,8 @@ CreateImageMem :: proc(ctx: ^Context, data: []byte, imageFlags: ImageFlags) -> i
return 0 return 0
} }
pixel_data := mem.slice_ptr(img, int(w) * int(h) * int(n)) data := img[:int(w) * int(h) * int(n)]
image := CreateImageRGBA(ctx, int(w), int(h), imageFlags, pixel_data) image := CreateImageRGBA(ctx, int(w), int(h), imageFlags, data)
stbi.image_free(img) stbi.image_free(img)
return image return image
} }
@@ -1158,8 +1155,6 @@ IntersectScissor :: proc(
} }
state := __getState(ctx) state := __getState(ctx)
pxform: Matrix
invxorm: Matrix
// If no previous scissor has been set, set the scissor as current scissor. // If no previous scissor has been set, set the scissor as current scissor.
if state.scissor.extent[0] < 0 { if state.scissor.extent[0] < 0 {
@@ -1167,9 +1162,11 @@ IntersectScissor :: proc(
return return
} }
pxform = state.scissor.xform pxform := state.scissor.xform
ex := state.scissor.extent[0] ex := state.scissor.extent[0]
ey := state.scissor.extent[1] ey := state.scissor.extent[1]
invxorm: Matrix
TransformInverse(&invxorm, state.xform) TransformInverse(&invxorm, state.xform)
TransformMultiply(&pxform, invxorm) TransformMultiply(&pxform, invxorm)
tex := ex * abs(pxform[0]) + ey * abs(pxform[2]) tex := ex * abs(pxform[0]) + ey * abs(pxform[2])
@@ -1197,7 +1194,7 @@ ResetScissor :: proc(ctx: ^Context) {
/////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////
// state table instead of if else chains // state table instead of if else chains
OP_STATE_TABLE :: [CompositeOperation][2]BlendFactor { OP_STATE_TABLE := [CompositeOperation][2]BlendFactor {
.SOURCE_OVER = {.ONE, .ONE_MINUS_SRC_ALPHA}, .SOURCE_OVER = {.ONE, .ONE_MINUS_SRC_ALPHA},
.SOURCE_IN = {.DST_ALPHA, .ZERO}, .SOURCE_IN = {.DST_ALPHA, .ZERO},
.SOURCE_OUT = {.ONE_MINUS_DST_ALPHA, .ZERO}, .SOURCE_OUT = {.ONE_MINUS_DST_ALPHA, .ZERO},
@@ -1214,8 +1211,7 @@ OP_STATE_TABLE :: [CompositeOperation][2]BlendFactor {
} }
__compositeOperationState :: proc(op: CompositeOperation) -> (res: CompositeOperationState) { __compositeOperationState :: proc(op: CompositeOperation) -> (res: CompositeOperationState) {
table := OP_STATE_TABLE factors := OP_STATE_TABLE[op]
factors := table[op]
res.srcRGB = factors.x res.srcRGB = factors.x
res.dstRGB = factors.y res.dstRGB = factors.y
res.srcAlpha = factors.x res.srcAlpha = factors.x
@@ -1242,14 +1238,13 @@ GlobalCompositeBlendFuncSeparate :: proc(
srcAlpha: BlendFactor, srcAlpha: BlendFactor,
dstAlpha: BlendFactor, dstAlpha: BlendFactor,
) { ) {
op := CompositeOperationState { state := __getState(ctx)
state.compositeOperation = CompositeOperationState{
srcRGB, srcRGB,
dstRGB, dstRGB,
srcAlpha, srcAlpha,
dstAlpha, dstAlpha,
} }
state := __getState(ctx)
state.compositeOperation = op
} }
/////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////
@@ -1277,46 +1272,38 @@ __distPtSeg :: proc(x, y, px, py, qx, qy: f32) -> f32 {
if d > 0 { if d > 0 {
t /= d t /= d
} }
t = clamp(t, 0, 1)
if t < 0 {
t = 0
} else if t > 1 {
t = 1
}
dx = px + t * pqx - x dx = px + t * pqx - x
dy = py + t * pqy - y dy = py + t * pqy - y
return dx * dx + dy * dy return dx * dx + dy * dy
} }
__appendCommands :: proc(ctx: ^Context, values: []f32) { __appendCommands :: proc(ctx: ^Context, values: ..f32) {
state := __getState(ctx) state := __getState(ctx)
if Commands(values[0]) != .CLOSE && Commands(values[0]) != .WINDING { if Commands(values[0]) != .CLOSE && Commands(values[0]) != .WINDING {
ctx.commandx = values[len(values)-2] ctx.commandx = values[len(values)-2]
ctx.commandy = values[len(values)-1] ctx.commandy = values[len(values)-1]
} }
for i := 0; i < len(values); /**/ {
i := 0
for i < len(values) {
cmd := Commands(values[i]) cmd := Commands(values[i])
switch cmd { switch cmd {
case .MOVE_TO, .LINE_TO: case .MOVE_TO, .LINE_TO:
TransformPoint(&values[i+1], &values[i+2], state.xform, values[i+1], values[i+2]) TransformPoint(&values[i+1], &values[i+2], state.xform, values[i+1], values[i+2])
i += 3 i += 3
case .BEZIER_TO: case .BEZIER_TO:
TransformPoint(&values[i+1], &values[i+2], state.xform, values[i+1], values[i+2]) TransformPoint(&values[i+1], &values[i+2], state.xform, values[i+1], values[i+2])
TransformPoint(&values[i+3], &values[i+4], state.xform, values[i+3], values[i+4]) TransformPoint(&values[i+3], &values[i+4], state.xform, values[i+3], values[i+4])
TransformPoint(&values[i+5], &values[i+6], state.xform, values[i+5], values[i+6]) TransformPoint(&values[i+5], &values[i+6], state.xform, values[i+5], values[i+6])
i += 7 i += 7
case .CLOSE:
case .CLOSE: i += 1 i += 1
case .WINDING: i += 2 case .WINDING:
i += 2
// default case:
case: i += 1 i += 1
} }
} }
@@ -1513,9 +1500,7 @@ __flattenPaths :: proc(ctx: ^Context) {
i += 3 i += 3
case .BEZIER_TO: case .BEZIER_TO:
last := __lastPoint(ctx) if last := __lastPoint(ctx); last != nil {
if last != nil {
cp1 := ctx.commands[i + 1:] cp1 := ctx.commands[i + 1:]
cp2 := ctx.commands[i + 3:] cp2 := ctx.commands[i + 3:]
p := ctx.commands[i + 5:] p := ctx.commands[i + 5:]
@@ -1542,8 +1527,7 @@ __flattenPaths :: proc(ctx: ^Context) {
cache.bounds[3] = -1e6 cache.bounds[3] = -1e6
// Calculate the direction and length of line segments. // Calculate the direction and length of line segments.
for j in 0..<len(cache.paths) { for &path in cache.paths {
path := &cache.paths[j]
pts := cache.points[path.first:] pts := cache.points[path.first:]
// If the first and last points are the same, remove the last, mark as closed path. // If the first and last points are the same, remove the last, mark as closed path.
@@ -1624,18 +1608,13 @@ __vset :: proc(dst: ^[]Vertex, x, y, u, v: f32, loc := #caller_location) {
__roundJoin :: proc( __roundJoin :: proc(
dst: ^[]Vertex, dst: ^[]Vertex,
p0: ^Point, p0, p1: ^Point,
p1: ^Point, lw, rw: f32,
lw: f32, lu,ru: f32,
rw: f32,
lu: f32,
ru: f32,
ncap: int, ncap: int,
) { ) {
dlx0 := p0.dy dlx0, dly0 := p0.dy, -p0.dx
dly0 := -p0.dx dlx1, dly1 := p1.dy, -p1.dx
dlx1 := p1.dy
dly1 := -p1.dx
if .LEFT in p1.flags { if .LEFT in p1.flags {
lx0,ly0,lx1,ly1: f32 lx0,ly0,lx1,ly1: f32
@@ -1695,17 +1674,12 @@ __roundJoin :: proc(
__bevelJoin :: proc( __bevelJoin :: proc(
dst: ^[]Vertex, dst: ^[]Vertex,
p0: ^Point, p0, p1: ^Point,
p1: ^Point, lw, rw: f32,
lw: f32, lu, ru: f32,
rw: f32,
lu: f32,
ru: f32,
) { ) {
dlx0 := p0.dy dlx0,dly0 := p0.dy, -p0.dx
dly0 := -p0.dx dlx1, dly1 := p1.dy, -p1.dx
dlx1 := p1.dy
dly1 := -p1.dx
rx0, ry0, rx1, ry1: f32 rx0, ry0, rx1, ry1: f32
lx0, ly0, lx1, ly1: f32 lx0, ly0, lx1, ly1: f32
@@ -1891,9 +1865,9 @@ __calculateJoins :: proc(
p1.dmx = (dlx0 + dlx1) * 0.5 p1.dmx = (dlx0 + dlx1) * 0.5
p1.dmy = (dly0 + dly1) * 0.5 p1.dmy = (dly0 + dly1) * 0.5
dmr2 = p1.dmx*p1.dmx + p1.dmy*p1.dmy dmr2 = p1.dmx*p1.dmx + p1.dmy*p1.dmy
if (dmr2 > 0.000001) { if dmr2 > 0.000001 {
scale := 1.0 / dmr2 scale := 1.0 / dmr2
if (scale > 600.0) { if scale > 600.0 {
scale = 600.0 scale = 600.0
} }
p1.dmx *= scale p1.dmx *= scale
@@ -1901,25 +1875,25 @@ __calculateJoins :: proc(
} }
// Clear flags, but keep the corner. // Clear flags, but keep the corner.
p1.flags = (.CORNER in p1.flags) ? { .CORNER } : {} p1.flags = {.CORNER} if .CORNER in p1.flags else nil
// Keep track of left turns. // Keep track of left turns.
__cross = p1.dx * p0.dy - p0.dx * p1.dy __cross = p1.dx * p0.dy - p0.dx * p1.dy
if __cross > 0.0 { if __cross > 0.0 {
nleft += 1 nleft += 1
incl(&p1.flags, PointFlag.LEFT) p1.flags += {.LEFT}
} }
// Calculate if we should use bevel or miter for inner join. // Calculate if we should use bevel or miter for inner join.
limit = max(1.01, min(p0.len, p1.len) * iw) limit = max(1.01, min(p0.len, p1.len) * iw)
if (dmr2 * limit * limit) < 1.0 { if (dmr2 * limit * limit) < 1.0 {
incl(&p1.flags, PointFlag.INNER_BEVEL) p1.flags += {.INNER_BEVEL}
} }
// Check to see if the corner needs to be beveled. // Check to see if the corner needs to be beveled.
if .CORNER in p1.flags { if .CORNER in p1.flags {
if (dmr2 * miterLimit*miterLimit) < 1.0 || lineJoin == .BEVEL || lineJoin == .ROUND { if (dmr2 * miterLimit*miterLimit) < 1.0 || lineJoin == .BEVEL || lineJoin == .ROUND {
incl(&p1.flags, PointFlag.BEVEL) p1.flags += {.BEVEL}
} }
} }
@@ -1968,7 +1942,7 @@ __expandStroke :: proc(
// Calculate max vertex usage. // Calculate max vertex usage.
cverts := 0 cverts := 0
for &path in cache.paths { for path in cache.paths {
loop := path.closed loop := path.closed
// TODO check if f32 calculation necessary? // TODO check if f32 calculation necessary?
@@ -1991,8 +1965,7 @@ __expandStroke :: proc(
verts := __allocTempVerts(ctx, cverts) verts := __allocTempVerts(ctx, cverts)
dst_index: int dst_index: int
for i in 0..<len(cache.paths) { for &path in cache.paths {
path := &cache.paths[i]
pts := cache.points[path.first:] pts := cache.points[path.first:]
p0, p1: ^Point p0, p1: ^Point
start, end: int start, end: int
@@ -2097,7 +2070,7 @@ __expandFill :: proc(
// Calculate max vertex usage. // Calculate max vertex usage.
cverts := 0 cverts := 0
for &path in cache.paths { for path in cache.paths {
cverts += path.count + path.nbevel + 1 cverts += path.count + path.nbevel + 1
if fringe { if fringe {
@@ -2125,7 +2098,7 @@ __expandFill :: proc(
p0 = &pts[path.count-1] p0 = &pts[path.count-1]
p1 = &pts[0] p1 = &pts[0]
for j in 0..<path.count { for _ in 0..<path.count {
if .BEVEL in p1.flags { if .BEVEL in p1.flags {
dlx0 := p0.dy dlx0 := p0.dy
dly0 := -p0.dx dly0 := -p0.dx
@@ -2152,8 +2125,8 @@ __expandFill :: proc(
p1 = mem.ptr_offset(p1, 1) p1 = mem.ptr_offset(p1, 1)
} }
} else { } else {
for j in 0..<path.count { for v in pts[:path.count] {
__vset(&dst, pts[j].x, pts[j].y, 0.5,1) __vset(&dst, v.x, v.y, 0.5, 1)
} }
} }
@@ -2182,7 +2155,7 @@ __expandFill :: proc(
p0 = &pts[path.count-1] p0 = &pts[path.count-1]
p1 = &pts[0] p1 = &pts[0]
for j in 0..<path.count { for _ in 0..<path.count {
if (.BEVEL in p1.flags) || (.INNER_BEVEL in p1.flags) { if (.BEVEL in p1.flags) || (.INNER_BEVEL in p1.flags) {
__bevelJoin(&dst, p0, p1, lw, rw, lu, ru) __bevelJoin(&dst, p0, p1, lw, rw, lu, ru)
} else { } else {
@@ -2257,14 +2230,12 @@ FillStrokeScoped :: proc(ctx: ^Context) {
// Starts new sub-path with specified point as first point. // Starts new sub-path with specified point as first point.
MoveTo :: proc(ctx: ^Context, x, y: f32) { MoveTo :: proc(ctx: ^Context, x, y: f32) {
values := [3]f32 { __cmdf(.MOVE_TO), x, y } __appendCommands(ctx, __cmdf(.MOVE_TO), x, y)
__appendCommands(ctx, values[:])
} }
// Adds line segment from the last point in the path to the specified point. // Adds line segment from the last point in the path to the specified point.
LineTo :: proc(ctx: ^Context, x, y: f32) { LineTo :: proc(ctx: ^Context, x, y: f32) {
values := [3]f32 { __cmdf(.LINE_TO), x, y } __appendCommands(ctx, __cmdf(.LINE_TO), x, y)
__appendCommands(ctx, values[:])
} }
// Adds cubic bezier segment from last point in the path via two control points to the specified point. // Adds cubic bezier segment from last point in the path via two control points to the specified point.
@@ -2274,15 +2245,14 @@ BezierTo :: proc(
c2x, c2y: f32, c2x, c2y: f32,
x, y: f32, x, y: f32,
) { ) {
values := [?]f32 { __cmdf(.BEZIER_TO), c1x, c1y, c2x, c2y, x, y } __appendCommands(ctx, __cmdf(.BEZIER_TO), c1x, c1y, c2x, c2y, x, y)
__appendCommands(ctx, values[:])
} }
// Adds quadratic bezier segment from last point in the path via a control point to the specified point. // Adds quadratic bezier segment from last point in the path via a control point to the specified point.
QuadTo :: proc(ctx: ^Context, cx, cy, x, y: f32) { QuadTo :: proc(ctx: ^Context, cx, cy, x, y: f32) {
x0 := ctx.commandx x0 := ctx.commandx
y0 := ctx.commandy y0 := ctx.commandy
values := [?]f32 { __appendCommands(ctx,
__cmdf(.BEZIER_TO), __cmdf(.BEZIER_TO),
x0 + 2 / 3 * (cx - x0), x0 + 2 / 3 * (cx - x0),
y0 + 2 / 3 * (cy - y0), y0 + 2 / 3 * (cy - y0),
@@ -2290,8 +2260,7 @@ QuadTo :: proc(ctx: ^Context, cx, cy, x, y: f32) {
y + 2 / 3 * (cy - y), y + 2 / 3 * (cy - y),
x, x,
y, y,
} )
__appendCommands(ctx, values[:])
} }
// Adds an arc segment at the corner defined by the last path point, and two specified points. // Adds an arc segment at the corner defined by the last path point, and two specified points.
@@ -2419,37 +2388,33 @@ Arc :: proc(ctx: ^Context, cx, cy, r, a0, a1: f32, dir: Winding) {
} }
// stored internally // stored internally
__appendCommands(ctx, values[:nvals]) __appendCommands(ctx, ..values[:nvals])
} }
// Closes current sub-path with a line segment. // Closes current sub-path with a line segment.
ClosePath :: proc(ctx: ^Context) { ClosePath :: proc(ctx: ^Context) {
values := [1]f32 { __cmdf(.CLOSE) } __appendCommands(ctx, __cmdf(.CLOSE))
__appendCommands(ctx, values[:])
} }
// Sets the current sub-path winding, see NVGwinding and NVGsolidity. // Sets the current sub-path winding, see NVGwinding and NVGsolidity.
PathWinding :: proc(ctx: ^Context, direction: Winding) { PathWinding :: proc(ctx: ^Context, direction: Winding) {
values := [2]f32 { __cmdf(.WINDING), f32(direction) } __appendCommands(ctx, __cmdf(.WINDING), f32(direction))
__appendCommands(ctx, values[:])
} }
// same as path_winding but with different enum // same as path_winding but with different enum
PathSolidity :: proc(ctx: ^Context, solidity: Solidity) { PathSolidity :: proc(ctx: ^Context, solidity: Solidity) {
values := [2]f32 { __cmdf(.WINDING), f32(solidity) } __appendCommands(ctx, __cmdf(.WINDING), f32(solidity))
__appendCommands(ctx, values[:])
} }
// Creates new rectangle shaped sub-path. // Creates new rectangle shaped sub-path.
Rect :: proc(ctx: ^Context, x, y, w, h: f32) { Rect :: proc(ctx: ^Context, x, y, w, h: f32) {
values := [?]f32 { __appendCommands(ctx,
__cmdf(.MOVE_TO), x, y, __cmdf(.MOVE_TO), x, y,
__cmdf(.LINE_TO), x, y + h, __cmdf(.LINE_TO), x, y + h,
__cmdf(.LINE_TO), x + w, y + h, __cmdf(.LINE_TO), x + w, y + h,
__cmdf(.LINE_TO), x + w, y, __cmdf(.LINE_TO), x + w, y,
__cmdf(.CLOSE), __cmdf(.CLOSE),
} )
__appendCommands(ctx, values[:])
} }
// Creates new rounded rectangle shaped sub-path. // Creates new rounded rectangle shaped sub-path.
@@ -2480,7 +2445,7 @@ RoundedRectVarying :: proc(
ryTR := min(radius_top_right, halfh) * math.sign(h) ryTR := min(radius_top_right, halfh) * math.sign(h)
rxTL := min(radius_top_left, halfw) * math.sign(w) rxTL := min(radius_top_left, halfw) * math.sign(w)
ryTL := min(radius_top_left, halfh) * math.sign(h) ryTL := min(radius_top_left, halfh) * math.sign(h)
values := [?]f32 { __appendCommands(ctx,
__cmdf(.MOVE_TO), x, y + ryTL, __cmdf(.MOVE_TO), x, y + ryTL,
__cmdf(.LINE_TO), x, y + h - ryBL, __cmdf(.LINE_TO), x, y + h - ryBL,
__cmdf(.BEZIER_TO), x, y + h - ryBL*(1 - KAPPA), x + rxBL*(1 - KAPPA), y + h, x + rxBL, y + h, __cmdf(.BEZIER_TO), x, y + h - ryBL*(1 - KAPPA), x + rxBL*(1 - KAPPA), y + h, x + rxBL, y + h,
@@ -2491,22 +2456,20 @@ RoundedRectVarying :: proc(
__cmdf(.LINE_TO), x + rxTL, y, __cmdf(.LINE_TO), x + rxTL, y,
__cmdf(.BEZIER_TO), x + rxTL*(1 - KAPPA), y, x, y + ryTL*(1 - KAPPA), x, y + ryTL, __cmdf(.BEZIER_TO), x + rxTL*(1 - KAPPA), y, x, y + ryTL*(1 - KAPPA), x, y + ryTL,
__cmdf(.CLOSE), __cmdf(.CLOSE),
} )
__appendCommands(ctx, values[:])
} }
} }
// Creates new ellipse shaped sub-path. // Creates new ellipse shaped sub-path.
Ellipse :: proc(ctx: ^Context, cx, cy, rx, ry: f32) { Ellipse :: proc(ctx: ^Context, cx, cy, rx, ry: f32) {
values := [?]f32 { __appendCommands(ctx,
__cmdf(.MOVE_TO), cx-rx, cy, __cmdf(.MOVE_TO), cx-rx, cy,
__cmdf(.BEZIER_TO), cx-rx, cy+ry*KAPPA, cx-rx*KAPPA, cy+ry, cx, cy+ry, __cmdf(.BEZIER_TO), cx-rx, cy+ry*KAPPA, cx-rx*KAPPA, cy+ry, cx, cy+ry,
__cmdf(.BEZIER_TO), cx+rx*KAPPA, cy+ry, cx+rx, cy+ry*KAPPA, cx+rx, cy, __cmdf(.BEZIER_TO), cx+rx*KAPPA, cy+ry, cx+rx, cy+ry*KAPPA, cx+rx, cy,
__cmdf(.BEZIER_TO), cx+rx, cy-ry*KAPPA, cx+rx*KAPPA, cy-ry, cx, cy-ry, __cmdf(.BEZIER_TO), cx+rx, cy-ry*KAPPA, cx+rx*KAPPA, cy-ry, cx, cy-ry,
__cmdf(.BEZIER_TO), cx-rx*KAPPA, cy-ry, cx-rx, cy-ry*KAPPA, cx-rx, cy, __cmdf(.BEZIER_TO), cx-rx*KAPPA, cy-ry, cx-rx, cy-ry*KAPPA, cx-rx, cy,
__cmdf(.CLOSE), __cmdf(.CLOSE),
} )
__appendCommands(ctx, values[:])
} }
// Creates new circle shaped sub-path. // Creates new circle shaped sub-path.
@@ -2542,7 +2505,7 @@ Fill :: proc(ctx: ^Context) {
ctx.cache.paths[:], ctx.cache.paths[:],
) )
for &path in ctx.cache.paths { for path in ctx.cache.paths {
ctx.fillTriCount += len(path.fill) - 2 ctx.fillTriCount += len(path.fill) - 2
ctx.fillTriCount += len(path.stroke) - 2 ctx.fillTriCount += len(path.stroke) - 2
ctx.drawCallCount += 2 ctx.drawCallCount += 2
@@ -2588,7 +2551,7 @@ Stroke :: proc(ctx: ^Context) {
ctx.cache.paths[:], ctx.cache.paths[:],
) )
for &path in ctx.cache.paths { for path in ctx.cache.paths {
ctx.strokeTriCount += len(path.stroke) - 2 ctx.strokeTriCount += len(path.stroke) - 2
ctx.drawCallCount += 1 ctx.drawCallCount += 1
} }
@@ -2597,22 +2560,22 @@ Stroke :: proc(ctx: ^Context) {
DebugDumpPathCache :: proc(ctx: ^Context) { DebugDumpPathCache :: proc(ctx: ^Context) {
fmt.printf("~~~~~~~~~~~~~Dumping %d cached paths\n", len(ctx.cache.paths)) fmt.printf("~~~~~~~~~~~~~Dumping %d cached paths\n", len(ctx.cache.paths))
for &path, i in ctx.cache.paths { for path, i in ctx.cache.paths {
fmt.printf(" - Path %d\n", i) fmt.printf(" - Path %d\n", i)
if len(path.fill) != 0 { if len(path.fill) != 0 {
fmt.printf(" - fill: %d\n", len(path.fill)) fmt.printf(" - fill: %d\n", len(path.fill))
for j in 0..<len(path.fill) { for v in path.fill {
fmt.printf("%f\t%f\n", path.fill[j].x, path.fill[j].y) fmt.printf("%f\t%f\n", v.x, v.y)
} }
} }
if len(path.stroke) != 0 { if len(path.stroke) != 0 {
fmt.printf(" - stroke: %d\n", len(path.stroke)) fmt.printf(" - stroke: %d\n", len(path.stroke))
for j in 0..<len(path.stroke) { for v in path.stroke {
fmt.printf("%f\t%f\n", path.stroke[j].x, path.stroke[j].y) fmt.printf("%f\t%f\n", v.x, v.y)
} }
} }
} }
@@ -2766,7 +2729,6 @@ __flushTextTexture :: proc(ctx: ^Context) {
dirty: [4]f32 dirty: [4]f32
assert(ctx.params.renderUpdateTexture != nil) assert(ctx.params.renderUpdateTexture != nil)
if fontstash.ValidateTexture(&ctx.fs, &dirty) { if fontstash.ValidateTexture(&ctx.fs, &dirty) {
font_image := ctx.fontImages[ctx.fontImageIdx] font_image := ctx.fontImages[ctx.fontImageIdx]
@@ -2867,7 +2829,7 @@ TextIcon :: proc(ctx: ^Context, xpos, ypos: f32, codepoint: rune) -> f32 {
font := fontstash.__getFont(fs, state.fontId) font := fontstash.__getFont(fs, state.fontId)
isize := i16(fstate.size * 10) isize := i16(fstate.size * 10)
iblur := i16(fstate.blur) iblur := i16(fstate.blur)
glyph := fontstash.__getGlyph(fs, font, codepoint, isize, iblur) glyph, _ := fontstash.__getGlyph(fs, font, codepoint, isize, iblur)
fscale := fontstash.__getPixelHeightScale(font, f32(isize) / 10) fscale := fontstash.__getPixelHeightScale(font, f32(isize) / 10)
// transform x / y // transform x / y
@@ -2986,7 +2948,7 @@ Text :: proc(ctx: ^Context, x, y: f32, text: string) -> f32 {
// Create triangles // Create triangles
if nverts + 6 <= cverts { if nverts + 6 <= cverts {
verts[nverts] = { c[0], c[1], q.s0, q.t0 } verts[nverts+0] = {c[0], c[1], q.s0, q.t0}
verts[nverts+1] = {c[4], c[5], q.s1, q.t1} verts[nverts+1] = {c[4], c[5], q.s1, q.t1}
verts[nverts+2] = {c[2], c[3], q.s1, q.t0} verts[nverts+2] = {c[2], c[3], q.s1, q.t0}
verts[nverts+3] = {c[0], c[1], q.s0, q.t0} verts[nverts+3] = {c[0], c[1], q.s0, q.t0}
@@ -3043,7 +3005,7 @@ TextBounds :: proc(
invscale := f32(1.0) / scale invscale := f32(1.0) / scale
if state.fontId == -1 { if state.fontId == -1 {
return {} return 0
} }
fs := &ctx.fs fs := &ctx.fs
@@ -3056,10 +3018,10 @@ TextBounds :: proc(
width := fontstash.TextBounds(fs, input, x * scale, y * scale, bounds) width := fontstash.TextBounds(fs, input, x * scale, y * scale, bounds)
if bounds != nil {
// Use line bounds for height. // Use line bounds for height.
one, two := fontstash.LineBounds(fs, y * scale) one, two := fontstash.LineBounds(fs, y * scale)
if bounds != nil {
bounds[1] = one bounds[1] = one
bounds[3] = two bounds[3] = two
bounds[0] *= invscale bounds[0] *= invscale
@@ -3112,8 +3074,7 @@ TextBox :: proc(
y := y y := y
input := input input := input
for nrows, input_last in TextBreakLines(ctx, &input, break_row_width, &rows_mod) { for nrows, input_last in TextBreakLines(ctx, &input, break_row_width, &rows_mod) {
for i in 0..<nrows { for row in rows[:nrows] {
row := &rows[i]
Text(ctx, x, y, input_last[row.start:row.end]) Text(ctx, x, y, input_last[row.start:row.end])
y += lineHeight * state.lineHeight y += lineHeight * state.lineHeight
} }
@@ -3163,6 +3124,7 @@ TextBreakLines :: proc(
break_x := break_row_width * scale break_x := break_row_width * scale
iter := fontstash.TextIterInit(fs, 0, 0, text^) iter := fontstash.TextIterInit(fs, 0, 0, text^)
prev_iter := iter prev_iter := iter
q: fontstash.Quad q: fontstash.Quad
stopped_early: bool stopped_early: bool
@@ -3179,32 +3141,33 @@ TextBreakLines :: proc(
type = .Space type = .Space
case '\n': case '\n':
type = pcodepoint == 13 ? .Space : .Newline type = .Space if pcodepoint == 13 else .Newline
case '\r': case '\r':
type = pcodepoint == 10 ? .Space : .Newline type = .Space if pcodepoint == 10 else .Newline
case 0x0085: case 0x0085:
// NEL // NEL
type = .Newline type = .Newline
case: case:
if (iter.codepoint >= 0x4E00 && iter.codepoint <= 0x9FFF) || switch iter.codepoint {
(iter.codepoint >= 0x3000 && iter.codepoint <= 0x30FF) || case 0x4E00..=0x9FFF,
(iter.codepoint >= 0xFF00 && iter.codepoint <= 0xFFEF) || 0x3000..=0x30FF,
(iter.codepoint >= 0x1100 && iter.codepoint <= 0x11FF) || 0xFF00..=0xFFEF,
(iter.codepoint >= 0x3130 && iter.codepoint <= 0x318F) || 0x1100..=0x11FF,
(iter.codepoint >= 0xAC00 && iter.codepoint <= 0xD7AF) { 0x3130..=0x318F,
0xAC00..=0xD7AF:
type = .CJK type = .CJK
} else { case:
type = .Char type = .Char
} }
} }
if type == .Newline { if type == .Newline {
// Always handle new lines. // Always handle new lines.
rows[nrows].start = row_start != -1 ? row_start : iter.str rows[nrows].start = row_start if row_start != -1 else iter.str
rows[nrows].end = row_end != -1 ? row_end : iter.str rows[nrows].end = row_end if row_end != -1 else iter.str
rows[nrows].width = row_width * invscale rows[nrows].width = row_width * invscale
rows[nrows].minx = row_min_x * invscale rows[nrows].minx = row_min_x * invscale
rows[nrows].maxx = row_max_x * invscale rows[nrows].maxx = row_max_x * invscale
@@ -3270,7 +3233,7 @@ TextBreakLines :: proc(
// Break to new line when a character is beyond break width. // Break to new line when a character is beyond break width.
if (type == .Char || type == .CJK) && next_width > break_x { if (type == .Char || type == .CJK) && next_width > break_x {
// The run length is too long, need to break to new line. // The run length is too long, need to break to new line.
if (break_end == row_start) { if break_end == row_start {
// The current word is longer than the row length, just break it from here. // The current word is longer than the row length, just break it from here.
rows[nrows].start = row_start rows[nrows].start = row_start
rows[nrows].end = iter.str rows[nrows].end = iter.str
@@ -3398,8 +3361,7 @@ TextBoxBounds :: proc(
y := y y := y
for nrows, input_last in TextBreakLines(ctx, &input, breakRowWidth, &rows_mod) { for nrows, input_last in TextBreakLines(ctx, &input, breakRowWidth, &rows_mod) {
for i in 0..<nrows { for row in rows[:nrows] {
row := &rows[i]
rminx, rmaxx, dx: f32 rminx, rmaxx, dx: f32
// Horizontal bounds // Horizontal bounds