Skip to content

Commit 6f5fda6

Browse files
committed
font_mask multi surface
Changed res of animation_base to be 1/4 of 1080p Tweaks to the book bits
1 parent 516aa96 commit 6f5fda6

10 files changed

Lines changed: 92 additions & 19 deletions

File tree

book/BarCamp2024.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ Preface: Computing Education Sux
3232
* > Introduction of new syllabus may be reason number of girls taking subject more than halved in eight years, academics say
3333
* Q: So what is important for young people?
3434
* The grand answer: Self actualization and altering the world though self action and building something
35-
* The simple answer: Choose to build shit
35+
* The simple answer: They choose to build shit
3636
* The refined anser: 'Authentic Participation'
3737

3838
### Qualifications vs Certification

book/citification.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,8 @@ No Cirt, but made by big players
149149

150150
Testing
151151
https://istqb.org/certifications/certified-tester-foundation-level-ctfl-v4-0/
152+
https://www.bcs.org/media/ilhdvwam/istqb-certified-tester-syllabus.pdf
153+
152154
https://www.bcs.org/qualifications-and-certifications/certifications-for-professionals/software-testing-certifications/istqb-certified-tester-foundation-level/
153155
IEEE Computer Society https://www.computer.org/product/education/software-testing-course
154156

book/olderLearners.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
2+
Is there an age that is too old?
3+
4+
https://initcoder.com/posts/37-year-old-learning-cs/#notes

teachprogramming/static/projects/game/animation_base.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
function createFullScreenCanvasElement({width=640, height=360, background_color='black'}={}) {
1+
function createFullScreenCanvasElement({width=480, height=270, background_color='black'}={}) {
22
const body_style = `
33
margin: 0;
44
height: 100%;

teachprogramming/static/projects/game/animation_base_pygame.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ def install(name):
1515

1616

1717
class PygameBase():
18-
def __init__(self, title="pg", resolution=(320,180), fps=60, color_background='black'):
18+
def __init__(self, title="pg", resolution=(480,270), fps=60, color_background='black'):
1919
pygame.init()
2020
pygame.display.set_caption(title)
2121
self.screen = pygame.display.set_mode(resolution, pygame.SCALED | pygame.RESIZABLE)

teachprogramming/static/projects/game/animation_base_skia.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,6 @@
22

33
import {Canvas} from 'skia-canvas'
44

5-
let canvas = new Canvas(400, 400)
5+
let canvas = new Canvas(480, 270)
66
let ctx = canvas.getContext("2d")
77
let {width, height} = canvas

teachprogramming/static/projects/graphics/font/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ _venv:
2222
python3 -m venv _venv
2323
_venv/bin/pip install pygame
2424
run_pygame_font: _venv animation_base_pygame.py
25-
_venv/bin/python3 pygame_font.py
25+
_venv/bin/python3 font_pygame.py
2626

2727
animation_base.js:
2828
ln -s ../../game/animation_base.js animation_base.js

teachprogramming/static/projects/graphics/font/font.html

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,17 +17,17 @@
1717

1818
class Font extends CanvasAnimationBase {
1919
constructor() {
20-
super(undefined, 60, {background_color: 'black', width: 320, height: 180})
20+
super(undefined, 60, {background_color: 'black', width: 480, height: 270})
2121
this.random_ys = [...range(10)].map((i)=>Math.floor(Math.random()*this.h)) // ver: list_scroll_x
2222
}
2323

2424
async constructor_async() {
25-
this.font = this.load_font_advance(this.invert(await this.load_image("font", "font.webp")))
25+
this.font = this.load_font_advance(CanvasAnimationBase.invert(await this.load_image("font", "font.webp")))
2626
}
2727

2828
load_font = (img) => Object.fromEntries(
2929
[...range(Math.floor(img.width/8))].map((i)=>[
30-
String.fromCharCode(i), this.subsurface(img, i*8, 0, 8, 8)
30+
String.fromCharCode(i), CanvasAnimationBase.subsurface(img, i*8, 0, 8, 8)
3131
])
3232
)
3333

@@ -36,7 +36,7 @@
3636
const [ww, hh] = [img.width, img.height]
3737
return Object.fromEntries(
3838
[...range(Math.min(Math.floor(ww/w)*Math.floor(hh/h),seq.length))].map((i)=>[
39-
seq[i], this.subsurface(img, (i*w)%ww, Math.floor((i*w)/ww)*h, w, h)
39+
seq[i], CanvasAnimationBase.subsurface(img, (i*w)%ww, Math.floor((i*w)/ww)*h, w, h)
4040
])
4141
)
4242
}

teachprogramming/static/projects/graphics/font/font_mask.html

Lines changed: 71 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,58 @@
1818

1919
class Surface {
2020
constructor(width, height) {
21-
this._o = new OffscreenCanvas(width, height)
22-
this._c = this._o.getContext("2d")
21+
if (!(Number.isInteger(width) && Number.isInteger(height))) {debugger}
22+
console.assert(Number.isInteger(width) && Number.isInteger(height), "Surface must have int width/height")
23+
this.o = new OffscreenCanvas(width, height)
24+
this._c = this.o.getContext("2d")
2325
this._img = undefined
2426
}
27+
get w() {return this.o.width}
28+
get h() {return this.o.height}
2529
get c() {this._img = undefined; return this._c}
26-
get img() {return this._img || (this._img = this._o.transferToImageBitmap())}
30+
get img() {return this._img || (this._img = this.o.transferToImageBitmap())}
31+
clear() {this.c.clearRect(0, 0, this.w, this.h)}
32+
static isDimensionMatch(a, b) {return a.w==b.w && a.h==b.h}
33+
static fromCanvas(canvas) {
34+
const s = new Surface(canvas.width, canvas.height)
35+
s.c.drawImage(canvas,0,0)
36+
return s
37+
}
2738
}
2839

2940

41+
class SurfaceMix {
42+
/*
43+
Mix two Surfaces
44+
A B Mask Output
45+
|-----| |-----| |-----| |-----|
46+
| a | | b | |OOOO/| | a /|
47+
| | | | |OOO/ | | / |
48+
| |+| |+|OO/ |=| / |
49+
| | | | |O/ | | / |
50+
| a | | b | |/ | |/ b |
51+
|-----| |-----| |-----| |-----|
52+
A & B are mutated/modified/cut so they can be drawn to create the Output
53+
*/
54+
constructor(surface_a, surface_b, mask) {
55+
this.a = surface_a
56+
this.b = surface_b
57+
this.mask = mask || new Surface(this.a.w, this.a.h)
58+
console.assert(Surface.isDimensionMatch(this.a, this.b), "Surfaces should match dimension")
59+
console.assert(Surface.isDimensionMatch(this.a, this.mask), "Mask should match Surface dimension")
60+
}
61+
cut() {
62+
this.a.c.save()
63+
this.a.c.globalCompositeOperation = 'destination-in';
64+
this.a.c.drawImage(this.mask.o, 0, 0)
65+
this.a.c.restore()
66+
this.b.c.save()
67+
this.b.c.globalCompositeOperation = 'destination-out';
68+
this.b.c.drawImage(this.mask.o, 0, 0)
69+
this.b.c.restore()
70+
}
71+
}
72+
3073
class Font {
3174
constructor(img) {
3275
this.font = this._load_font_advance(img)
@@ -63,7 +106,7 @@
63106
draw_char_mask(c, char, x, y) {
64107
let img
65108
if (!(img = this.char_cache[char])) {
66-
img = this.render_mask_img(this.font[char], this.background.img)
109+
img = this.render_mask_img(this.font[char], this.background.o)
67110
this.char_cache[char] = img
68111
}
69112
c.drawImage(img, x, y)
@@ -79,25 +122,44 @@
79122

80123
class FontCanvas extends CanvasAnimationBase {
81124
constructor() {
82-
super(undefined, 60, {background_color: 'black', width: 320, height: 180})
125+
super(undefined, 60, {background_color: 'black', width: 480, height: 270})
126+
this.a = Surface.fromCanvas(this.canvas)
127+
this.b = Surface.fromCanvas(this.canvas)
128+
this.mix = new SurfaceMix(this.a, this.b)
83129
}
84130

85131
async constructor_async() {
86-
this.font = new Font(CanvasAnimationBase.invert(await this.load_image("font", "font.webp")))
132+
this.font = new Font(CanvasAnimationBase.invert(await this.load_image("font", "Babyteeth.webp")))
87133
}
88134

89135
model_inc(frame) {
90136
}
91137
draw(context, frame) {
138+
92139
this.font.clear_cache()
93140
const bc = this.font.background.c
94141
bc.fillStyle='green'; bc.fillRect(0,0,8,8);
95-
let f = Math.abs(Math.floor(Math.sin(frame/64)*16))
142+
let f = Math.abs(Math.floor(Math.sin(frame/64)*15))
96143
CanvasAnimationBase.drawLine(bc,4+f%16,-4,-4,4+f%16,'#00FF00')
97144

145+
this.a.clear()
146+
this.font.draw_font(this.a.c, "Hello, What is this! OMG OMG", 20, 20)
147+
148+
this.b.clear()
149+
this.b.c.fillStyle='grey'
150+
this.b.c.fillRect(0,0,this.b.w,this.b.h)
151+
152+
this.mix.mask.clear()
153+
this.mix.mask.c.fillStyle = 'white'
154+
this.mix.mask.c.fillRect(0,0,frame%this.w,this.h)
155+
156+
this.mix.cut()
157+
98158
this.clear()
99-
const c = context
100-
this.font.draw_font(c, "Hello, What is this! OMG OMG", 20, 20)
159+
context.drawImage(this.a.o,0,0)
160+
context.drawImage(this.b.o,0,0)
161+
162+
CanvasAnimationBase.drawLine(context, frame%this.w,0,frame%this.w,this.h,'white',4)
101163
}
102164

103165

teachprogramming/static/projects/mini/byteDecode.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,9 @@ tt = """
88
065 115 032 116 104 101 032 119 111 114 108 100 032 105 115 032 115 101 116 032 111 110 032 102 105 114 101 013 010 119 104 105 108 101 032 112 114 101 112 097 114 105 110 103 032 102 111 114 032 116 104 105 115 032 102 105 103 104 116 013 010 073 110 032 116 104 101 032 100 097 114 107 032 097 032 115 112 101 108 108 119 097 114 101 032 114 105 115 101 013 010 077 097 100 101 032 111 102 032 049 046 052 052 032 109 101 103 097 098 121 116 101 115 013 010 013 010 073 110 032 097 032 102 108 111 112 112 121 032 100 105 115 107 032 102 105 116 115 032 116 105 103 104 116 013 010 087 105 116 104 032 097 032 099 114 097 099 107 116 114 111 032 112 097 099 107 101 100 032 105 110 115 105 100 101 013 010 077 101 103 097 116 114 097 105 110 101 114 115 032 116 111 032 098 111 111 115 116 032 121 111 117 114 032 109 105 103 104 116 013 010 071 111 116 116 097 032 116 114 121 032 098 101 102 111 114 101 032 121 111 117 032 102 105 103 104 116 013 010 013 010 078 111 119 032 097 103 097 105 110 032 097 110 111 116 104 101 114 032 116 105 109 101 013 010 070 111 108 108 111 119 032 109 101 032 097 108 111 110 103 032 116 104 101 115 101 032 114 104 121 109 101 115 013 010 073 102 032 121 111 117 032 119 097 110 116 032 116 111 032 103 101 116 032 116 104 105 115 032 112 114 105 122 101 013 010 072 105 100 100 101 110 032 105 110 032 098 101 116 119 101 101 110 032 116 104 101 115 101 032 108 105 110 101 115 013 010 013 010 077 097 107 101 032 097 032 115 117 109 032 111 102 032 097 108 108 032 116 104 111 115 101 032 098 121 116 101 115 013 010 084 114 097 115 104 032 116 104 101 032 111 100 100 115 032 097 110 100 032 109 097 107 101 032 105 116 032 116 105 103 104 116 013 010 084 117 114 110 032 116 111 032 065 083 067 073 073 032 099 111 100 101 032 097 110 100 032 119 114 105 116 101 013 010 065 108 108 032 116 104 111 115 101 032 110 117 109 098 101 114 115 032 111 118 101 114 032 097 032 108 105 110 101 013 010 013 010 078 111 119 032 106 117 115 116 032 107 101 101 112 032 116 104 097 116 032 105 110 032 121 111 117 114 032 109 105 110 100 013 010 067 114 097 099 107 032 116 104 101 032 099 111 100 101 032 098 101 108 111 119 032 116 104 101 115 101 032 108 105 110 101 115 013 010 085 115 101 032 116 104 101 032 099 111 100 101 119 111 114 100 032 121 111 117 032 119 105 108 108 032 102 105 110 100 013 010 084 111 032 114 101 100 101 101 109 032 116 104 101 032 098 111 110 117 115 032 112 114 105 122 101 013 010 013 010 069 110 106 111 121 032 070 108 111 112 112 121 032 068 105 115 107 032 079 118 101 114 100 114 105 118 101 033
99
"""
1010
print(bytes(map(int, filter(None, map(lambda i: i.strip().lstrip('0'), tt.split(" "))))).decode('utf8'))
11-
```
11+
```
12+
13+
https://www.razor.co.uk/careers/vacancies/senior-python-engineer-with-ai
14+
15+
data = '5f4dcc3b5aa765d61d8327deb882cf99'
16+
bytes.fromhex(data).decode('utf-8')

0 commit comments

Comments
 (0)