📄 mug.c
字号:
i = d.y; if(i < 0){ /* * should really check i/2, but this is safe and feedback * makes the control feel right */ i = -min(-i, a[Right]); i = max(i, a[Left]); } i = max(i, a[Top]); if(i >= Dy(r)) break; r.min.y += i; /* divide the half bit equally */ toggle = 1-toggle; if(toggle){ r.min.x += i/2; r.max.x = r.min.x+Dy(r); }else{ r.max.x -= i/2; r.min.x = r.max.x-Dy(r); } break; case RTopRight: i = (-d.x+d.y)/2; if(i>=Dx(r) || i>=Dy(r)) break; i = -min(-i, a[Right]); i = max(i, a[Top]); r.max.x -= i; r.min.y += i; break; case RLeft: i = d.x; if(i < 0){ i = -min(-i, a[Bottom]); i = max(i, a[Top]); } i = max(i, a[Left]); if(i >= Dx(r)) break; r.min.x += i; /* divide the half bit equally */ toggle = 1-toggle; if(toggle){ r.min.y += i/2; r.max.y = r.min.y+Dx(r); }else{ r.max.y -= i/2; r.min.y = r.max.y-Dx(r); } break; case RMiddle: if(d.x >= 0) d.x = min(d.x, a[Right]); else d.x = max(d.x, a[Left]); if(d.y >= 0) d.y = min(d.y, a[Bottom]); else d.y = max(d.y, a[Top]); r = rectaddpt(r, d); break; case RRight: i = d.x; if(i > 0){ i = min(i, a[Bottom]); i = -max(-i, a[Top]); } i = min(i, a[Right]); if(-i >= Dx(r)) break; r.max.x += i; /* divide the half bit equally */ toggle = 1-toggle; if(toggle){ r.min.y -= i/2; r.max.y = r.min.y+Dx(r); }else{ r.max.y += i/2; r.min.y = r.max.y-Dx(r); } break; case RBotLeft: i = (d.x+-d.y)/2; if(i>=Dx(r) || i>=Dy(r)) break; i = max(i, a[Left]); i = -min(-i, a[Bottom]); r.min.x += i; r.max.y -= i; break; case RBot: i = d.y; if(i > 0){ i = min(i, a[Right]); i = -max(-i, a[Left]); } i = min(i, a[Bottom]); if(i >= Dy(r)) break; r.max.y += i; /* divide the half bit equally */ toggle = 1-toggle; if(toggle){ r.min.x -= i/2; r.max.x = r.min.x+Dy(r); }else{ r.max.x += i/2; r.min.x = r.max.x-Dy(r); } break; case RBotRight: i = (-d.x+-d.y)/2; if(i>=Dx(r) || i>=Dy(r)) break; i = -min(-i, a[Right]); i = -min(-i, a[Bottom]); r.max.x -= i; r.max.y -= i; break; } if(Dx(r)<3 || Dy(r)<3){ *rp = oldr; return 0; } *rp = r; return !eqrect(r, oldr);}voidrlist(Rectangle r, Rectangle *ra){ Rectangle tr; tr = r; tr.max.y = r.min.y+Dy(r)/4; ra[0] = tr; ra[0].max.x = tr.min.x+Dx(tr)/4; ra[1] = tr; ra[1].min.x = ra[0].max.x; ra[1].max.x = tr.max.x-Dx(tr)/4; ra[2] = tr; ra[2].min.x = ra[1].max.x; tr.min.y = tr.max.y; tr.max.y = r.max.y-Dy(r)/4; ra[3] = tr; ra[3].max.x = tr.min.x+Dx(tr)/4; ra[4] = tr; ra[4].min.x = ra[3].max.x; ra[4].max.x = tr.max.x-Dx(tr)/4; ra[5] = tr; ra[5].min.x = ra[4].max.x; tr.min.y = tr.max.y; tr.max.y = r.max.y; ra[6] = tr; ra[6].max.x = tr.min.x+Dx(tr)/4; ra[7] = tr; ra[7].min.x = ra[6].max.x; ra[7].max.x = tr.max.x-Dx(tr)/4; ra[8] = tr; ra[8].min.x = ra[7].max.x;}intabs(int a){ if(a < 0) return -a; return a;}voidusage(void){ fprint(2, "usage: mug [file.bit]\n"); exits("usage");}voideresized(int new){ if(new && getwindow(display, Refmesg) < 0) fprint(2,"can't reattach to window"); drawscreen(1);}/*interface notescursor changes while in rbig to indicate region.only button 1 works for resizing regiononly button 1 works for moving thingy in rampbutton-3 menu: Reset, Depth, Undo, Save, Write*/Cursor tl = { {-4, -4}, {0xfe, 0x00, 0x82, 0x00, 0x8c, 0x00, 0x87, 0xff, 0xa0, 0x01, 0xb0, 0x01, 0xd0, 0x01, 0x11, 0xff, 0x11, 0x00, 0x11, 0x00, 0x11, 0x00, 0x11, 0x00, 0x11, 0x00, 0x11, 0x00, 0x11, 0x00, 0x1f, 0x00, }, {0x00, 0x00, 0x7c, 0x00, 0x70, 0x00, 0x78, 0x00, 0x5f, 0xfe, 0x4f, 0xfe, 0x0f, 0xfe, 0x0e, 0x00, 0x0e, 0x00, 0x0e, 0x00, 0x0e, 0x00, 0x0e, 0x00, 0x0e, 0x00, 0x0e, 0x00, 0x0e, 0x00, 0x00, 0x00, }};Cursor t = { {-7, -8}, {0x00, 0x00, 0x00, 0x00, 0x03, 0x80, 0x06, 0xc0, 0x1c, 0x70, 0x10, 0x10, 0x0c, 0x60, 0xfc, 0x7f, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x03, 0x80, 0x0f, 0xe0, 0x03, 0x80, 0x03, 0x80, 0x7f, 0xfe, 0x7f, 0xfe, 0x7f, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }};Cursor tr = { {-11, -4}, {0x00, 0x7f, 0x00, 0x41, 0x00, 0x31, 0xff, 0xe1, 0x80, 0x05, 0x80, 0x0d, 0x80, 0x0b, 0xff, 0x88, 0x00, 0x88, 0x0, 0x88, 0x00, 0x88, 0x00, 0x88, 0x00, 0x88, 0x00, 0x88, 0x00, 0x88, 0x00, 0xf8, }, {0x00, 0x00, 0x00, 0x3e, 0x00, 0x0e, 0x00, 0x1e, 0x7f, 0xfa, 0x7f, 0xf2, 0x7f, 0xf0, 0x00, 0x70, 0x00, 0x70, 0x00, 0x70, 0x00, 0x70, 0x00, 0x70, 0x00, 0x70, 0x00, 0x70, 0x00, 0x70, 0x00, 0x00, }};Cursor r = { {-8, -7}, {0x07, 0xc0, 0x04, 0x40, 0x04, 0x40, 0x04, 0x58, 0x04, 0x68, 0x04, 0x6c, 0x04, 0x06, 0x04, 0x02, 0x04, 0x06, 0x04, 0x6c, 0x04, 0x68, 0x04, 0x58, 0x04, 0x40, 0x04, 0x40, 0x04, 0x40, 0x07, 0xc0, }, {0x00, 0x00, 0x03, 0x80, 0x03, 0x80, 0x03, 0x80, 0x03, 0x90, 0x03, 0x90, 0x03, 0xf8, 0x03, 0xfc, 0x03, 0xf8, 0x03, 0x90, 0x03, 0x90, 0x03, 0x80, 0x03, 0x80, 0x03, 0x80, 0x03, 0x80, 0x00, 0x00, }};Cursor br = { {-11, -11}, {0x00, 0xf8, 0x00, 0x88, 0x00, 0x88, 0x00, 0x88, 0x00, 0x88, 0x00, 0x88, 0x00, 0x88, 0x00, 0x88, 0xff, 0x88, 0x80, 0x0b, 0x80, 0x0d, 0x80, 0x05, 0xff, 0xe1, 0x00, 0x31, 0x00, 0x41, 0x00, 0x7f, }, {0x00, 0x00, 0x00, 0x70, 0x00, 0x70, 0x00, 0x70, 0x0, 0x70, 0x00, 0x70, 0x00, 0x70, 0x00, 0x70, 0x00, 0x70, 0x7f, 0xf0, 0x7f, 0xf2, 0x7f, 0xfa, 0x00, 0x1e, 0x00, 0x0e, 0x00, 0x3e, 0x00, 0x00, }};Cursor b = { {-7, -7}, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0xfc, 0x7f, 0x0c, 0x60, 0x10, 0x10, 0x1c, 0x70, 0x06, 0xc0, 0x03, 0x80, 0x00, 0x00, 0x00, 0x00, }, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xfe, 0x7f, 0xfe, 0x7f, 0xfe, 0x03, 0x80, 0x03, 0x80, 0x0f, 0xe0, 0x03, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }};Cursor bl = { {-4, -11}, {0x1f, 0x00, 0x11, 0x00, 0x11, 0x00, 0x11, 0x00, 0x11, 0x00, 0x11, 0x00, 0x11, 0x00, 0x11, 0x00, 0x11, 0xff, 0xd0, 0x01, 0xb0, 0x01, 0xa0, 0x01, 0x87, 0xff, 0x8c, 0x00, 0x82, 0x00, 0xfe, 0x00, }, {0x00, 0x00, 0x0e, 0x00, 0x0e, 0x00, 0x0e, 0x00, 0x0e, 0x00, 0x0e, 0x00, 0x0e, 0x00, 0x0e, 0x00, 0x0e, 0x00, 0x0f, 0xfe, 0x4f, 0xfe, 0x5f, 0xfe, 0x78, 0x00, 0x70, 0x00, 0x7c, 0x00, 0x00, 0x0, }};Cursor l = { {-7, -7}, {0x03, 0xe0, 0x02, 0x20, 0x02, 0x20, 0x1a, 0x20, 0x16, 0x20, 0x36, 0x20, 0x60, 0x20, 0x40, 0x20, 0x60, 0x20, 0x36, 0x20, 0x16, 0x20, 0x1a, 0x20, 0x02, 0x20, 0x02, 0x20, 0x02, 0x20, 0x03, 0xe0, }, {0x00, 0x00, 0x01, 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x09, 0xc0, 0x09, 0xc0, 0x1f, 0xc0, 0x3f, 0xc0, 0x1f, 0xc0, 0x09, 0xc0, 0x09, 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x00, 0x00, }};Cursor boxcursor = { {-7, -7}, {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x1F, 0xF8, 0x1F, 0xF8, 0x1F, 0xF8, 0x1F, 0xF8, 0x1F, 0xF8, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, {0x00, 0x00, 0x7F, 0xFE, 0x7F, 0xFE, 0x7F, 0xFE, 0x70, 0x0E, 0x70, 0x0E, 0x70, 0x0E, 0x70, 0x0E, 0x70, 0x0E, 0x70, 0x0E, 0x70, 0x0E, 0x70, 0x0E, 0x7F, 0xFE, 0x7F, 0xFE, 0x7F, 0xFE, 0x00, 0x00, }};Cursor clearcursor;Cursor *corners[10] = { &tl, &t, &tr, &l, &boxcursor, &r, &bl, &b, &br, nil, /* default arrow */};char *item[] = { "Reset", "Depth", "Undo", "Write", "Exit", nil};Menu menu = { item, nil, 2};/*BUG make less flashy */voidmoveface(Image *back, Point lastp, Image *face, Point p, Point d){ draw(screen, rectaddpt(back->r, subpt(lastp, d)), back, nil, back->r.min); draw(back, back->r, screen, nil, addpt(back->r.min, subpt(p, d))); border(screen, rectaddpt(face->r, subpt(p, d)), -1, display->black, ZP); draw(screen, rectaddpt(face->r, subpt(p, d)), face, nil, face->r.min);}intdragface(Mouse *m, Image *im, Point d, int x){ int i; Point lastp; static Image *back; if(back == nil){ back = allocimage(display, Rect(-1,-1,49,49), display->image->chan, 0, DNofill); if(back == nil) sysfatal("dragface backing store: %r"); } lastp = m->xy; draw(back, back->r, screen, nil, addpt(back->r.min, subpt(lastp, d))); esetcursor(&clearcursor); do{ moveface(back, lastp, im, m->xy, d); lastp = m->xy; }while(*m=emouse(), m->buttons==1); draw(screen, rectaddpt(back->r, subpt(lastp, d)), back, nil, back->r.min); esetcursor(nil); if(m->buttons==0){ for(i=0; i<nelem(face); i++) if(ptinrect(m->xy, rface[i])) return i; if(ptinrect(m->xy, rsmall)) return -1; return x; } while(*m=emouse(), m->buttons) ; return x;}voidinitstate(void){ state.black = 0.0; state.white = 1.0; state.stretch = 1.0; state.depth = 4; state.gamma = 1.0; setgtab(&state); state.selr = insetrect(orig->r, 5); sdx = Dx(state.selr); sdy = Dy(state.selr); if(sdx > sdy) state.selr.max.x = state.selr.min.x+sdy; else state.selr.max.y = state.selr.min.y+sdx;}voidmain(int argc, char **argv){ int ccursor, i, fd, k, n, y; uchar *data; double gammatab[256]; Event e; Mouse m; Point lastp, p; Rectangle nselr, rbig9[9]; ARGBEGIN{ default: usage(); }ARGEND if(argc > 1) usage(); if(argc == 1){ if((fd = open(argv[0], OREAD)) < 0) sysfatal("open %s: %r", argv[0]); }else fd = 0; initdraw(0, 0, "mug"); if((orig = readimage(display, fd, 0)) == nil) sysfatal("readimage: %r"); orig = grey8image(orig); initramp(); initclamp(); initval2cmap(); bkgd = allocimagemix(display, DPaleyellow, DWhite); small = allocimage(display, Rect(0,0,48,48), GREY4, 0, DWhite); tmp8 = allocimage(display, Rect(0,0,48,48), GREY8, 0, DWhite); red = allocimage(display, Rect(0,0,1,1), display->image->chan, 1, DRed); green = allocimage(display, Rect(0,0,1,1), display->image->chan, 1, DGreen); blue = allocimage(display, Rect(0,0,1,1), display->image->chan, 1, DBlue); if(bkgd==nil || small==nil || tmp8==nil || red==nil || green==nil || blue==nil) sysfatal("allocimage: %r"); n = Dx(orig->r)*Dy(orig->r); data = emalloc(n*sizeof data[0]); rdata = emalloc(n*sizeof rdata[0]); if(unloadimage(orig, orig->r, data, n) != n) sysfatal("unloadimage: %r"); for(i=0; i<256; i++) gammatab[i] = pow((255-i)/(double)255.0, GAMMA); for(i=0; i<n; i++) rdata[i] = gammatab[255-data[i]]; initstate(); process(rdata, orig->r, state.selr, small); drawscreen(1); flushimage(display, 1); einit(Emouse|Ekeyboard); ccursor = 9; for(;;){ if((n=eread(Emouse|Ekeyboard, &e))==Ekeyboard) continue; if(n != Emouse) break; m = e.mouse; if(m.buttons&4){ ccursor = 9; esetcursor(corners[ccursor]); switch(emenuhit(3, &m, &menu)){ case -1: continue; case 0: /* Reset */ mark(); initstate(); small = allocimage(display, Rect(0,0,48,48), CHAN1(CGrey, state.depth), 0, DWhite); if(small == nil) sysfatal("allocimage: %r"); process(rdata, orig->r, state.selr, small); drawface(-1); drawscreen(0); break; case 1: /* Depth */ mark(); /* osmall = small, so no freeimage */ state.depth /= 2; if(state.depth == 0) state.depth = 8; small = allocimage(display, Rect(0,0,48,48), CHAN1(CGrey, state.depth), 0, DWhite); if(small == nil) sysfatal("allocimage: %r"); process(rdata, orig->r, state.selr, small); drawface(-1); break; case 2: /* Undo */ undo(); break; case 3: /* Write */ writeface(nil, small); break; case 4: /* Exit */ exits(nil); break; } } if(ptinrect(m.xy, rbig)){ rlist(rectaddpt(state.selr, subpt(rbig.min, orig->r.min)), rbig9); for(i=0; i<9; i++) if(ptinrect(m.xy, rbig9[i])) break; if(i != ccursor){ ccursor = i; esetcursor(corners[ccursor]); } if(i==9) continue; if(m.buttons & 1){ mark(); lastp = m.xy; while(m=emouse(), m.buttons&1){ if(move(state.selr, orig->r, subpt(m.xy, lastp), i, &nselr)){ moveframe(state.selr, nselr); state.selr = nselr; lastp = m.xy; process(rdata, orig->r, state.selr, small); drawface(-1); } } } continue; } if(ccursor != 9){ /* default cursor */ ccursor = 9; esetcursor(corners[ccursor]); } if(ptinrect(m.xy, rramp)){ if(m.buttons != 1) continue; mark(); y = gamma2y(state.gamma); if(abs(y-(m.xy.y-rramp.min.y)) > 5) continue; k = section(m.xy.x-rramp.min.x); drawrampbar(green, &state); lastp = m.xy; while(m=emouse(), m.buttons&1){ if(!ptinrect(m.xy, rramp)) continue; switch(k){ case -1: continue; case 0: if((m.xy.x-rramp.min.x)/255.0 < state.white){ state.black = (m.xy.x-rramp.min.x)/255.0; break; } continue; case 1: state.gamma = y2gamma(m.xy.y-rramp.min.y); setgtab(&state); break; case 2: if((m.xy.x-rramp.min.x)/255.0 > state.black){ state.white = (m.xy.x-rramp.min.x)/255.0; break; } continue; case 10: state.black += (m.xy.x-lastp.x)/255.0; state.white += (m.xy.x-lastp.x)/255.0; state.gamma = y2gamma(p.y); break; } process(rdata, orig->r, state.selr, small); drawface(-1); drawrampbar(green, &state); } if(m.buttons == 0){ process(rdata, orig->r, state.selr, small); drawface(-1); drawrampbar(red, &state); }else undo(); continue; } if(ptinrect(m.xy, rsmall)){ if(m.buttons != 1) continue; n=dragface(&m, small, subpt(m.xy, rsmall.min), -1); if(n == -1) continue; saveface(nil, n); } for(i=0; i<nelem(face); i++) if(ptinrect(m.xy, rface[i])) break; if(i<nelem(face) && face[i] != nil){ if(m.buttons != 1) continue; n=dragface(&m, face[i]->small, subpt(m.xy, rface[i].min), i); if(n == i) continue; saveface(face[i], n); continue; } do m = emouse(); while(m.buttons==1); } exits(nil);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -