From 9dcaefe7c93743cf97e2fbdd13da5ca5dc810bd9 Mon Sep 17 00:00:00 2001 From: Jean-Marie 'Histausse' Mineau Date: Sat, 25 Oct 2025 23:40:56 +0200 Subject: [PATCH] new icons, and outline --- slides/icons.typ | 576 +++++++++++++++++++++++++++++++++----------- slides/lib.typ | 29 +-- slides/outlines.typ | 569 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 1011 insertions(+), 163 deletions(-) create mode 100644 slides/outlines.typ diff --git a/slides/icons.typ b/slides/icons.typ index a4c8e1c..1ba48e8 100644 --- a/slides/icons.typ +++ b/slides/icons.typ @@ -5,10 +5,11 @@ } #let polar( - x0: 0pt, y0: 0pt, + origin: (0pt, 0pt), r: 0pt, th: 0deg, ) = { + let (x0, y0) = origin ( x0 + r * calc.cos(th), y0 + r * calc.sin(th), @@ -21,11 +22,10 @@ th0: 0deg, th1: 0deg, ) = { - let (x0, y0) = center - let (x1, y1) = polar(x0: x0, y0: y0, r: r, th: th0) - let (x2, y2) = polar(x0: x0, y0: y0, r: r, th: th1) - let (x_u1, y_u1) = polar(x0: 0pt, y0: 0pt, r: 1pt, th: th0 + 90deg) - let (x_u2, y_u2) = polar(x0: 0pt, y0: 0pt, r: 1pt, th: th1 + 90deg) + let (x1, y1) = polar(origin: center, r: r, th: th0) + let (x2, y2) = polar(origin: center, r: r, th: th1) + let (x_u1, y_u1) = polar(origin: (0pt, 0pt), r: 1pt, th: th0 + 90deg) + let (x_u2, y_u2) = polar(origin: (0pt, 0pt), r: 1pt, th: th1 + 90deg) let th = th1 - th0 let l = 4 * r / 3 * calc.tan(th / 4) / 1pt @@ -37,13 +37,24 @@ ((x1, y1), (x_q1, y_q1), (x_q2, y_q2), (x2, y2)) } +#let fit_txt_to_width(txt, width) = context { + let size = measure(txt) + if size.width == 0 { + txt + } else { + let ratio = width / size.width + set text(size: ratio * 1em) + txt + } +} + #let circle_path( center: (0pt, 0pt), r: 0pt, ) = { ( curve.move( - polar(x0: center.at(0), y0: center.at(1), r: r, th: 0deg) + polar(origin: center, r: r, th: 0deg) ), ..for i in range(4) { let (p0, q0, q1, p1) = arc(center: center, r: r, th0: i*90deg, th1: (i+1)*90deg) @@ -53,6 +64,65 @@ ) } +#let arrow(start, end, ..points, stroke: 3pt + black) = { + let strk = std.stroke(stroke) + for pt in points.pos() { + let strk = std.stroke( + paint: strk.paint, + thickness: strk.thickness, + join: "round", + ) + place( + bottom + left, + line( + start: start, + end: end, + stroke: strk + ) + ) + place( + bottom + left, + dx: end.at(0) - strk.thickness / 2, + dy: end.at(1) + strk.thickness / 2, + circle( + radius: strk.thickness / 2, + stroke: none, + fill: strk.paint, + ) + ) + start = end + end = pt + } + place( + bottom + left, + line( + start: start, + end: end, + stroke: strk + ) + ) + let (xe, ye) = end + let (xs, ys) = start + let w = xe.pt() - xs.pt() + let h = ye.pt() - ys.pt() + let len = if w == 0pt and h == 0pt { + 1pt + } else { + calc.sqrt(w*w + h*h) + } + let cos = w / len + let sin = h / len + + place( + bottom + left, + polygon( + fill: strk.paint, + stroke: strk, + end, + (xe + strk.thickness * (sin - cos), ye - strk.thickness * (sin + cos )), + (xe - strk.thickness * (sin + cos), ye - strk.thickness * (sin - cos )), + )) +} #let phone( width: 200pt, @@ -156,16 +226,16 @@ ..for i in range(nb-teeth) { let angle = i * 360deg / nb-teeth let center_off = calc.sin(teeth-angle/2) * in-rad - let (x0_1, y0_1) = polar(x0: x0, y0: y0, r: center_off, th: angle - 90deg) - let (x0_2, y0_2) = polar(x0: x0, y0: y0, r: center_off, th: angle + 90deg) + let (x0_1, y0_1) = polar(origin: (x0, y0), r: center_off, th: angle - 90deg) + let (x0_2, y0_2) = polar(origin: (x0, y0), r: center_off, th: angle + 90deg) - let p0 = polar(x0: x0_1, y0: y0_1, r: out-rad, th: angle) - let p1 = polar(x0: x0_2, y0: y0_2, r: out-rad, th: angle) - let p2 = polar(x0: x0, y0: y0, r: in-rad, th: angle + inter-teeth-angle/2) - let p3 = polar(x0: x0, y0: y0, r: in-rad, th: angle + 3*inter-teeth-angle/2) + let p0 = polar(origin: (x0_1, y0_1), r: out-rad, th: angle) + let p1 = polar(origin: (x0_2, y0_2), r: out-rad, th: angle) + let p2 = polar(origin: (x0, y0), r: in-rad, th: angle + inter-teeth-angle/2) + let p3 = polar(origin: (x0, y0), r: in-rad, th: angle + 3*inter-teeth-angle/2) - let u2 = polar(x0: 0pt, y0: 0pt, r: 1pt, th: angle + inter-teeth-angle/2 + 90deg) - let u3 = polar(x0: 0pt, y0: 0pt, r: 1pt, th: angle + 3*inter-teeth-angle/2 + 90deg) + let u2 = polar(origin: (0pt, 0pt), r: 1pt, th: angle + inter-teeth-angle/2 + 90deg) + let u3 = polar(origin: (0pt, 0pt), r: 1pt, th: angle + 3*inter-teeth-angle/2 + 90deg) let l2 = 4 * in-rad / 3 * calc.tan(inter-teeth-angle / 4) / 1pt let l3 = -l2 //let l2 = 1 @@ -197,10 +267,10 @@ curve.close(mode: "straight"), ..for i in range(4) { let angle = i * 360deg / 4 - let p0 = polar(x0: x0, y0: y0, r: center-rad, th: angle) - let u0 = polar(x0: 0pt, y0: 0pt, r: 1pt, th: angle + 90deg) - let p1 = polar(x0: x0, y0: y0, r: center-rad, th: angle+90deg) - let u1 = polar(x0: 0pt, y0: 0pt, r: 1pt, th: angle + 180deg) + let p0 = polar(origin: (x0, y0), r: center-rad, th: angle) + let u0 = polar(origin: (0pt, 0pt), r: 1pt, th: angle + 90deg) + let p1 = polar(origin: (x0, y0), r: center-rad, th: angle+90deg) + let u1 = polar(origin: (0pt, 0pt), r: 1pt, th: angle + 180deg) let l0 = 4 * center-rad / 3 * calc.tan(90deg / 4) / 1pt let l1 = -l0 let q0 = (p0.at(0) + l0 * u0.at(0), p0.at(1) + l0 * u0.at(1)) @@ -329,8 +399,7 @@ ..for i in range(6) { let last_hex_p = hex_pi hex_pi = polar( - x0: hex_pi.at(0), - y0: hex_pi.at(1), + origin: hex_pi, r: hex_side, th: hex_thi, ) @@ -395,13 +464,6 @@ })) } -#let apk(height: 100pt) = image("imgs/ico/apk.svg", height: height) -#let apks(height: 100pt) = { - place(apk(height: height)) - place(dx: height * 4 / 10, dy: -height * 3 / 10, apk(height: height)) - place(dx: height * 6 / 10, dy: height / 10, apk(height: height)) -} - #let transfo(height: 200pt) = { box(width: height, height: height, { place( @@ -433,67 +495,23 @@ }) } -#let report(height: 100pt) = image("imgs/ico/report.svg", height: height) - -#let th-outline(height: 600pt, width: 900pt, hide-static: false) = { - let small-ico-h = height / 16 - let big-ico-h = height / 6 - - let static = stack(dir: ltr, - apks(height: small-ico-h), - h(big-ico-h), - $ -> $, - h(big-ico-h), - analyse(height: big-ico-h), - h(big-ico-h), - $ -> $, - h(big-ico-h), - report(height: small-ico-h), - ) - - let th = stack(dir: ltr, - apks(height: small-ico-h), - h(big-ico-h*2/3), - $->$, - h(big-ico-h/4), - phone(height: height/4, width: height/8), - h(big-ico-h/4), - $->$, - h(big-ico-h/4), - transfo(height: big-ico-h), - h(big-ico-h/4), - $->$, - h(big-ico-h/4), - apk(height: small-ico-h), - h(big-ico-h/4), - $->$, - h(big-ico-h/4), - analyse(height: big-ico-h), - h(big-ico-h/4), - $->$, - h(big-ico-h/4), - report(height: small-ico-h), - ) - - box(height: 600pt, width: 900pt, - stack( - if hide-static { hide(static)} else { static }, - v(big-ico-h), - th, - ) - ) -} - #let file( height: 200pt, stroke: black + 3pt, fill: white, fill_back: none, + corner-rad: none, type: "cornered", body: [], ) = { let width = height / 1.414 - let fill_back = if fill_back == none { fill.lighten(30%) } else { fill_back } + let fill_back = if fill_back == none and fill == none { + none + } else if fill_back == none { + fill.lighten(30%) + } else { + fill_back + } let types = ( "cornered", @@ -504,55 +522,115 @@ type in types, message: "type for file must be in " + repr(types) ) + let corner-rad = if corner-rad == none { + if type == "clip" { + width / 10 + } else { + none + } + } else { + corner-rad + } + let clip_head_width_up = width / 2 + let clip_head_width_dw = width * 2 / 5 + let clip_head_height = width / 10 - let corner = ( + let corner_lup_pth = if corner-rad == none { + (curve.move((0pt, 0pt)),) + } else { + (curve.move((0pt, 0pt)),) + ( + curve.move((0pt, corner-rad)), + curve.cubic( + ..arc( + center: (corner-rad, corner-rad), + r: corner-rad, + th0:-180deg, + th1: -90deg, + ).slice(1) + ) + ) + } + let corner_rdw_pth = if corner-rad == none { + (curve.line((width, height)),) + } else { + ( + curve.line((width, height - corner-rad)), + curve.cubic( + ..arc( + center: (width - corner-rad, height - corner-rad), + r: corner-rad, + th0: 0deg, + th1: 90deg, + ).slice(1) + ) + ) + } + let corner_ldw_pth = if corner-rad == none { + (curve.line((0pt, height)),) + } else { + ( + curve.line((corner-rad, height)), + curve.cubic( + ..arc( + center: (corner-rad, height - corner-rad), + r: corner-rad, + th0: 90deg, + th1: 180deg, + ).slice(1) + ) + ) + } + + let corner_rup = ( width - height / 5, height / 5, ) - let corner_up = ( - corner.at(0), + let corner_rup_up = ( + corner_rup.at(0), 0pt, ) - let corner_dw = ( + let corner_rup_dw = ( width, - corner.at(1) + corner_rup.at(1) ) - /* - let corner_up_q = ( - (corner_up.at(0) + width) / 2, - corner_up.at(1) - ) - let corner_q0 = ( - corner.at(0), - corner.at(1) - ) - let corner_q1 = ( - corner.at(0), - corner.at(1) - ) - let corner_dw_q = ( - corner_dw.at(0), - corner_dw.at(1) / 3 - )*/ - let corner_pth = if type == "cornered" { + let corner_rup_pth = if type == "cornered" and corner-rad == none { ( - curve.line(corner_up), - curve.line(corner), - //curve.cubic( - // corner_up_q, - // corner_q0, - // corner - //), - curve.line(corner_dw) - //curve.cubic( - // corner_q1, - // corner_dw_q, - // corner_dw, - //), + curve.line(corner_rup_up), + curve.line(corner_rup), + curve.line(corner_rup_dw) ) - } else { + } else if type == "cornered" { + ( + curve.line(corner_rup_up), + curve.line(( + corner_rup.at(0), + corner_rup.at(1) - corner-rad + )), + curve.cubic(..arc( + center: ( + corner_rup.at(0) + corner-rad, + corner_rup.at(1) - corner-rad + ), + r: corner-rad, + th0: 180deg, + th1: 90deg, + ).slice(1)), + curve.line(corner_rup_dw) + ) + }else if corner-rad == none { (curve.line((width, 0pt)),) + } else { + ( + curve.line((width - corner-rad, 0pt)), + curve.cubic(..arc( + center: (width - corner-rad, corner-rad), + r: corner-rad, + th0: -90deg, + th1: 0deg, + ).slice(1)) + ) } box( @@ -561,6 +639,7 @@ //stroke: black, { if type == "cornered" { + let stroke = std.stroke(stroke) let stroke = std.stroke( join: "round", paint: stroke.paint, @@ -570,9 +649,8 @@ curve( fill: fill_back, stroke: stroke, - curve.move(corner_up), - curve.line(corner), - curve.line(corner_dw), + curve.move(corner_rup_up), + ..corner_rup_pth, curve.close() ) }) @@ -581,13 +659,45 @@ curve( fill: fill, stroke: stroke, - curve.move((0pt, 0pt)), - ..corner_pth, - curve.line((width, height)), - curve.line((0pt, height)), + ..corner_lup_pth, + ..corner_rup_pth, + ..corner_rdw_pth, + ..corner_ldw_pth, curve.close(), ) }) + if type == "clip" { + place( + left+top, + curve( + fill: none, + stroke: stroke, + curve.move(( + (width - clip_head_width_up) / 2, + 0pt + )), + curve.line(( + (width - clip_head_width_dw) / 2, + clip_head_height + )), + curve.line(( + (width + clip_head_width_dw) / 2, + clip_head_height + )), + curve.line(( + (width + clip_head_width_up) / 2, + 0pt + )), + ) + ) + } + place(top+left, + box( + width: width, + height: height, + body + ) + ) } ) } @@ -725,8 +835,7 @@ th1: - antenna_angle + antenna_width_angle/2, ) let antenna_r_c = polar( - x0: head_center.at(0), - y0: head_center.at(1), + origin: head_center, r: body_width / 2 + antenna_length - antenna_width/2, th: - antenna_angle ) @@ -776,8 +885,7 @@ ) let antenna_l_c = polar( - x0: head_center.at(0), - y0: head_center.at(1), + origin: head_center, r: body_width / 2 + antenna_length - antenna_width/2, th: 180deg + antenna_angle ) @@ -817,8 +925,7 @@ let eye_l = circle_path( center: polar( - x0: head_center.at(0), - y0: head_center.at(1), + origin: head_center, r: rad_eye_in_head, th: 180deg + angle_eye, ), @@ -826,8 +933,7 @@ ) let eye_r = circle_path( center: polar( - x0: head_center.at(0), - y0: head_center.at(1), + origin: head_center, r: rad_eye_in_head, th: - angle_eye, ), @@ -1007,16 +1113,216 @@ ) } +#let apk( + height: 200pt, + stroke: black + 3pt, + fill: green, + fill_back: none, + android_fill: white, + txt: ".apk" +) = { + let body = layout( size => { + let droid = android( + height: size.height * 2/3 - size.height * 0.05, + stroke: none, + stroke_eye: none, + fill: android_fill, + fill_eye: android_fill, + ) + let droid_size = measure(droid) + place( + top+center, + dy: size.height * 0.1, + droid + ) + let txt = fit_txt_to_width( + text( + fill: android_fill, + smallcaps(txt) + ), + size.width * 0.8 + ) + let txt_size = measure(txt) + place( + top+center, + dy: size.height - size.height * 0.1 - txt_size.height, + txt + ) + }) + file( + height: height, + stroke: stroke, + fill: fill, + fill_back: fill_back, + corner-rad: height / 1.414 / 10, + body: body + ) +} + +#let report( + height: 200pt, + stroke: black + 3pt, + fill: white, +) = { + let body = layout( size => { + let node_radius = height / 25 + let node = circle( + radius: node_radius, + fill: fill, + stroke: stroke + ) + let nodes_x0 = size.width * 0.15 + let nodes_y0 = size.height * (1/3 + 0.05) + let n0 = ( + nodes_x0, + nodes_y0 + ) + let n1 = ( + nodes_x0 + size.width * 0.1, + nodes_y0 + size.height * (-0.12) + ) + let n2 = ( + nodes_x0 + size.width * 0.25, + nodes_y0 + size.height * (-0.06) + ) + let n3 = ( + nodes_x0 + size.width * 0.35, + nodes_y0 + size.height * (-0.2) + ) + let last_n = none + for n in (n0, n1, n2, n3) { + let stroke = std.stroke(stroke) + let stroke = std.stroke( + join: "round", + paint: stroke.paint, + thickness: node_radius/3, + ) + if last_n != none { + place( + top+left, + line( + start: last_n, + end: n, + stroke: stroke + ) + ) + } + last_n = n + } + for n in (n0, n1, n2, n3) { + place( + top+left, + dx: n.at(0) - node_radius, + dy: n.at(1) - node_radius, + node + ) + } + + let r_gap = size.width / 10 + let r_x0 = size.width / 2 + r_gap + let r_y0 = size.height / 2 + r_gap + let r_w = size.width / 2 - 2*r_gap + let r_h = size.height / 2 - 2*r_gap + + place( + top+left, + dx: r_x0, + dy: r_y0, + rect( + fill: white, + stroke: stroke, + width: r_w, + height: r_h + ) + ) + + let nb_line = 8 + let line_width = size.height / 30 + let line_x_gap = line_width + let line_y_gap_up = (size.height * 3 / 20) + let line_y_gap_dw = size.height / 20 + let line_spacing = ( + size.height - + line_width - + line_y_gap_up - + line_y_gap_dw + ) / (nb_line - 1) + + let line_x0_0 = n3.at(0) + node_radius + line_x_gap + line_width / 2 + let line_x0_1 = line_x_gap + line_width / 2 + let line_x1_0 = size.width - line_x0_1 + let line_x1_1 = r_x0 - line_x_gap - line_width / 2 + let line_y0 = line_y_gap_up + line_width / 2 + + for i in range(nb_line) { + let stroke = std.stroke(stroke) + let stroke = std.stroke( + join: "round", + cap: "round", + paint: stroke.paint, + thickness: line_width, + ) + let y = line_y0 + i * line_spacing + + let x0 = if ( + (y > n3.at(1) - node_radius - line_width / 2) and + (y < n0.at(1) + node_radius + line_width / 2) + + ){ + line_x0_0 + } else { + line_x0_1 + } + let x1 = if ( + (y > r_y0 - line_width / 2) and + (y < r_y0 + r_h + line_width / 2) + ) { + line_x1_1 + } else { + line_x1_0 + } + place( + left+top, + line( + stroke: stroke, + start: (x0, y), + end: (x1, y), + ) + ) + } + //mark(..n0) + }) + file( + height: height, + stroke: stroke, + type: "clip", + fill: fill, + body: body + ) +} + + +#let apks(height: 100pt) = { + place(apk(height: height)) + place(dx: height * 4 / 10, dy: -height * 3 / 10, apk(height: height)) + place(dx: height * 6 / 10, dy: height / 10, apk(height: height)) +} + +#report(height: 200pt) + //#gear() //#phone(body: [Hello World!]) //#wrench() -#file(fill: green) -#h(2em) -#android(height: 200pt) +//#file(fill: white, type: "clip")//corner-rad: 10pt) +//#h(2em) +//#android(height: 200pt) + /* #apk() +#apk(fill: red) +#apk(android_fill: red) #v(4em) #apks() #v(12em) diff --git a/slides/lib.typ b/slides/lib.typ index 37e7073..a91744c 100644 --- a/slides/lib.typ +++ b/slides/lib.typ @@ -2,7 +2,7 @@ #import "figures.typ": figures, get_figure #import "../lib.typ": pb1-text, pb2-text, pb3-text -#import "icons.typ": th-outline +#import "icons.typ": arrow #let pirat-color = ( black: rgb("#000000"), @@ -117,30 +117,3 @@ pirat-color.red, #let eye-2 = ghost.with("imgs/ghosts/eye-2.png") #let eye-3 = ghost.with("imgs/ghosts/eye-3.png") #let eye-4 = ghost.with("imgs/ghosts/eye-4.png") - -#let arrow(start, end, strk: 3pt + black) = { - let strk = stroke(strk) - start.at(1) = -start.at(1) - end.at(1) = -end.at(1) - let (xe, ye) = end - let (xs, ys) = start - let w = xe.pt() - xs.pt() - let h = ye.pt() - ys.pt() - let len = if w == 0pt and h == 0pt { - 1pt - } else { - calc.sqrt(w*w + h*h) - } - let cos = w / len - let sin = h / len - - place(bottom + left, line(start: start, end: end, stroke: strk)) - place(bottom + left, polygon( - fill: strk.paint, - stroke: strk, - end, - (xe + strk.thickness * (sin - cos), ye - strk.thickness * (sin + cos )), - (xe - strk.thickness * (sin + cos), ye - strk.thickness * (sin - cos )), - )) -} - diff --git a/slides/outlines.typ b/slides/outlines.typ new file mode 100644 index 0000000..d9c4f61 --- /dev/null +++ b/slides/outlines.typ @@ -0,0 +1,569 @@ +#import "./icons.typ": * + + +#let static_outline( + small_icon_size: 100pt, + big_icon_size: 200pt, +) = context { + let width = 2 * small_icon_size + big_icon_size * 2 + let height = big_icon_size + let arrow_width = small_icon_size / 10 + let arrow_gap = small_icon_size / 5 + + let app = apk( + fill: red, + height: small_icon_size + ) + let rprt = report(height: small_icon_size) + let analyser = box( + height: big_icon_size, + width: big_icon_size, + stroke: black, + align(center+horizon, text(fill: red)[TODO]) + ) + + let app_size = measure(app) + let app_pos = ( + 0pt, + -(height - app_size.height) / 2 + ) + let analyser_size = measure(analyser) + let analyser_pos = ( + width / 2 - analyser_size.width / 2, + -(height - analyser_size.height) / 2 + ) + let rprt_size = measure(rprt) + let rprt_pos = ( + width - rprt_size.width, + -(height - rprt_size.height) / 2 + ) + + + box( + width: width, + height: height, + //stroke: black, + { + place( + left+bottom, + dx: app_pos.at(0), + dy: app_pos.at(1), + app + ) + place( + left+bottom, + dx: analyser_pos.at(0), + dy: analyser_pos.at(1), + analyser + ) + place( + left+bottom, + dx: rprt_pos.at(0), + dy: rprt_pos.at(1), + rprt + ) + arrow( + stroke: (arrow_width + black), + ( + app_pos.at(0) + app_size.width + arrow_gap, + app_pos.at(1) - app_size.height / 2 + ), + ( + analyser_pos.at(0) - arrow_gap, + analyser_pos.at(1) - analyser_size.height / 2, + ) + ) + arrow( + stroke: (arrow_width + black), + ( + analyser_pos.at(0) + analyser_size.width + arrow_gap, + analyser_pos.at(1) - analyser_size.height / 2, + ), + ( + rprt_pos.at(0) - arrow_gap, + rprt_pos.at(1) - rprt_size.height / 2 + ) + ) + } + ) +} + +#let dexhunter_outline( + small_icon_size: 100pt, + big_icon_size: 200pt, +) = context { + let width = small_icon_size * 3 + big_icon_size + let height = (3 + 1) * small_icon_size + let arrow_width = small_icon_size / 10 + let arrow_gap = small_icon_size / 5 + + let app = apk( + fill: red, + height: small_icon_size + ) + let dex = apk( + fill: green, + height: small_icon_size, + txt: ".dex" + ) + + let phone = phone( + width: big_icon_size / 2, + height: big_icon_size, + ) + + let app_size = measure(app) + let dex_size = measure(dex) + let phone_size = measure(phone) + + let app_pos = ( + 0pt, + -height / 2 + app_size.height / 2 + ) + let dex_pos0 = ( + width - dex_size.width, + 0pt + ) + let dex_pos1 = ( + width - dex_size.width, + -height / 2 + dex_size.height / 2 + ) + let dex_pos2 = ( + width - dex_size.width, + -height + dex_size.height + ) + + let phone_pos = ( + width / 2 - phone_size.width / 2, + -height / 2 + phone_size.height / 2 + ) + + let arrow_l_x0 = phone_pos.at(0) + phone_size.width + arrow_gap + let arrow_l_x2 = width - dex_size.width - arrow_gap + let arrow_l_x1 = (arrow_l_x2 + arrow_l_x0) / 2 + + let arrow_l_y0_0 = phone_pos.at(1) - phone_size.height * 1/4 + let arrow_l_y0_1 = phone_pos.at(1) - phone_size.height * 2/4 + let arrow_l_y0_2 = phone_pos.at(1) - phone_size.height * 3/4 + let arrow_l_y1_0 = dex_pos0.at(1) - dex_size.height / 2 + let arrow_l_y1_1 = dex_pos1.at(1) - dex_size.height / 2 + let arrow_l_y1_2 = dex_pos2.at(1) - dex_size.height / 2 + + box( + width: width, + height: height, + stroke: black, + { + place( + left+bottom, + dx: app_pos.at(0), + dy: app_pos.at(1), + app + ) + place( + left+bottom, + dx: dex_pos0.at(0), + dy: dex_pos0.at(1), + dex + ) + place( + left+bottom, + dx: dex_pos1.at(0), + dy: dex_pos1.at(1), + dex + ) + place( + left+bottom, + dx: dex_pos2.at(0), + dy: dex_pos2.at(1), + dex + ) + place( + left+bottom, + dx: phone_pos.at(0), + dy: phone_pos.at(1), + phone + ) + + arrow( + stroke: arrow_width + black, + ( + app_pos.at(0) + app_size.width + arrow_gap, + app_pos.at(1) - app_size.height / 2 + ), + ( + phone_pos.at(0) - arrow_gap, + phone_pos.at(1) - phone_size.height / 2, + ) + ) + arrow( + stroke: arrow_width + black, + (arrow_l_x0, arrow_l_y0_0), + (arrow_l_x1, arrow_l_y0_0), + (arrow_l_x1, arrow_l_y1_0), + (arrow_l_x2, arrow_l_y1_0), + ) + arrow( + stroke: arrow_width + black, + (arrow_l_x0, arrow_l_y0_1), + (arrow_l_x1, arrow_l_y0_1), + (arrow_l_x1, arrow_l_y1_1), + (arrow_l_x2, arrow_l_y1_1), + ) + arrow( + stroke: arrow_width + black, + (arrow_l_x0, arrow_l_y0_2), + (arrow_l_x1, arrow_l_y0_2), + (arrow_l_x1, arrow_l_y1_2), + (arrow_l_x2, arrow_l_y1_2), + ) + } + ) +} + +#let theseus_outline( + small_icon_size: 60pt, + big_icon_size: 90pt, +) = context { + let width = ( + small_icon_size * 4 + + big_icon_size * 3 + + 5 * small_icon_size + ) + let height = 4.5 * small_icon_size + big_icon_size + let y0 = (height - big_icon_size) - 2 * small_icon_size + let arrow_width = small_icon_size / 10 + let arrow_gap = small_icon_size / 5 + + let app = apk( + fill: red, + height: small_icon_size + ) + let app2 = apk( + fill: blue, + height: small_icon_size + ) + let dex = apk( + fill: green, + height: small_icon_size, + txt: ".dex" + ) + let rprt = report( + height: small_icon_size, + ) + + let phone = phone( + width: big_icon_size * 0.75, + height: big_icon_size * 1.5, + ) + + let app_size = measure(app) + let dex_size = measure(dex) + let rprt_size = measure(rprt) + let phone_size = measure(phone) + + let app_pos = ( + 0pt, + -y0 + app_size.height / 2 + ) + + let dex_pos_x = width * 2/7 - dex_size.width / 2 + let dex_pos0 = ( + dex_pos_x, + - y0 + 2 * dex_size.height + ) + let dex_pos1 = ( + dex_pos_x, + - y0 + dex_size.height / 2 + ) + let rprt_pos2 = ( + width * 2/7 - rprt_size.width / 2, + - y0 - dex_size.height + ) + + let phone_pos = ( + width / 7 - phone_size.width / 2, + -y0 + phone_size.height / 2 + ) + + let arrow_1_x0 = phone_pos.at(0) + phone_size.width + arrow_gap + let arrow_1_x2 = dex_pos_x - arrow_gap + let arrow_1_x1 = (arrow_1_x2 + arrow_1_x0) / 2 + + let arrow_1_y0_0 = phone_pos.at(1) - phone_size.height * 1/4 + let arrow_1_y0_1 = phone_pos.at(1) - phone_size.height * 2/4 + let arrow_1_y0_2 = phone_pos.at(1) - phone_size.height * 3/4 + let arrow_1_y1_0 = dex_pos0.at(1) - dex_size.height / 2 + let arrow_1_y1_1 = dex_pos1.at(1) - dex_size.height / 2 + let arrow_1_y1_2 = rprt_pos2.at(1) - dex_size.height / 2 + + let patcher = box( + height: big_icon_size, + width: big_icon_size, + stroke: black, + align(center+horizon, text(fill: red)[TODO PATCHER]) + ) + let patcher_size = measure(patcher) + let patcher_pos = ( + width * 3.3 / 7 - patcher_size.width / 2, + -y0 + patcher_size.height / 2 + ) + + let arrow_2_x0 = dex_pos1.at(0) + dex_size.width + arrow_gap + let arrow_2_x2 = patcher_pos.at(0) - arrow_gap + let arrow_2_x1 = (arrow_2_x2 + arrow_2_x0) / 2 + + let arrow_2_y0_0 = dex_pos0.at(1) - dex_size.height / 2 + let arrow_2_y0_1 = dex_pos1.at(1) - dex_size.height / 2 + let arrow_2_y0_2 = rprt_pos2.at(1) - dex_size.height / 2 + let arrow_2_y1_0 = patcher_pos.at(1) - patcher_size.height * 1/4 + let arrow_2_y1_1 = patcher_pos.at(1) - patcher_size.height * 2/4 + let arrow_2_y1_2 = patcher_pos.at(1) - patcher_size.height * 3/4 + + + let app2_size = measure(app2) + let app2_pos = ( + width * 4.5 / 7 - app2_size.width / 2, + -y0 + app2_size.height / 2 + ) + + let analyser = box( + height: big_icon_size, + width: big_icon_size, + stroke: black, + align(center+horizon, text(fill: red)[TODO ANALYSER]) + ) + let analyser_size = measure(analyser) + let analyser_pos = ( + width * 5.7 / 7 - analyser_size.width / 2, + -y0 + analyser_size.height / 2 + ) + let analyser_pos2 = ( + width / 2 - analyser_size.width / 2, + -height + analyser_size.height + ) + + let rprt2_pos = ( + width - rprt_size.width, + -y0 + rprt_size.height / 2 + ) + let rprt3_pos = ( + analyser_pos2.at(0) + analyser_size.width + 2 * rprt_size.width, + analyser_pos2.at(1) - analyser_size.height / 2 + rprt_size.height / 2 + ) + + box( + width: width, + height: height, + //stroke: black, + { + place( + left+bottom, + dx: app_pos.at(0), + dy: app_pos.at(1), + app + ) + place( + left+bottom, + dx: dex_pos0.at(0), + dy: dex_pos0.at(1), + dex + ) + place( + left+bottom, + dx: dex_pos1.at(0), + dy: dex_pos1.at(1), + dex + ) + place( + left+bottom, + dx: rprt_pos2.at(0), + dy: rprt_pos2.at(1), + rprt + ) + place( + left+bottom, + dx: phone_pos.at(0), + dy: phone_pos.at(1), + phone + ) + + arrow( + stroke: arrow_width + black, + ( + app_pos.at(0) + app_size.width + arrow_gap, + app_pos.at(1) - app_size.height / 2 + ), + ( + phone_pos.at(0) - arrow_gap, + phone_pos.at(1) - phone_size.height / 2, + ) + ) + arrow( + stroke: arrow_width + black, + (arrow_1_x0, arrow_1_y0_0), + (arrow_1_x1, arrow_1_y0_0), + (arrow_1_x1, arrow_1_y1_0), + (arrow_1_x2, arrow_1_y1_0), + ) + arrow( + stroke: arrow_width + black, + (arrow_1_x0, arrow_1_y0_1), + (arrow_1_x1, arrow_1_y0_1), + (arrow_1_x1, arrow_1_y1_1), + (arrow_1_x2, arrow_1_y1_1), + ) + arrow( + stroke: arrow_width + black, + (arrow_1_x0, arrow_1_y0_2), + (arrow_1_x1, arrow_1_y0_2), + (arrow_1_x1, arrow_1_y1_2), + (arrow_1_x2, arrow_1_y1_2), + ) + arrow( + stroke: arrow_width + black, + (arrow_2_x0, arrow_2_y0_0), + (arrow_2_x1, arrow_2_y0_0), + (arrow_2_x1, arrow_2_y1_0), + (arrow_2_x2, arrow_2_y1_0), + ) + arrow( + stroke: arrow_width + black, + (arrow_2_x0, arrow_2_y0_1), + (arrow_2_x1, arrow_2_y0_1), + (arrow_2_x1, arrow_2_y1_1), + (arrow_2_x2, arrow_2_y1_1), + ) + arrow( + stroke: arrow_width + black, + (arrow_2_x0, arrow_2_y0_2), + (arrow_2_x1, arrow_2_y0_2), + (arrow_2_x1, arrow_2_y1_2), + (arrow_2_x2, arrow_2_y1_2), + ) + + place( + bottom+left, + dx: patcher_pos.at(0), + dy: patcher_pos.at(1), + patcher + ) + arrow( + stroke: arrow_width + black, + ( + patcher_pos.at(0) + patcher_size.width + arrow_gap, + patcher_pos.at(1) - patcher_size.height / 2 + ), + ( + app2_pos.at(0) - arrow_gap, + app2_pos.at(1) - app2_size.height / 2, + ) + ) + place( + bottom+left, + dx: app2_pos.at(0), + dy: app2_pos.at(1), + app2 + ) + arrow( + stroke: arrow_width + black, + ( + app2_pos.at(0) + app2_size.width + arrow_gap, + app2_pos.at(1) - app2_size.height / 2 + ), + ( + analyser_pos.at(0) - arrow_gap, + analyser_pos.at(1) - analyser_size.height / 2, + ) + ) + place( + bottom+left, + dx: analyser_pos.at(0), + dy: analyser_pos.at(1), + analyser + ) + arrow( + stroke: arrow_width + black, + ( + analyser_pos.at(0) + analyser_size.width + arrow_gap, + analyser_pos.at(1) - analyser_size.height / 2 + ), + ( + rprt2_pos.at(0) - arrow_gap, + rprt2_pos.at(1) - rprt_size.height / 2, + ) + ) + place( + left+bottom, + dx: rprt2_pos.at(0), + dy: rprt2_pos.at(1), + rprt + ) + arrow( + stroke: arrow_width + black, + ( + app_pos.at(0) + app_size.width / 2, + app_pos.at(1) + arrow_gap, + ), + ( + app_pos.at(0) + app_size.width / 2, + -arrow_width + ), + ( + patcher_pos.at(0) + patcher_size.width / 2, + -arrow_width + ), + ( + patcher_pos.at(0) + patcher_size.width / 2, + patcher_pos.at(1) + arrow_gap + ) + ) + + place( + bottom+left, + dx: analyser_pos2.at(0), + dy: analyser_pos2.at(1), + analyser + ) + place( + left+bottom, + dx: rprt3_pos.at(0), + dy: rprt3_pos.at(1), + rprt + ) + + arrow( + stroke: arrow_width + black, + ( + analyser_pos2.at(0) + analyser_size.width + arrow_gap, + analyser_pos2.at(1) - analyser_size.height / 2, + ), + ( + rprt3_pos.at(0) - arrow_gap, + rprt3_pos.at(1) - rprt_size.height / 2, + ) + ) + arrow( + stroke: arrow_width + black, + ( + app_pos.at(0) + app_size.width/2, + app_pos.at(1) - app_size.height - arrow_gap, + ), + ( + app_pos.at(0) + app_size.width/2, + analyser_pos2.at(1) - analyser_size.height / 2, + ), + ( + analyser_pos2.at(0) - arrow_gap, + analyser_pos2.at(1) - analyser_size.height / 2, + ), + ) + } + ) +} + +#set page(flipped: true) +#set align(center+horizon) +//#dexhunter_outline() +//#static_outline() +#theseus_outline()