📄 tweak.c
字号:
chan = GREY4; break; case 8: chan = CMAP8; break; } b = allocimage(display, Rect(0, 0, y, y), chan, 0, -1); if(b == 0){ mesg("image alloc failed file %s: %r", file); free(data); close(fd); goto Err; } i = 0; for(j=0; j<y; j++){ for(x=0; (c=data[i])!='\n'; ){ if(c=='0' && data[i+1] == 'x'){ i += 2; continue; } if(strchr(hex, c)){ buf[x++] = ~((tohex(c)<<4) | tohex(data[i+1])); i += 2; continue; } i++; } i++; loadimage(b, Rect(0, j, y, j+1), buf, sizeof buf); } free(data); }else{ face = NORMAL; s = 0; b = readimage(display, fd, 0); if(b == 0){ mesg("can't read bitmap file %s: %r", file); close(fd); goto Err; } if(seek(fd, 0, 1) < d->length) s = readsubfonti(display, file, fd, b, 0); } close(fd); t = malloc(sizeof(Thing)); if(t == 0){ nomem: mesg("malloc failed: %r"); if(s) freesubfont(s); else freeimage(b); goto Err; } t->name = strdup(file); if(t->name == 0){ free(t); goto nomem; } t->b = b; t->s = s; t->face = face; t->mod = 0; t->parent = 0; t->c = -1; t->mag = 1; t->off = 0; memmove(err, oerr, sizeof err); return t;}intatline(int x, Point p, char *line, char *buf){ char *s, *c, *word, *hit; int w, wasblank; Rune r; wasblank = 1; hit = 0; word = 0; for(s=line; *s; s+=w){ w = chartorune(&r, s); x += runestringnwidth(font, &r, 1); if(wasblank && r!=' ') word = s; wasblank = 0; if(r == ' '){ if(x >= p.x) break; wasblank = 1; } if(r == ':') hit = word; } if(x < p.x) return 0; c = utfrune(hit, ':'); strncpy(buf, hit, c-hit); buf[c-hit] = 0; return 1;}intattext(Thing *t, Point p, char *buf){ char l0[256], l1[256]; if(!ptinrect(p, t->tr)) return 0; stext(t, l0, l1); if(p.y < t->tr.min.y+font->height) return atline(t->r.min.x, p, l0, buf); else return atline(t->r.min.x, p, l1, buf);}inttype(char *buf, char *tag){ Rune r; char *p; esetcursor(&busy); p = buf; for(;;){ *p = 0; mesg("%s: %s", tag, buf); r = ekbd(); switch(r){ case '\n': mesg(""); esetcursor(0); return p-buf; case 0x15: /* control-U */ p = buf; break; case '\b': if(p > buf) --p; break; default: p += runetochar(p, &r); } }}voidtextedit(Thing *t, char *tag){ char buf[256]; char *s; Image *b; Subfont *f; Fontchar *fc, *nfc; Rectangle r; ulong chan; int i, ld, d, w, c, doredraw, fdx, x; Thing *nt; buttons(Up); if(type(buf, tag) == 0) return; if(strcmp(tag, "file") == 0){ for(s=buf; *s; s++) if(*s <= ' '){ mesg("illegal file name"); return; } if(strcmp(t->name, buf) != 0){ if(t->parent) t->parent->mod = 1; else t->mod = 1; } for(nt=thing; nt; nt=nt->next) if(t==nt || t->parent==nt || nt->parent==t){ free(nt->name); nt->name = strdup(buf); if(nt->name == 0){ mesg("malloc failed: %r"); return; } text(nt); } return; } if(strcmp(tag, "depth") == 0){ if(buf[0]<'0' || '9'<buf[0] || (d=atoi(buf))<0 || d>8 || log2[d]<0){ mesg("illegal ldepth"); return; } if(d == t->b->depth) return; if(t->parent) t->parent->mod = 1; else t->mod = 1; if(d == 8) chan = CMAP8; else chan = CHAN1(CGrey, d); for(nt=thing; nt; nt=nt->next){ if(nt!=t && nt!=t->parent && nt->parent!=t) continue; b = allocimage(display, nt->b->r, chan, 0, 0); if(b == 0){ nobmem: mesg("image alloc failed: %r"); return; } draw(b, b->r, nt->b, nil, nt->b->r.min); freeimage(nt->b); nt->b = b; if(nt->s){ b = allocimage(display, nt->b->r, chan, 0, -1); if(b == 0) goto nobmem; draw(b, b->r, nt->b, nil, nt->b->r.min); f = allocsubfont(t->name, nt->s->n, nt->s->height, nt->s->ascent, nt->s->info, b); if(f == 0){ nofmem: freeimage(b); mesg("can't make subfont: %r"); return; } nt->s->info = 0; /* prevent it being freed */ nt->s->bits = 0; freesubfont(nt->s); nt->s = f; } drawthing(nt, 0); } return; } if(strcmp(tag, "mag") == 0){ if(buf[0]<'0' || '9'<buf[0] || (ld=atoi(buf))<=0 || ld>Maxmag){ mesg("illegal magnification"); return; } if(t->mag == ld) return; t->mag = ld; redraw(t); return; } if(strcmp(tag, "r") == 0){ if(t->s){ mesg("can't change rectangle of subfont\n"); return; } s = buf; r.min.x = strtoul(s, &s, 0); r.min.y = strtoul(s, &s, 0); r.max.x = strtoul(s, &s, 0); r.max.y = strtoul(s, &s, 0); if(Dx(r)<=0 || Dy(r)<=0){ mesg("illegal rectangle"); return; } if(t->parent) t = t->parent; for(nt=thing; nt; nt=nt->next){ if(nt->parent==t && !rectinrect(nt->b->r, r)) tclose1(nt); } b = allocimage(display, r, t->b->chan, 0, 0); if(b == 0) goto nobmem; draw(b, r, t->b, nil, r.min); freeimage(t->b); t->b = b; b = allocimage(display, r, t->b->chan, 0, 0); if(b == 0) goto nobmem; redraw(t); t->mod = 1; return; } if(strcmp(tag, "ascent") == 0){ if(buf[0]<'0' || '9'<buf[0] || (ld=atoi(buf))<0 || ld>t->s->height){ mesg("illegal ascent"); return; } if(t->s->ascent == ld) return; t->s->ascent = ld; text(t); t->mod = 1; return; } if(strcmp(tag, "height") == 0){ if(buf[0]<'0' || '9'<buf[0] || (ld=atoi(buf))<0){ mesg("illegal height"); return; } if(t->s->height == ld) return; t->s->height = ld; text(t); t->mod = 1; return; } if(strcmp(tag, "left")==0 || strcmp(tag, "width") == 0){ if(buf[0]<'0' || '9'<buf[0] || (ld=atoi(buf))<0){ mesg("illegal value"); return; } fc = &t->parent->s->info[t->c]; if(strcmp(tag, "left")==0){ if(fc->left == ld) return; fc->left = ld; }else{ if(fc->width == ld) return; fc->width = ld; } text(t); t->parent->mod = 1; return; } if(strcmp(tag, "offset(hex)") == 0){ if(!strchr(hex, buf[0])){ illoff: mesg("illegal offset"); return; } s = 0; ld = strtoul(buf, &s, 16); if(*s) goto illoff; t->off = ld; text(t); for(nt=thing; nt; nt=nt->next) if(nt->parent == t) text(nt); return; } if(strcmp(tag, "n") == 0){ if(buf[0]<'0' || '9'<buf[0] || (w=atoi(buf))<=0){ mesg("illegal n"); return; } f = t->s; if(w == f->n) return; doredraw = 0; again: for(nt=thing; nt; nt=nt->next) if(nt->parent == t){ doredraw = 1; tclose1(nt); goto again; } r = t->b->r; if(w < f->n) r.max.x = f->info[w].x; b = allocimage(display, r, t->b->chan, 0, 0); if(b == 0) goto nobmem; draw(b, b->r, t->b, nil, r.min); fdx = Dx(editr) - 2*Border; if(Dx(t->b->r)/fdx != Dx(b->r)/fdx) doredraw = 1; freeimage(t->b); t->b = b; b = allocimage(display, r, t->b->chan, 0, 0); if(b == 0) goto nobmem; draw(b, b->r, t->b, nil, r.min); nfc = malloc((w+1)*sizeof(Fontchar)); if(nfc == 0){ mesg("malloc failed"); freeimage(b); return; } fc = f->info; for(i=0; i<=w && i<=f->n; i++) nfc[i] = fc[i]; if(w+1 < i) memset(nfc+i, 0, ((w+1)-i)*sizeof(Fontchar)); x = fc[f->n].x; for(; i<=w; i++) nfc[i].x = x; f = allocsubfont(t->name, w, f->height, f->ascent, nfc, b); if(f == 0) goto nofmem; t->s->bits = nil; /* don't free it */ freesubfont(t->s); f->info = nfc; t->s = f; if(doredraw) redraw(thing); else drawthing(t, 0); t->mod = 1; return; } if(strcmp(tag, "iwidth") == 0){ if(buf[0]<'0' || '9'<buf[0] || (w=atoi(buf))<0){ mesg("illegal iwidth"); return; } w -= Dx(t->b->r); if(w == 0) return; r = t->parent->b->r; r.max.x += w; c = t->c; t = t->parent; f = t->s; b = allocimage(display, r, t->b->chan, 0, 0); if(b == 0) goto nobmem; fc = &f->info[c]; draw(b, Rect(b->r.min.x, b->r.min.y, b->r.min.x+(fc[1].x-t->b->r.min.x), b->r.min.y+Dy(t->b->r)), t->b, nil, t->b->r.min); draw(b, Rect(fc[1].x+w, b->r.min.y, w+t->b->r.max.x, b->r.min.y+Dy(t->b->r)), t->b, nil, Pt(fc[1].x, t->b->r.min.y)); fdx = Dx(editr) - 2*Border; doredraw = 0; if(Dx(t->b->r)/fdx != Dx(b->r)/fdx) doredraw = 1; freeimage(t->b); t->b = b; b = allocimage(display, r, t->b->chan, 0, 0); if(b == 0) goto nobmem; draw(b, b->r, t->b, nil, t->b->r.min); fc = &f->info[c+1]; for(i=c+1; i<=f->n; i++, fc++) fc->x += w; f = allocsubfont(t->name, f->n, f->height, f->ascent, f->info, b); if(f == 0) goto nofmem; /* t->s and f share info; free carefully */ fc = f->info; t->s->bits = nil; t->s->info = 0; freesubfont(t->s); f->info = fc; t->s = f; if(doredraw) redraw(t); else drawthing(t, 0); /* redraw all affected chars */ for(nt=thing; nt; nt=nt->next){ if(nt->parent!=t || nt->c<c) continue; fc = &f->info[nt->c]; r.min.x = fc[0].x; r.min.y = nt->b->r.min.y; r.max.x = fc[1].x; r.max.y = nt->b->r.max.y; b = allocimage(display, r, nt->b->chan, 0, 0); if(b == 0) goto nobmem; draw(b, r, t->b, nil, r.min); doredraw = 0; if(Dx(nt->b->r)/fdx != Dx(b->r)/fdx) doredraw = 1; freeimage(nt->b); nt->b = b; if(c != nt->c) text(nt); else{ if(doredraw) redraw(nt); else drawthing(nt, 0); } } t->mod = 1; return; } mesg("cannot edit %s in file %s", tag, t->name);}voidcntledit(char *tag){ char buf[256]; long l; buttons(Up); if(type(buf, tag) == 0) return; if(strcmp(tag, "mag") == 0){ if(buf[0]<'0' || '9'<buf[0] || (l=atoi(buf))<=0 || l>Maxmag){ mesg("illegal magnification"); return; } mag = l; cntl(); return; } if(strcmp(tag, "but1")==0 || strcmp(tag, "but2")==0){ if(buf[0]<'0' || '9'<buf[0] || (l=atoi(buf))<0 || l>255){ mesg("illegal value"); return; } if(strcmp(tag, "but1") == 0) but1val = l; else if(strcmp(tag, "but2") == 0) but2val = l; cntl(); return; } if(strcmp(tag, "invert-on-copy")==0){ if(buf[0]=='y' || buf[0]=='1') invert = 1; else if(buf[0]=='n' || buf[0]=='0') invert = 0; else{ mesg("illegal value"); return; } cntl(); return; } mesg("cannot edit %s", tag);}voidbuttons(int ud){ while((mouse.buttons==0) != ud) mouse = emouse();}Pointscreenpt(Thing *t, Point realp){ int fdx, n; Point p; fdx = Dx(editr)-2*Border; if(t->mag > 1) fdx -= fdx%t->mag; p = mulpt(subpt(realp, t->b->r.min), t->mag); if(fdx < Dx(t->b->r)*t->mag){ n = p.x/fdx; p.y += n * (Dy(t->b->r)*t->mag+Border); p.x -= n * fdx; } p = addpt(p, t->r.min); return p;}Pointrealpt(Thing *t, Point screenp){ int fdx, n, dy; Point p; fdx = (Dx(editr)-2*Border); if(t->mag > 1) fdx -= fdx%t->mag; p.y = screenp.y-t->r.min.y; p.x = 0; if(fdx < Dx(t->b->r)*t->mag){ dy = Dy(t->b->r)*t->mag+Border; n = (p.y/dy); p.x = n * fdx; p.y -= n * dy; } p.x += screenp.x-t->r.min.x; p = addpt(divpt(p, t->mag), t->b->r.min); return p;}intsweep(int but, Rectangle *r){ Thing *t; Point p, q, lastq; esetcursor(&sweep0); buttons(Down); if(mouse.buttons != (1<<(but-1))){ buttons(Up); esetcursor(0); return 0; } p = mouse.xy; for(t=thing; t; t=t->next) if(ptinrect(p, t->r)) break; if(t) p = screenpt(t, realpt(t, p)); r->min = p; r->max = p; esetcursor(&box); lastq = ZP; while(mouse.buttons == (1<<(but-1))){ edrawgetrect(insetrect(*r, -Borderwidth), 1); mouse = emouse(); edrawgetrect(insetrect(*r, -Borderwidth), 0); q = mouse.xy; if(t) q = screenpt(t, realpt(t, q)); if(eqpt(q, lastq)) continue; *r = canonrect(Rpt(p, q)); lastq = q; } esetcursor(0); if(mouse.buttons){ buttons(Up); return 0; } return 1;}voidopenedit(Thing *t, Point pt, int c){ int x, y; Point p; Rectangle r; Rectangle br; Fontchar *fc; Thing *nt; if(t->b->depth > 8){ mesg("image has depth %d; can't handle >8", t->b->depth); return; } br = t->b->r; if(t->s == 0){ c = -1; /* if big enough to bother, sweep box */ if(Dx(br)<=16 && Dy(br)<=16) r = br; else{ if(!sweep(1, &r)) return; r = rectaddpt(r, subpt(br.min, t->r.min)); if(!rectclip(&r, br)) return; if(Dx(br) <= 8){ r.min.x = br.min.x; r.max.x = br.max.x; }else if(Dx(r) < 4){ toosmall: mesg("rectangle too small"); return; } if(Dy(br) <= 8){ r.min.y = br.min.y; r.max.y = br.max.y; }else if(Dy(r) < 4) goto toosmall; } }else if(c >= 0){ fc = &t->s->info[c]; r.min.x = fc[0].x; r.min.y = br.min.y; r.max.x = fc[1].x; r.max.y = br.min.y + Dy(br); }else{ /* just point at character */ fc = t->s->info; p = addpt(pt, subpt(br.min, t->r.min)); x = br.min.x; y = br.min.y; for(c=0; c<t->s->n; c++,fc++){ again: r.min.x = x; r.min.y = y; r.max.x = x + fc[1].x - fc[0].x; r.max.y = y + Dy(br); if(ptinrect(p, r)) goto found; if(r.max.x >= br.min.x+Dx(t->r)){ x -= Dx(t->r);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -