#let mark(x, y) = { place(line(start: (x - 5pt, y - 5pt), end: (x + 5pt, y + 5pt))) place(line(start: (x + 5pt, y - 5pt), end: (x - 5pt, y + 5pt))) } #let polar( origin: (0pt, 0pt), r: 0pt, th: 0deg, ) = { let (x0, y0) = origin ( x0 + r * calc.cos(th), y0 + r * calc.sin(th), ) } #let arc( center: (0pt, 0pt), r: 0pt, th0: 0deg, th1: 0deg, ) = { 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 let x_q1 = x1 + l * x_u1 let y_q1 = y1 + l * y_u1 let x_q2 = x2 - l * x_u2 let y_q2 = y2 - l * y_u2 ((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(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) (curve.cubic(q0, q1, p1),) }, curve.close() ) } #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, height: 400pt, stroke: 3pt+black, body: [], ) = { let h_screen = height*12/15 let w_screen = width*8/10 let r = (height/15) let h_button = (height - h_screen) / 6 let w_button = w_screen / 3 let dy_button = -((height - h_screen) / 2 - h_button) / 2 let h-top-line = ((height - h_screen) / 2) / 6 let w-top-line-bar = w_screen / 2 let dy-top-line = (((height - h_screen) / 2) - h-top-line) / 3 let r-cam = ((height - h_screen) / 2) / 5 let dx-cam = -r-cam*2 let dy-cam = ((height - h_screen) / 2 / 2) - r-cam let top-line = stack( dir: ltr, circle(radius: h-top-line/2, stroke: stroke), h(h-top-line), rect( width: w-top-line-bar, height: h-top-line, radius: h-top-line/2, stroke: stroke, ), h(h-top-line), circle(radius: h-top-line/2, stroke: stroke), h(h-top-line), circle(radius: h-top-line/2, stroke: stroke) ) rect( width: width, height: height, inset: 0pt, stroke: stroke, radius: r, { place(center+horizon, rect( width: w_screen, height: h_screen, stroke: stroke, body, ) ) place(center+bottom, dy: dy_button, rect( width: w_button, height: h_button, stroke: stroke, radius: h_screen / 2, ) ) place(center+top, dy: dy-top-line, top-line ) place(right+top, dx: dx-cam, dy: dy-cam, circle(radius: r-cam, stroke: stroke) ) } ) } #let gear( //x0: 0pt, y0: 0pt, out-rad: 100pt, in-rad: none, center-rad: none, nb-teeth: 6, teeth-angle: none, stroke: black + 3pt, fill: luma(70%), ) = { let x0 = out-rad let y0 = out-rad let teeth-angle = if teeth-angle == none { 360deg / nb-teeth / 2 } else { teeth-angle } let inter-teeth-angle = (360deg / nb-teeth) - teeth-angle let in-rad = if in-rad == none { out-rad * 0.75 } else { in-rad } let center-rad = if center-rad == none { in-rad / 2 } else { center-rad } box(width: 2*out-rad, height: 2*out-rad, { //place(left+bottom, line(start: (0%, -50%), end: (100%, -50%))) //place(left+bottom, line(start: (50%, 0%), end: (50%, -100%))) curve( stroke: stroke, fill: fill, fill-rule: "even-odd", ..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(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(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(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 let q2 = (p2.at(0) + l2 * u2.at(0), p2.at(1) + l2 * u2.at(1)) let q3 = (p3.at(0) + l3 * u3.at(0), p3.at(1) + l3 * u3.at(1)) let result = ( curve.line(p0), curve.line(p1), curve.line(p2), /* curve.line(q2), curve.line(p2), curve.line(p3), curve.line(q3), curve.line(p3), */ curve.cubic(q2, q3, p3) ) if i == 0 { result.insert(0, curve.move(p0)) } result }, curve.close(mode: "straight"), ..for i in range(4) { let angle = i * 360deg / 4 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)) let q1 = (p1.at(0) + l1 * u1.at(0), p1.at(1) + l1 * u1.at(1)) let result = ( curve.cubic(q0, q1, p1), ) if i == 0 { result.insert(0, curve.move(p0)) } result }, curve.close() ) /*place(left+bottom, // wtf? dx: out-rad - center-rad, dy: -out-rad + center-rad, circle( radius: center-rad, stroke: stroke, fill: fill-center, ) )*/ }) } #let wrench( length: 200pt, hex_side: none, handle_width: none, head_rad: none, stroke: 3pt+black, fill: luma(70%), ) = { let handle_width = if handle_width == none { length * 0.15 } else { handle_width } let handle_rad = handle_width / 2 let head_rad = if head_rad == none { handle_rad * 2.2 } else { head_rad } let hex_side = if hex_side == none { head_rad * 0.6 } else { hex_side } let hex_angle = 360deg / 6 let head_width = hex_side * 0.2 let hex_h = hex_side * calc.cos(hex_angle * 2 - 90deg) let pommel_center = (handle_rad, 0pt) let head_neck_half_angle = calc.asin(handle_rad / head_rad) let head_face_half_angle = calc.asin((hex_h + head_width) / head_rad) let head_center = (length - calc.sqrt( head_rad / 1pt * head_rad / 1pt - (hex_h + head_width) / 1pt * (hex_h + head_width) / 1pt ) * 1pt , 0pt) let handle_length = head_center.at(0) - calc.sqrt( head_rad/1pt*head_rad/1pt - handle_rad/1pt*handle_rad/1pt ) * 1pt let ( pommel_p0, pommel_q0, pommel_q1, pommel_p1 ) = arc( center: pommel_center, r: handle_rad, th0: 90deg, th1: 180deg ) let ( _, pommel_q2, pommel_q3, pommel_p3 ) = arc( center: pommel_center, r: handle_rad, th0: 180deg, th1: 270deg ) let neck_dw = (handle_length, handle_rad) let neck_up = (handle_length, -handle_rad) let ( head_neck_up_p0, head_neck_up_q0, head_neck_up_q1, head_neck_up_p1 ) = arc( center: head_center, r: head_rad, th0: -90deg + head_neck_half_angle - 90deg, th1: - 90deg ) let ( head_fup_p0, head_fup_q0, head_fup_q1, head_fup_p1 ) = arc( center: head_center, r: head_rad, th0: - 90deg, th1: - head_face_half_angle, ) let ( head_fdw_p0, head_fdw_q0, head_fdw_q1, head_fdw_p1, ) = arc( center: head_center, r: head_rad, th0: head_face_half_angle, th1: 90deg, ) let ( head_neck_dw_p0, head_neck_dw_q0, neck_dw_q1, _ ) = arc( center: head_center, r: head_rad, th0: 90deg, th1: 180deg - head_neck_half_angle ) let hex_thi = -hex_angle let hex_pi = (length - (1 + calc.cos(hex_angle)) * hex_side - head_width, 0pt) let hex = ( ..for i in range(6) { let last_hex_p = hex_pi hex_pi = polar( origin: hex_pi, r: hex_side, th: hex_thi, ) hex_thi = hex_thi + hex_angle (last_hex_p,) } ) let head_fup_in = head_fup_p1 head_fup_in.at(1) += head_width let head_fdw_in = head_fdw_p0 head_fdw_in.at(1) -= head_width box( width: 200pt, height: 200pt, //stroke: black, place(left+horizon, { place(curve( stroke: stroke, fill: fill, curve.move(neck_dw), curve.line(pommel_p0), curve.cubic(pommel_q0, pommel_q1, pommel_p1), curve.cubic(pommel_q2, pommel_q3, pommel_p3), curve.line(neck_up), //curve.line(head_neck_up_p0), curve.cubic(head_neck_up_q0, head_neck_up_q1, head_neck_up_p1), curve.cubic(head_fup_q0, head_fup_q1, head_fup_p1), curve.line(head_fup_in), ..for i in (1, 0, 5) { //(2, 1, 0, 5, 4) { (curve.line(hex.at(i)),) }, curve.line(head_fdw_in), curve.line(head_fdw_p0), curve.cubic(head_fdw_q0, head_fdw_q1, head_fdw_p1), //curve.line(head_neck_dw_p0), curve.cubic(head_neck_dw_q0, neck_dw_q1, neck_dw), curve.close(mode: "straight") )) /* mark(..pommel_center) mark(..pommel_p0) mark(..pommel_p1) mark(..pommel_p3) mark(..neck_up) mark(..neck_dw) mark(..head_fdw_p0) mark(..head_fdw_p1) for p in hex { mark(..p) } mark(..head_center) */ })) } #let transfo(height: 200pt) = { box(width: height, height: height, { place( left+bottom, dx: height / 12, dy: - height * 3 / 12, gear(out-rad: height/3) ) place( left+bottom, dx: height * 2 / 5, dy: 0pt, wrench(length: height*7/8) ) }) } #let loop(height: 100pt) = image("imgs/ico/loop.svg", height: height) #let analyse(height: 200pt) = { box(width: height, stroke: black, { apk(height: height) place( left+top, dx: - height * 3/10, dy: - height * 1 / 10, loop(height: height/2) ) }) } #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 and fill == none { none } else if fill_back == none { fill.lighten(30%) } else { fill_back } let types = ( "cornered", "plain", "clip", ) assert( 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_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_rup_up = ( corner_rup.at(0), 0pt, ) let corner_rup_dw = ( width, corner_rup.at(1) ) let corner_rup_pth = if type == "cornered" and corner-rad == none { ( curve.line(corner_rup_up), curve.line(corner_rup), curve.line(corner_rup_dw) ) } 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( width: width, height: height, //stroke: black, { if type == "cornered" { let stroke = std.stroke(stroke) let stroke = std.stroke( join: "round", paint: stroke.paint, thickness: stroke.thickness, ) place(top+left, { curve( fill: fill_back, stroke: stroke, curve.move(corner_rup_up), ..corner_rup_pth, curve.close() ) }) } place(top+left, { curve( fill: fill, stroke: stroke, ..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 ) ) } ) } #let android( height: 200pt, stroke: black + 3pt, stroke_eye: none, fill: green, fill_eye: white, ) = { let width = height * 0.78 let body_height = height * 0.47 let body_width = body_height * 1 let leg_height = body_height / 2 let leg_width = body_width / 4 let leg_gap = body_width / 4 let arm_width = leg_width let arm_length = body_height * 0.8 let arm_gap = arm_width / 4 let arm_offset_to_body = 0pt let head_gap = body_height * 0.1 let antenna_angle = 45deg let antenna_width = body_width * 0.07 let antenna_width_angle = calc.asin(2*antenna_width/body_width) let antenna_length = body_width * 0.2 let eye_rad = body_width * 0.05 let rad_eye_in_head = body_width * 0.35 let angle_eye = 45deg let leg_r_1 = ( width / 2 + leg_gap / 2, height - leg_height ) let leg_r_c = ( width / 2 + leg_gap / 2 + leg_width / 2, height - leg_width / 2 ) let ( leg_r_2, leg_r_2_q, leg_r_3_q0, leg_r_3, ) = arc( center: leg_r_c, r: leg_width / 2, th0: 180deg, th1: 90deg, ) let ( _, leg_r_3_q1, leg_r_4_q, leg_r_4, ) = arc( center: leg_r_c, r: leg_width / 2, th0: 90deg, th1: 0deg, ) let leg_r_5 = ( width / 2 + leg_gap / 2 + leg_width, height - leg_height ) let body_dr = ( width / 2 + body_width / 2, height - leg_height ) let body_ur = ( width / 2 + body_width / 2, height - body_height - leg_height ) let body_ul = ( width / 2 - body_width / 2, height - body_height - leg_height ) let body_dl = ( width / 2 - body_width / 2, height - leg_height ) let leg_l_1 = ( width / 2 - leg_gap / 2 - leg_width, height - leg_height ) let leg_l_c = ( width / 2 - leg_gap / 2 - leg_width / 2, height - leg_width / 2 ) let ( leg_l_2, leg_l_2_q, leg_l_3_q0, leg_l_3, ) = arc( center: leg_l_c, r: leg_width / 2, th0: 180deg, th1: 90deg, ) let ( _, leg_l_3_q1, leg_l_4_q, leg_l_4, ) = arc( center: leg_l_c, r: leg_width / 2, th0: 90deg, th1: 0deg, ) let leg_l_5 = ( width / 2 - leg_gap / 2, height - leg_height ) let head_center = ( width / 2, height - leg_height - body_height - head_gap, ) let ( head_r, head_r_q, head_ra1_q, head_ra1 ) = arc( center: head_center, r: body_width / 2, th0: 0deg, th1: - antenna_angle + antenna_width_angle/2, ) let antenna_r_c = polar( origin: head_center, r: body_width / 2 + antenna_length - antenna_width/2, th: - antenna_angle ) let ( antenna_r_0, antenna_r_0_q, antenna_r_1_q0, antenna_r_1 ) = arc( center: antenna_r_c, r: antenna_width/2, th0: - antenna_angle + 90deg, th1: - antenna_angle, ) let ( _, antenna_r_1_q1, antenna_r_2_q, antenna_r_2 ) = arc( center: antenna_r_c, r: antenna_width/2, th0: - antenna_angle, th1: - antenna_angle - 90deg, ) let ( head_ra2, head_ra2_q, head_t_q0, head_t ) = arc( center: head_center, r: body_width / 2, th0: - antenna_angle - antenna_width_angle/2, th1: -90deg, ) let ( head_la1, head_la1_q, head_t_q1, _, ) = arc( center: head_center, r: body_width / 2, th0: 180deg + antenna_angle + antenna_width_angle/2, th1: 270deg, ) let antenna_l_c = polar( origin: head_center, r: body_width / 2 + antenna_length - antenna_width/2, th: 180deg + antenna_angle ) let ( antenna_l_0, antenna_l_0_q, antenna_l_1_q0, antenna_l_1 ) = arc( center: antenna_l_c, r: antenna_width/2, th0: 180deg + antenna_angle + 90deg, th1: 180deg + antenna_angle, ) let ( _, antenna_l_1_q1, antenna_l_2_q, antenna_l_2 ) = arc( center: antenna_l_c, r: antenna_width/2, th0: 180deg + antenna_angle, th1: 180deg + antenna_angle -90deg, ) let ( head_la2, head_la2_q, head_l_q, head_l ) = arc( center: head_center, r: body_width / 2, th0: 180deg + antenna_angle - antenna_width_angle/2, th1: 180deg, ) let eye_l = circle_path( center: polar( origin: head_center, r: rad_eye_in_head, th: 180deg + angle_eye, ), r: eye_rad ) let eye_r = circle_path( center: polar( origin: head_center, r: rad_eye_in_head, th: - angle_eye, ), r: eye_rad ) let arm_lup_c = ( width/2 - body_width/2 - arm_gap - arm_width/2, height - leg_height - body_height + arm_width/2 - arm_offset_to_body, ) let arm_ldw_c = ( width/2 - body_width/2 - arm_gap - arm_width/2, height - leg_height - body_height - arm_width/2 - arm_offset_to_body + arm_length ) let arm_rup_c = ( width/2 + body_width/2 + arm_gap + arm_width/2, height - leg_height - body_height + arm_width/2 - arm_offset_to_body ) let arm_rdw_c = ( width/2 + body_width/2 + arm_gap + arm_width/2, height - leg_height - body_height - arm_width/2 - arm_offset_to_body + arm_length ) let ( arm_lup_0, arm_lup_0_q, arm_lup_1_q0, arm_lup_1, ) = arc( center: arm_lup_c, r: arm_width/2, th0: 0deg, th1: -90deg, ) let ( _, arm_lup_1_q1, arm_lup_2_q, arm_lup_2, ) = arc( center: arm_lup_c, r: arm_width/2, th0: -90deg, th1: -180deg, ) let ( arm_ldw_0, arm_ldw_0_q, arm_ldw_1_q0, arm_ldw_1, ) = arc( center: arm_ldw_c, r: arm_width/2, th0: -180deg, th1: -270deg, ) let ( _, arm_ldw_1_q1, arm_ldw_2_q, arm_ldw_2, ) = arc( center: arm_ldw_c, r: arm_width/2, th0: -270deg, th1: -360deg, ) let ( arm_rup_0, arm_rup_0_q, arm_rup_1_q0, arm_rup_1, ) = arc( center: arm_rup_c, r: arm_width/2, th0: 0deg, th1: -90deg, ) let ( _, arm_rup_1_q1, arm_rup_2_q, arm_rup_2, ) = arc( center: arm_rup_c, r: arm_width/2, th0: -90deg, th1: -180deg, ) let ( arm_rdw_0, arm_rdw_0_q, arm_rdw_1_q0, arm_rdw_1, ) = arc( center: arm_rdw_c, r: arm_width/2, th0: -180deg, th1: -270deg, ) let ( _, arm_rdw_1_q1, arm_rdw_2_q, arm_rdw_2, ) = arc( center: arm_rdw_c, r: arm_width/2, th0: -270deg, th1: -360deg, ) box( width: width, height: height, //stroke: black, { place(left+top, curve( stroke: stroke, fill: fill, curve.move(leg_r_1), curve.line(leg_r_2), curve.cubic(leg_r_2_q, leg_r_3_q0, leg_r_3), curve.cubic(leg_r_3_q1, leg_r_4_q, leg_r_4), curve.line(leg_r_5), curve.line(body_dr), curve.line(body_ur), curve.line(body_ul), curve.line(body_dl), curve.line(leg_l_1), curve.line(leg_l_2), curve.cubic(leg_l_2_q, leg_l_3_q0, leg_l_3), curve.cubic(leg_l_3_q1, leg_l_4_q, leg_l_4), curve.line(leg_l_5), curve.close(), curve.move(head_r), curve.cubic(head_r_q, head_ra1_q, head_ra1), curve.line(antenna_r_0), curve.cubic(antenna_r_0_q, antenna_r_1_q0, antenna_r_1), curve.cubic(antenna_r_1_q1, antenna_r_2_q, antenna_r_2), curve.line(head_ra2), curve.cubic(head_ra2_q, head_t_q0, head_t), curve.cubic(head_t_q1, head_la1_q, head_la1), curve.line(antenna_l_0), curve.cubic(antenna_l_0_q, antenna_l_1_q0, antenna_l_1), curve.cubic(antenna_l_1_q1, antenna_l_2_q, antenna_l_2), curve.line(head_la2), curve.cubic(head_la2_q, head_l_q, head_l), curve.close(mode: "straight"), curve.move(arm_lup_0), curve.cubic(arm_lup_0_q, arm_lup_1_q0, arm_lup_1), curve.cubic(arm_lup_1_q1, arm_lup_2_q, arm_lup_2), curve.line(arm_ldw_0), curve.cubic(arm_ldw_0_q, arm_ldw_1_q0, arm_ldw_1), curve.cubic(arm_ldw_1_q1, arm_ldw_2_q, arm_ldw_2), curve.close(mode: "straight"), curve.move(arm_rup_0), curve.cubic(arm_rup_0_q, arm_rup_1_q0, arm_rup_1), curve.cubic(arm_rup_1_q1, arm_rup_2_q, arm_rup_2), curve.line(arm_rdw_0), curve.cubic(arm_rdw_0_q, arm_rdw_1_q0, arm_rdw_1), curve.cubic(arm_rdw_1_q1, arm_rdw_2_q, arm_rdw_2), curve.close(mode: "straight"), )) place(left+top, curve( stroke: stroke_eye, fill: fill_eye, ..eye_l, ..eye_r )) } ) } #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: white, type: "clip")//corner-rad: 10pt) //#h(2em) //#android(height: 200pt) /* #apk() #apk(fill: red) #apk(android_fill: red) #v(4em) #apks() #v(12em) #transfo() #analyse() #report() */