mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-06 23:58:50 +00:00
General code style clean up for vendor:nanovg
This commit is contained in:
Vendored
+183
-221
@@ -284,7 +284,7 @@ __setDevicePxRatio :: proc(ctx: ^Context, ratio: f32) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
__getState :: #force_inline proc(ctx: ^Context) -> ^State #no_bounds_check {
|
__getState :: #force_inline proc(ctx: ^Context) -> ^State #no_bounds_check {
|
||||||
return &ctx.states[ctx.nstates - 1]
|
return &ctx.states[ctx.nstates-1]
|
||||||
}
|
}
|
||||||
|
|
||||||
CreateInternal :: proc(params: Params) -> (ctx: ^Context) {
|
CreateInternal :: proc(params: Params) -> (ctx: ^Context) {
|
||||||
@@ -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
|
||||||
}
|
}
|
||||||
@@ -667,7 +664,7 @@ Save :: proc(ctx: ^Context) {
|
|||||||
|
|
||||||
// copy prior
|
// copy prior
|
||||||
if ctx.nstates > 0 {
|
if ctx.nstates > 0 {
|
||||||
ctx.states[ctx.nstates] = ctx.states[ctx.nstates - 1]
|
ctx.states[ctx.nstates] = ctx.states[ctx.nstates-1]
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.nstates += 1
|
ctx.nstates += 1
|
||||||
@@ -817,7 +814,7 @@ FillPaint :: proc(ctx: ^Context, paint: Paint) {
|
|||||||
|
|
||||||
Transform :: proc(ctx: ^Context, a, b, c, d, e, f: f32) {
|
Transform :: proc(ctx: ^Context, a, b, c, d, e, f: f32) {
|
||||||
state := __getState(ctx)
|
state := __getState(ctx)
|
||||||
TransformPremultiply(&state.xform, { a, b, c, d, e, f })
|
TransformPremultiply(&state.xform, {a, b, c, d, e, f})
|
||||||
}
|
}
|
||||||
|
|
||||||
// Resets current transform to a identity matrix.
|
// Resets current transform to a identity matrix.
|
||||||
@@ -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,13 +916,13 @@ 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
|
||||||
}
|
}
|
||||||
|
|
||||||
CreateImage :: proc { CreateImagePath, CreateImageMem }
|
CreateImage :: proc{CreateImagePath, CreateImageMem}
|
||||||
|
|
||||||
// Creates image from specified image data.
|
// Creates image from specified image data.
|
||||||
// Returns handle to the image.
|
// Returns handle to the image.
|
||||||
@@ -1097,7 +1094,7 @@ ImagePattern :: proc(
|
|||||||
p.extent[1] = h
|
p.extent[1] = h
|
||||||
|
|
||||||
p.image = image
|
p.image = image
|
||||||
p.innerColor = { 1,1,1,alpha }
|
p.innerColor = {1, 1, 1, alpha}
|
||||||
p.outerColor = p.innerColor
|
p.outerColor = p.innerColor
|
||||||
|
|
||||||
return
|
return
|
||||||
@@ -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,25 +1194,24 @@ 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},
|
||||||
.ATOP = { .DST_ALPHA, .ONE_MINUS_SRC_ALPHA },
|
.ATOP = {.DST_ALPHA, .ONE_MINUS_SRC_ALPHA},
|
||||||
|
|
||||||
.DESTINATION_OVER = { .ONE_MINUS_DST_ALPHA, .ONE },
|
.DESTINATION_OVER = {.ONE_MINUS_DST_ALPHA, .ONE},
|
||||||
.DESTINATION_IN = { .ZERO, .SRC_ALPHA },
|
.DESTINATION_IN = {.ZERO, .SRC_ALPHA},
|
||||||
.DESTINATION_OUT = { .ZERO, .ONE_MINUS_SRC_ALPHA },
|
.DESTINATION_OUT = {.ZERO, .ONE_MINUS_SRC_ALPHA},
|
||||||
.DESTINATION_ATOP = { .ONE_MINUS_DST_ALPHA, .SRC_ALPHA },
|
.DESTINATION_ATOP = {.ONE_MINUS_DST_ALPHA, .SRC_ALPHA},
|
||||||
|
|
||||||
.LIGHTER = { .ONE, .ONE },
|
.LIGHTER = {.ONE, .ONE},
|
||||||
.COPY = { .ONE, .ZERO },
|
.COPY = {.ONE, .ZERO},
|
||||||
.XOR = { .ONE_MINUS_DST_ALPHA, .ONE_MINUS_SRC_ALPHA },
|
.XOR = {.ONE_MINUS_DST_ALPHA, .ONE_MINUS_SRC_ALPHA},
|
||||||
}
|
}
|
||||||
|
|
||||||
__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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1331,14 +1318,14 @@ __clearPathCache :: proc(ctx: ^Context) {
|
|||||||
|
|
||||||
__lastPath :: proc(ctx: ^Context) -> ^Path {
|
__lastPath :: proc(ctx: ^Context) -> ^Path {
|
||||||
if len(ctx.cache.paths) > 0 {
|
if len(ctx.cache.paths) > 0 {
|
||||||
return &ctx.cache.paths[len(ctx.cache.paths) - 1]
|
return &ctx.cache.paths[len(ctx.cache.paths)-1]
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
__addPath :: proc(ctx: ^Context) {
|
__addPath :: proc(ctx: ^Context) {
|
||||||
append(&ctx.cache.paths, Path {
|
append(&ctx.cache.paths, Path{
|
||||||
first = len(ctx.cache.points),
|
first = len(ctx.cache.points),
|
||||||
winding = .CCW,
|
winding = .CCW,
|
||||||
})
|
})
|
||||||
@@ -1346,7 +1333,7 @@ __addPath :: proc(ctx: ^Context) {
|
|||||||
|
|
||||||
__lastPoint :: proc(ctx: ^Context) -> ^Point {
|
__lastPoint :: proc(ctx: ^Context) -> ^Point {
|
||||||
if len(ctx.cache.paths) > 0 {
|
if len(ctx.cache.paths) > 0 {
|
||||||
return &ctx.cache.points[len(ctx.cache.points) - 1]
|
return &ctx.cache.points[len(ctx.cache.points)-1]
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
@@ -1368,7 +1355,7 @@ __addPoint :: proc(ctx: ^Context, x, y: f32, flags: PointFlags) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
append(&ctx.cache.points, Point {
|
append(&ctx.cache.points, Point{
|
||||||
x = x,
|
x = x,
|
||||||
y = y,
|
y = y,
|
||||||
flags = flags,
|
flags = flags,
|
||||||
@@ -1415,7 +1402,7 @@ __polyArea :: proc(points: []Point) -> f32 {
|
|||||||
|
|
||||||
for i := 2; i < len(points); i += 1 {
|
for i := 2; i < len(points); i += 1 {
|
||||||
a := &points[0]
|
a := &points[0]
|
||||||
b := &points[i - 1]
|
b := &points[i-1]
|
||||||
c := &points[i]
|
c := &points[i]
|
||||||
area += __triarea2(a.x, a.y, b.x, b.y, c.x, c.y)
|
area += __triarea2(a.x, a.y, b.x, b.y, c.x, c.y)
|
||||||
}
|
}
|
||||||
@@ -1504,22 +1491,20 @@ __flattenPaths :: proc(ctx: ^Context) {
|
|||||||
case .MOVE_TO:
|
case .MOVE_TO:
|
||||||
__addPath(ctx)
|
__addPath(ctx)
|
||||||
p := ctx.commands[i + 1:]
|
p := ctx.commands[i + 1:]
|
||||||
__addPoint(ctx, p[0], p[1], { .CORNER })
|
__addPoint(ctx, p[0], p[1], {.CORNER})
|
||||||
i += 3
|
i += 3
|
||||||
|
|
||||||
case .LINE_TO:
|
case .LINE_TO:
|
||||||
p := ctx.commands[i + 1:]
|
p := ctx.commands[i + 1:]
|
||||||
__addPoint(ctx, p[0], p[1], { .CORNER })
|
__addPoint(ctx, p[0], p[1], {.CORNER})
|
||||||
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:]
|
||||||
__tesselateBezier(ctx, last.x,last.y, cp1[0],cp1[1], cp2[0],cp2[1], p[0],p[1], 0, { .CORNER })
|
__tesselateBezier(ctx, last.x,last.y, cp1[0],cp1[1], cp2[0],cp2[1], p[0],p[1], 0, {.CORNER})
|
||||||
}
|
}
|
||||||
|
|
||||||
i += 7
|
i += 7
|
||||||
@@ -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.
|
||||||
@@ -1551,7 +1535,7 @@ __flattenPaths :: proc(ctx: ^Context) {
|
|||||||
p1 := &pts[0]
|
p1 := &pts[0]
|
||||||
if __ptEquals(p0.x,p0.y, p1.x,p1.y, ctx.distTol) {
|
if __ptEquals(p0.x,p0.y, p1.x,p1.y, ctx.distTol) {
|
||||||
path.count -= 1
|
path.count -= 1
|
||||||
p0 = &pts[path.count - 1]
|
p0 = &pts[path.count-1]
|
||||||
path.closed = true
|
path.closed = true
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1618,24 +1602,19 @@ __chooseBevel :: proc(
|
|||||||
|
|
||||||
// set vertex & increase slice position (decreases length)
|
// set vertex & increase slice position (decreases length)
|
||||||
__vset :: proc(dst: ^[]Vertex, x, y, u, v: f32, loc := #caller_location) {
|
__vset :: proc(dst: ^[]Vertex, x, y, u, v: f32, loc := #caller_location) {
|
||||||
dst[0] = { x, y, u, v }
|
dst[0] = {x, y, u, v}
|
||||||
dst^ = dst[1:]
|
dst^ = dst[1:]
|
||||||
}
|
}
|
||||||
|
|
||||||
__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
|
||||||
@@ -1659,11 +1638,11 @@ __roundJoin :: proc(
|
|||||||
rx := p1.x + math.cos(a) * rw
|
rx := p1.x + math.cos(a) * rw
|
||||||
ry := p1.y + math.sin(a) * rw
|
ry := p1.y + math.sin(a) * rw
|
||||||
__vset(dst, p1.x, p1.y, 0.5, 1)
|
__vset(dst, p1.x, p1.y, 0.5, 1)
|
||||||
__vset(dst, rx, ry, ru,1)
|
__vset(dst, rx, ry, ru, 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
__vset(dst, lx1, ly1, lu,1)
|
__vset(dst, lx1, ly1, lu, 1)
|
||||||
__vset(dst, p1.x - dlx1*rw, p1.y - dly1*rw, ru,1)
|
__vset(dst, p1.x - dlx1*rw, p1.y - dly1*rw, ru, 1)
|
||||||
} else {
|
} else {
|
||||||
rx0,ry0,rx1,ry1: f32
|
rx0,ry0,rx1,ry1: f32
|
||||||
__chooseBevel(.INNER_BEVEL in p1.flags, p0, p1, -rw, &rx0, &ry0, &rx1, &ry1)
|
__chooseBevel(.INNER_BEVEL in p1.flags, p0, p1, -rw, &rx0, &ry0, &rx1, &ry1)
|
||||||
@@ -1673,8 +1652,8 @@ __roundJoin :: proc(
|
|||||||
a1 += math.PI * 2
|
a1 += math.PI * 2
|
||||||
}
|
}
|
||||||
|
|
||||||
__vset(dst, p1.x + dlx0*rw, p1.y + dly0*rw, lu,1)
|
__vset(dst, p1.x + dlx0*rw, p1.y + dly0*rw, lu, 1)
|
||||||
__vset(dst, rx0, ry0, ru,1)
|
__vset(dst, rx0, ry0, ru, 1)
|
||||||
|
|
||||||
temp := int(math.ceil((a1 - a0) / math.PI * f32(ncap)))
|
temp := int(math.ceil((a1 - a0) / math.PI * f32(ncap)))
|
||||||
n := clamp(temp, 2, ncap)
|
n := clamp(temp, 2, ncap)
|
||||||
@@ -1688,24 +1667,19 @@ __roundJoin :: proc(
|
|||||||
__vset(dst, p1.x, p1.y, 0.5, 1)
|
__vset(dst, p1.x, p1.y, 0.5, 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
__vset(dst, p1.x + dlx1*rw, p1.y + dly1*rw, lu,1)
|
__vset(dst, p1.x + dlx1*rw, p1.y + dly1*rw, lu, 1)
|
||||||
__vset(dst, rx1, ry1, ru,1)
|
__vset(dst, rx1, ry1, ru, 1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
__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
|
||||||
@@ -1713,59 +1687,59 @@ __bevelJoin :: proc(
|
|||||||
if .LEFT in p1.flags {
|
if .LEFT in p1.flags {
|
||||||
__chooseBevel(.INNER_BEVEL in p1.flags, p0, p1, lw, &lx0,&ly0, &lx1,&ly1)
|
__chooseBevel(.INNER_BEVEL in p1.flags, p0, p1, lw, &lx0,&ly0, &lx1,&ly1)
|
||||||
|
|
||||||
__vset(dst, lx0, ly0, lu,1)
|
__vset(dst, lx0, ly0, lu, 1)
|
||||||
__vset(dst, p1.x - dlx0*rw, p1.y - dly0*rw, ru,1)
|
__vset(dst, p1.x - dlx0*rw, p1.y - dly0*rw, ru, 1)
|
||||||
|
|
||||||
if .BEVEL in p1.flags {
|
if .BEVEL in p1.flags {
|
||||||
__vset(dst, lx0, ly0, lu,1)
|
__vset(dst, lx0, ly0, lu, 1)
|
||||||
__vset(dst, p1.x - dlx0*rw, p1.y - dly0*rw, ru,1)
|
__vset(dst, p1.x - dlx0*rw, p1.y - dly0*rw, ru, 1)
|
||||||
|
|
||||||
__vset(dst, lx1, ly1, lu,1)
|
__vset(dst, lx1, ly1, lu, 1)
|
||||||
__vset(dst, p1.x - dlx1*rw, p1.y - dly1*rw, ru,1)
|
__vset(dst, p1.x - dlx1*rw, p1.y - dly1*rw, ru, 1)
|
||||||
} else {
|
} else {
|
||||||
rx0 = p1.x - p1.dmx * rw
|
rx0 = p1.x - p1.dmx * rw
|
||||||
ry0 = p1.y - p1.dmy * rw
|
ry0 = p1.y - p1.dmy * rw
|
||||||
|
|
||||||
__vset(dst, p1.x, p1.y, 0.5,1)
|
__vset(dst, p1.x, p1.y, 0.5, 1)
|
||||||
__vset(dst, p1.x - dlx0*rw, p1.y - dly0*rw, ru,1)
|
__vset(dst, p1.x - dlx0*rw, p1.y - dly0*rw, ru, 1)
|
||||||
|
|
||||||
__vset(dst, rx0, ry0, ru,1)
|
__vset(dst, rx0, ry0, ru, 1)
|
||||||
__vset(dst, rx0, ry0, ru,1)
|
__vset(dst, rx0, ry0, ru, 1)
|
||||||
|
|
||||||
__vset(dst, p1.x, p1.y, 0.5,1)
|
__vset(dst, p1.x, p1.y, 0.5, 1)
|
||||||
__vset(dst, p1.x - dlx1*rw, p1.y - dly1*rw, ru,1)
|
__vset(dst, p1.x - dlx1*rw, p1.y - dly1*rw, ru, 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
__vset(dst, lx1, ly1, lu,1)
|
__vset(dst, lx1, ly1, lu, 1)
|
||||||
__vset(dst, p1.x - dlx1*rw, p1.y - dly1*rw, ru,1)
|
__vset(dst, p1.x - dlx1*rw, p1.y - dly1*rw, ru, 1)
|
||||||
} else {
|
} else {
|
||||||
__chooseBevel(.INNER_BEVEL in p1.flags, p0, p1, -rw, &rx0,&ry0, &rx1,&ry1)
|
__chooseBevel(.INNER_BEVEL in p1.flags, p0, p1, -rw, &rx0,&ry0, &rx1,&ry1)
|
||||||
|
|
||||||
__vset(dst, p1.x + dlx0*lw, p1.y + dly0*lw, lu,1)
|
__vset(dst, p1.x + dlx0*lw, p1.y + dly0*lw, lu, 1)
|
||||||
__vset(dst, rx0, ry0, ru,1)
|
__vset(dst, rx0, ry0, ru, 1)
|
||||||
|
|
||||||
if .BEVEL in p1.flags {
|
if .BEVEL in p1.flags {
|
||||||
__vset(dst, p1.x + dlx0*lw, p1.y + dly0*lw, lu,1)
|
__vset(dst, p1.x + dlx0*lw, p1.y + dly0*lw, lu, 1)
|
||||||
__vset(dst, rx0, ry0, ru,1)
|
__vset(dst, rx0, ry0, ru, 1)
|
||||||
|
|
||||||
__vset(dst, p1.x + dlx1*lw, p1.y + dly1*lw, lu,1)
|
__vset(dst, p1.x + dlx1*lw, p1.y + dly1*lw, lu, 1)
|
||||||
__vset(dst, rx1, ry1, ru,1)
|
__vset(dst, rx1, ry1, ru, 1)
|
||||||
} else {
|
} else {
|
||||||
lx0 = p1.x + p1.dmx * lw
|
lx0 = p1.x + p1.dmx * lw
|
||||||
ly0 = p1.y + p1.dmy * lw
|
ly0 = p1.y + p1.dmy * lw
|
||||||
|
|
||||||
__vset(dst, p1.x + dlx0*lw, p1.y + dly0*lw, lu,1)
|
__vset(dst, p1.x + dlx0*lw, p1.y + dly0*lw, lu, 1)
|
||||||
__vset(dst, p1.x, p1.y, 0.5,1)
|
__vset(dst, p1.x, p1.y, 0.5, 1)
|
||||||
|
|
||||||
__vset(dst, lx0, ly0, lu,1)
|
__vset(dst, lx0, ly0, lu, 1)
|
||||||
__vset(dst, lx0, ly0, lu,1)
|
__vset(dst, lx0, ly0, lu, 1)
|
||||||
|
|
||||||
__vset(dst, p1.x + dlx1*lw, p1.y + dly1*lw, lu,1)
|
__vset(dst, p1.x + dlx1*lw, p1.y + dly1*lw, lu, 1)
|
||||||
__vset(dst, p1.x, p1.y, 0.5,1)
|
__vset(dst, p1.x, p1.y, 0.5, 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
__vset(dst, p1.x + dlx1*lw, p1.y + dly1*lw, lu,1)
|
__vset(dst, p1.x + dlx1*lw, p1.y + dly1*lw, lu, 1)
|
||||||
__vset(dst, rx1, ry1, ru,1)
|
__vset(dst, rx1, ry1, ru, 1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1828,7 +1802,7 @@ __roundCapStart :: proc(
|
|||||||
ax := math.cos(a) * w
|
ax := math.cos(a) * w
|
||||||
ay := math.sin(a) * w
|
ay := math.sin(a) * w
|
||||||
__vset(dst, px - dlx*ax - dx*ay, py - dly*ax - dy*ay, u0,1)
|
__vset(dst, px - dlx*ax - dx*ay, py - dly*ax - dy*ay, u0,1)
|
||||||
__vset(dst, px, py, 0.5,1)
|
__vset(dst, px, py, 0.5, 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
__vset(dst, px + dlx*w, py + dly*w, u0,1)
|
__vset(dst, px + dlx*w, py + dly*w, u0,1)
|
||||||
@@ -1855,7 +1829,7 @@ __roundCapEnd :: proc(
|
|||||||
a := f32(i) / f32(ncap - 1) * math.PI
|
a := f32(i) / f32(ncap - 1) * math.PI
|
||||||
ax := math.cos(a) * w
|
ax := math.cos(a) * w
|
||||||
ay := math.sin(a) * w
|
ay := math.sin(a) * w
|
||||||
__vset(dst, px, py, 0.5,1)
|
__vset(dst, px, py, 0.5, 1)
|
||||||
__vset(dst, px - dlx*ax + dx*ay, py - dly*ax + dy*ay, u0,1)
|
__vset(dst, px - dlx*ax + dx*ay, py - dly*ax + dy*ay, u0,1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -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
|
||||||
@@ -2135,25 +2108,25 @@ __expandFill :: proc(
|
|||||||
if .LEFT in p1.flags {
|
if .LEFT in p1.flags {
|
||||||
lx := p1.x + p1.dmx * woff
|
lx := p1.x + p1.dmx * woff
|
||||||
ly := p1.y + p1.dmy * woff
|
ly := p1.y + p1.dmy * woff
|
||||||
__vset(&dst, lx, ly, 0.5,1)
|
__vset(&dst, lx, ly, 0.5, 1)
|
||||||
} else {
|
} else {
|
||||||
lx0 := p1.x + dlx0 * woff
|
lx0 := p1.x + dlx0 * woff
|
||||||
ly0 := p1.y + dly0 * woff
|
ly0 := p1.y + dly0 * woff
|
||||||
lx1 := p1.x + dlx1 * woff
|
lx1 := p1.x + dlx1 * woff
|
||||||
ly1 := p1.y + dly1 * woff
|
ly1 := p1.y + dly1 * woff
|
||||||
__vset(&dst, lx0, ly0, 0.5,1)
|
__vset(&dst, lx0, ly0, 0.5, 1)
|
||||||
__vset(&dst, lx1, ly1, 0.5,1)
|
__vset(&dst, lx1, ly1, 0.5, 1)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
__vset(&dst, p1.x + (p1.dmx * woff), p1.y + (p1.dmy * woff), 0.5,1)
|
__vset(&dst, p1.x + (p1.dmx * woff), p1.y + (p1.dmy * woff), 0.5, 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
p0 = p1
|
p0 = p1
|
||||||
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,12 +2155,12 @@ __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 {
|
||||||
__vset(&dst, p1.x + (p1.dmx * lw), p1.y + (p1.dmy * lw), lu,1)
|
__vset(&dst, p1.x + (p1.dmx * lw), p1.y + (p1.dmy * lw), lu, 1)
|
||||||
__vset(&dst, p1.x - (p1.dmx * rw), p1.y - (p1.dmy * rw), ru,1)
|
__vset(&dst, p1.x - (p1.dmx * rw), p1.y - (p1.dmy * rw), ru, 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
p0 = p1
|
p0 = p1
|
||||||
@@ -2195,8 +2168,8 @@ __expandFill :: proc(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Loop it
|
// Loop it
|
||||||
__vset(&dst, verts[dst_index + 0].x, verts[dst_index + 0].y, lu,1)
|
__vset(&dst, verts[dst_index + 0].x, verts[dst_index + 0].y, lu, 1)
|
||||||
__vset(&dst, verts[dst_index + 1].x, verts[dst_index + 1].y, ru,1)
|
__vset(&dst, verts[dst_index + 1].x, verts[dst_index + 1].y, ru, 1)
|
||||||
|
|
||||||
dst_diff := dst_start_length - len(dst)
|
dst_diff := dst_start_length - len(dst)
|
||||||
path.stroke = verts[dst_index:dst_index + dst_diff]
|
path.stroke = verts[dst_index:dst_index + dst_diff]
|
||||||
@@ -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
|
||||||
@@ -2910,12 +2872,12 @@ TextIcon :: proc(ctx: ^Context, xpos, ypos: f32, codepoint: rune) -> f32 {
|
|||||||
TransformPoint(&c[6], &c[7], state.xform, q.x0 * invscale, q.y1 * invscale)
|
TransformPoint(&c[6], &c[7], state.xform, q.x0 * invscale, q.y1 * invscale)
|
||||||
|
|
||||||
// Create triangles
|
// Create triangles
|
||||||
verts[0] = { c[0], c[1], q.s0, q.t0 }
|
verts[0] = {c[0], c[1], q.s0, q.t0}
|
||||||
verts[1] = { c[4], c[5], q.s1, q.t1 }
|
verts[1] = {c[4], c[5], q.s1, q.t1}
|
||||||
verts[2] = { c[2], c[3], q.s1, q.t0 }
|
verts[2] = {c[2], c[3], q.s1, q.t0}
|
||||||
verts[3] = { c[0], c[1], q.s0, q.t0 }
|
verts[3] = {c[0], c[1], q.s0, q.t0}
|
||||||
verts[4] = { c[6], c[7], q.s0, q.t1 }
|
verts[4] = {c[6], c[7], q.s0, q.t1}
|
||||||
verts[5] = { c[4], c[5], q.s1, q.t1 }
|
verts[5] = {c[4], c[5], q.s1, q.t1}
|
||||||
|
|
||||||
ctx.textureDirty = true
|
ctx.textureDirty = true
|
||||||
__renderText(ctx, verts[:])
|
__renderText(ctx, verts[:])
|
||||||
@@ -2986,12 +2948,12 @@ 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}
|
||||||
verts[nverts + 4] = { c[6], c[7], q.s0, q.t1 }
|
verts[nverts+4] = {c[6], c[7], q.s0, q.t1}
|
||||||
verts[nverts + 5] = { c[4], c[5], q.s1, q.t1 }
|
verts[nverts+5] = {c[4], c[5], q.s1, q.t1}
|
||||||
nverts += 6
|
nverts += 6
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -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
|
||||||
@@ -3341,7 +3304,7 @@ TextBreakLines :: proc(
|
|||||||
// NOTE a bit hacky, row.start / row.end need to work with last string range
|
// NOTE a bit hacky, row.start / row.end need to work with last string range
|
||||||
last = text^
|
last = text^
|
||||||
// advance early
|
// advance early
|
||||||
next := rows[nrows - 1].next
|
next := rows[nrows-1].next
|
||||||
text^ = text[next:]
|
text^ = text[next:]
|
||||||
// terminate the for loop on non ok
|
// terminate the for loop on non ok
|
||||||
ok = nrows != 0
|
ok = nrows != 0
|
||||||
@@ -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
|
||||||
@@ -3422,7 +3384,7 @@ TextBoxBounds :: proc(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if bounds != nil {
|
if bounds != nil {
|
||||||
bounds^ = { minx, miny, maxx, maxy }
|
bounds^ = {minx, miny, maxx, maxy}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user