/* -- write a title -- */ void write_title(struct SYMBOL *s) { char *p; p = &s->as.text[2]; while (isspace((unsigned char) *p)) p++; if (*p == '\0') return; p = trim_title(p, s == info['T' - 'A']); if (s == info['T' - 'A']) { bskip(cfmt.titlespace + cfmt.font_tb[TITLEFONT].size); set_font(TITLEFONT); } else { bskip(cfmt.subtitlespace + cfmt.font_tb[SUBTITLEFONT].size); set_font(SUBTITLEFONT); } if (cfmt.titleleft) PUT0("0 0 M("); else PUT1("%.1f 0 M(", 0.5 * ((cfmt.landscape ? cfmt.pageheight : cfmt.pagewidth) - cfmt.leftmargin - cfmt.rightmargin) / cfmt.scale); tex_str(p); PUT2("%s)show%s\n", tex_buf, cfmt.titleleft ? "" : "c"); }
/* -- output history -- */ void put_history(void) { struct SYMBOL *s, *s2; float h; bskip(cfmt.textspace); str_font(HISTORYFONT); for (s = info['I' - 'A']; s != 0; s = s->next) { if ((s2 = info[s->as.text[0] - 'A']) == 0) continue; get_str(tex_buf, &s->as.text[1], 256); h = cfmt.font_tb[HISTORYFONT].size * cfmt.lineskipfac; set_font(HISTORYFONT); PUT1("0 0 M(%s)show ", tex_buf); for (;;) { put_inf(s2); if ((s2 = s2->next) == 0) break; bskip(h); PUT0("50 0 M "); } bskip(h * 1.2); buffer_eob(); } }
/* -- write a text block -- */ void write_text_block(int job, int abc_state) { if (strtw < 0) return; if (strtx) { PUT1(")%s", strop); strtx = 0; } if (job == T_JUSTIFY) PUT0("}def\n" "/strop/show load def str\n"); else if (job == T_FILL) PUT0("\n"); bskip(cfmt.font_tb[TEXTFONT].size * cfmt.parskipfac); buffer_eob(); /* next line to allow pagebreak after each paragraph */ if (!epsf && abc_state != ABC_S_TUNE) write_buffer(); strtw = -1; }
int peers(char *page, unsigned int size, cjdc_ctx *ctx) { char *pk, *in, *out, *dup, *los, *oor, *sta, *swi, *usr; char ip6[43], *p = page, *end = page + size; char str[1024], *q = str; int more = 0, state = 0; if (*p++ != 'd') goto err; goto init; while (p < end) { char c =*p; if (state & indict) { switch (c) { case 'e': /* end of dict */ state &= ~indict; ++p; if (pk == NULL) goto pk_invalid; while (*pk++ != ':'); if (pubk2ip6(pk, ip6 + 3) < 0) { pk_invalid: ip6[0] = '1'; ip6[1] = ':'; ip6[2] = '?'; } else { ip6[0] = '3'; ip6[1] = '9'; ip6[2] = ':'; } q = bputs(q, ip6, 40); q = bputs(q, swi, 20); q = bputi(q, in); q = bputi(q, out); q = bputs(q, sta, 4); *q++ = ' '; q = bputi(q, dup); q = bputi(q, los); q = bputi(q, oor); if (usr) q = bputs(q, usr, 16); *q++ = '\n'; init: in = out = dup = los = oor = NULL; pk = sta = swi = usr = NULL; break; case '0': /* skip leading zeros */ skipzeros: while (*++p == '0'); break; case '1': switch (c = *++p) { case '0': if (p[2] == 'd') /* duplicate */ dup = bgeti(10, &p); else goto skip2; break; case '1': switch (p[2]) { case 'l': /* lostPackets */ los = bgeti(11, &p); break; case 's': /* switchLabel */ swi = bgets(11, &p); break; default: goto skip2; } break; case '8': /* 18:receivedOutOfRange */ oor = bgeti(18, &p); break; default: skip2: --p; goto skip; } break; case '4': if (p[2] == 'u') /* user */ usr = bgets(4, &p); else goto skip; break; case '5': if (p[2] == 's') /* state */ sta = bgets(5, &p); else goto skip; break; case '7': /* 7:bytesIn */ in = bgeti(7, &p); break; case '8': /* 8:bytesOut */ out = bgeti(8, &p); break; case '9': /* 9:publicKey */ pk = bgets(9, &p); break; default: goto skip; } } else if (state & inlist) { switch (c) { case 'd': state |= indict; ++p; break; case 'e': state &= ~inlist; ++p; break; default: goto err; } } else if (state & inpeers) { switch (c) { case 'l': /* start of list */ state |= inlist; ++p; break; case 'e': /* end of top dict */ state &= ~inpeers; ++p; goto out_; default: goto skip; } } else { switch (c) { case '0': goto skipzeros; case '4': if (p[2] == 'm' && p[7] == '1') more = 1; goto skip; case '5': if (p[2] == 'p' && p[6] == 's') state |= inpeers; goto skip; default: skip: p = bskip(p); } } if (p == NULL) { err: more = -1; break; } } out_: write(1, str, q - str); return more; }
/* -- write heading with format -- */ static void write_headform(float lwidth) { char *p, *q; struct SYMBOL *s; struct FONTSPEC *f; int align, i, j; float x, y, xa[3], ya[3], sz, yb[3]; char inf_nb[26]; INFO inf_s; char inf_ft[26]; float inf_sz[26]; char fmt[64]; memset(inf_nb, 0, sizeof inf_nb); memset(inf_ft, HISTORYFONT, sizeof inf_ft); inf_ft['A' - 'A'] = INFOFONT; inf_ft['C' - 'A'] = COMPOSERFONT; inf_ft['O' - 'A'] = COMPOSERFONT; inf_ft['P' - 'A'] = PARTSFONT; inf_ft['Q' - 'A'] = TEMPOFONT; inf_ft['R' - 'A'] = INFOFONT; inf_ft['T' - 'A'] = TITLEFONT; inf_ft['X' - 'A'] = TITLEFONT; memcpy(inf_s, info, sizeof inf_s); memset(inf_sz, 0, sizeof inf_sz); inf_sz['A' - 'A'] = cfmt.infospace; inf_sz['C' - 'A'] = cfmt.composerspace; inf_sz['O' - 'A'] = cfmt.composerspace; inf_sz['R' - 'A'] = cfmt.infospace; p = cfmt.titleformat; j = 0; for (;;) { while (isspace((unsigned char) *p)) p++; if (*p == '\0') break; i = *p - 'A'; if ((unsigned) i < 26) { inf_nb[i]++; switch (p[1]) { default: align = A_CENTER; break; case '1': align = A_RIGHT; p++; break; case '-': align = A_LEFT; p++; break; } if (j < sizeof fmt - 4) { fmt[j++] = i; fmt[j++] = align; } } else if (*p == ',') { if (j < sizeof fmt - 3) fmt[j++] = 126; /* next line */ } else if (*p == '+') { if (j > 0 && fmt[j - 1] < 125 && j < sizeof fmt - 3) fmt[j++] = 125; /* concatenate */ /*new fixme: add free text "..." ?*/ } p++; } fmt[j++] = 126; /* newline */ fmt[j] = 127; /* end of format */ ya[0] = ya[1] = ya[2] = cfmt.titlespace;; xa[0] = 0; xa[1] = lwidth * 0.5; xa[2] = lwidth; p = fmt; for (;;) { yb[0] = yb[1] = yb[2] = y = 0; q = p; for (;;) { i = *q++; if (i >= 126) /* if newline */ break; align = *q++; if (yb[align + 1] != 0) continue; s = inf_s[i]; if (s == 0 || inf_nb[i] == 0) continue; j = inf_ft[i]; f = &cfmt.font_tb[j]; sz = f->size * 1.1 + inf_sz[i]; if (y < sz) y = sz; yb[align + 1] = sz; /*fixme:should count the height of the concatenated field*/ if (*q == 125) q++; } for (i = 0; i < 3; i++) ya[i] += y - yb[i]; for (;;) { i = *p++; if (i >= 126) /* if newline */ break; align = *p++; s = inf_s[i]; if (s == 0 || inf_nb[i] == 0) continue; j = inf_ft[i]; str_font(j); x = xa[align + 1]; f = &cfmt.font_tb[j]; sz = f->size * 1.1 + inf_sz[i]; y = ya[align + 1] + sz; PUT2("%.1f %.1f M ", x, -y); if (*p == 125) { /* concatenate */ p++; /*fixme: do it work with different fields*/ if (*p == i && p[1] == align && s->next != 0) { char buf[256], *r; q = s->as.text; if (q[1] == ':') q += 2; while (isspace((unsigned char) *q)) q++; if (i == 'T' - 'A') q = trim_title(q, s == inf_s['T' - 'A']); strncpy(buf, q, sizeof buf - 1); buf[sizeof buf - 1] = '\0'; j = strlen(buf); if (j < sizeof buf - 1) { buf[j] = ' '; buf[j + 1] = '\0'; } s = s->next; q = s->as.text; if (q[1] == ':') q += 2; while (isspace((unsigned char) *q)) q++; if (s->as.text[0] == 'T' && s->as.text[1] == ':') q = trim_title(q, 0); r = buf + strlen(buf); strncpy(r, q, buf + sizeof buf - r - 1); tex_str(buf); str_out(tex_buf, align); PUT0("\n"); inf_nb[i]--; p += 2; } } else if (i == 'Q' - 'A') { /* special case for tempo */ if (align != A_LEFT) { float w; w = tempo_width(s); if (align == A_CENTER) PUT1("-%.1f 0 RM ", w * 0.5); else PUT1("-%.1f 0 RM ", w); } write_tempo(s, 0, 0.75); } else put_inf2r(s, 0, align); if (inf_s[i] == info['T' - 'A']) { inf_ft[i] = SUBTITLEFONT; str_font(SUBTITLEFONT); f = &cfmt.font_tb[SUBTITLEFONT]; inf_sz[i] = cfmt.subtitlespace; sz = f->size * 1.1 + inf_sz[i]; } s = s->next; if (inf_nb[i] == 1) { while (s != 0) { y += sz; PUT2("%.1f %.1f M ", x, -y); put_inf2r(s, 0, align); s = s->next; } } inf_s[i] = s; inf_nb[i]--; ya[align + 1] = y; } if (ya[1] > ya[0]) ya[0] = ya[1]; if (ya[2] > ya[0]) ya[0] = ya[2]; if (*p == 127) { bskip(ya[0]); break; } ya[1] = ya[2] = ya[0]; } }
/* -- output the words after tune -- */ void put_words(struct SYMBOL *words) { struct SYMBOL *s, *s_end, *s2; char *p; int i, n, have_text, max2col; float middle; str_font(WORDSFONT); /* see if we may have 2 columns */ middle = 0.5 * ((cfmt.landscape ? cfmt.pageheight : cfmt.pagewidth) - cfmt.leftmargin - cfmt.rightmargin) / cfmt.scale; max2col = (int) ((middle - 45.) / (cwid('a') * cfmt.font_tb[WORDSFONT].swfac)); n = 0; have_text = 0; for (s = words; s != 0; s = s->next) { p = &s->as.text[2]; while (isspace((unsigned char) *p)) p++; if (strlen(p) > max2col) { n = 0; break; } if (*p == '\0') { if (have_text) { n++; have_text = 0; } } else have_text = 1; } if (n > 0) { n++; n /= 2; i = n; have_text = 0; s_end = words; for (;;) { p = &s_end->as.text[2]; while (isspace((unsigned char) *p)) p++; if (*p == '\0') { if (have_text && --i <= 0) break; have_text = 0; } else have_text = 1; s_end = s_end->next; } s2 = s_end->next; } else { s_end = 0; s2 = 0; } /* output the text */ bskip(cfmt.wordsspace); for (s = words; s != 0 || s2 != 0; ) { bskip(cfmt.lineskipfac * cfmt.font_tb[WORDSFONT].size); if (s != 0) { put_wline(&s->as.text[2], 45., 0); s = s->next; if (s == s_end) s = 0; } if (s2 != 0) { if (put_wline(&s2->as.text[2], 20. + middle, 1)) { if (--n == 0) { if (s != 0) n++; else if (s2->next != 0) { /* center the last words */ /*fixme: should compute the width average.. */ middle *= 0.6; } } } s2 = s2->next; } } buffer_eob(); }
/* -- add text to a block -- */ void add_to_text_block(char *s, int job) { float baseskip, lw; char *p, sep; struct FONTSPEC *f; /* if first line, set the fonts */ if (strtw < 0) { str_font(TEXTFONT); strlw = ((cfmt.landscape ? cfmt.pageheight : cfmt.pagewidth) - cfmt.leftmargin - cfmt.rightmargin) / cfmt.scale; } if (curft > 0) f = &cfmt.font_tb[curft]; else f = &cfmt.font_tb[defft]; baseskip = f->size * cfmt.lineskipfac; /* follow lines */ if (job == T_LEFT || job == T_CENTER || job == T_RIGHT) { if (*s != '\0') { bskip(baseskip); if (job == T_LEFT) { PUT0("0 0 M "); put_str(s, A_LEFT); } else if (job == T_CENTER) { PUT1("%.1f 0 M ", strlw * 0.5); put_str(s, A_CENTER); } else { PUT1("%.1f 0 M ", strlw); put_str(s, A_RIGHT); } } else { bskip(baseskip * 0.5); buffer_eob(); } strtw = 0; return; } /* fill or justify lines */ if (strtw < 0) { /* if first line */ curft = defft; bskip(baseskip); PUT0("0 0 M "); if (job == T_FILL) strop = "show"; else { PUT0("/str{"); outft = -1; strop = "strop"; } strns = 0; strtw = 0; } if (*s == '\0') { /* empty line */ if (strtx) { PUT1(")%s", strop); strtx = 0; } if (job == T_JUSTIFY) PUT0("}def\n" "/strop/show load def str\n"); else PUT0("\n"); bskip(f->size * cfmt.lineskipfac * 1.5); buffer_eob(); PUT0("0 0 M "); if (job == T_JUSTIFY) { PUT0("/str{"); outft = -1; } strns = 0; strtw = 0; return; } p = s; for (;;) { while (*p != ' ' && *p != '\0') p++; sep = *p; *p = '\0'; lw = tex_str(s); if (strtw + lw > strlw) { if (strtx) { PUT1(")%s ", strop); strtx = 0; } if (job == T_JUSTIFY) { if (strns == 0) strns = 1; PUT2("}def\n" "/strop/strw load def/w 0 def str" "/w %.1f w sub %d div def" "/strop/jshow load def str ", strlw, strns); strns = 0; } bskip(cfmt.font_tb[curft].size * cfmt.lineskipfac); PUT0("0 0 M "); if (job == T_JUSTIFY) { PUT0("/str{"); outft = -1; } strtw = 0; } if (strtw != 0) { str_ft_out(" ", 0); strtw += cwid(' ') * cfmt.font_tb[curft].swfac; strns++; } str_ft_out(tex_buf, 0); strtw += lw; *p = sep; while (*p == ' ') p++; if (*p == '\0') break; s = p; } }
/* -- output the tune heading -- */ void write_heading(struct abctune *t) { struct SYMBOL *s, *rhythm, *area, *author; float lwidth, down1, down2; lwidth = ((cfmt.landscape ? cfmt.pageheight : cfmt.pagewidth) - cfmt.leftmargin - cfmt.rightmargin) / cfmt.scale; if (cfmt.titleformat != 0) { write_headform(lwidth); bskip(cfmt.musicspace); return; } /* titles */ for (s = info['T' - 'A']; s != 0; s = s->next) write_title(s); /* rhythm, composer, origin */ down1 = cfmt.composerspace + cfmt.font_tb[COMPOSERFONT].size; rhythm = (first_voice->key.bagpipe && !cfmt.infoline) ? info['R' - 'A'] : 0; if (rhythm) { str_font(COMPOSERFONT); PUT1("0 %.1f M ", -(cfmt.composerspace + cfmt.font_tb[COMPOSERFONT].size)); put_inf(rhythm); down1 -= cfmt.font_tb[COMPOSERFONT].size; } area = author = 0; if (t->abc_vers < 2) area = info['A' - 'A']; else author = info['A' - 'A']; if ((s = info['C' - 'A']) != 0 || info['O' - 'A'] || author != 0) { float xcomp; int align; str_font(COMPOSERFONT); bskip(cfmt.composerspace); if (cfmt.aligncomposer < 0) { xcomp = 0; align = A_LEFT; } else if (cfmt.aligncomposer == 0) { xcomp = lwidth * 0.5; align = A_CENTER; } else { xcomp = lwidth; align = A_RIGHT; } down2 = down1; if (author != 0) { for (;;) { bskip(cfmt.font_tb[COMPOSERFONT].size); down2 += cfmt.font_tb[COMPOSERFONT].size; PUT0("0 0 M "); put_inf(author); if ((author = author->next) == 0) break; } } if ((s = info['C' - 'A']) != 0 || info['O' - 'A']) { if (cfmt.aligncomposer >= 0 && down1 != down2) bskip(down1 - down2); for (;;) { bskip(cfmt.font_tb[COMPOSERFONT].size); PUT1("%.1f 0 M ", xcomp); put_inf2r(s, (s == 0 || s->next == 0) ? info['O' - 'A'] : 0, align); if (s == 0) break; if ((s = s->next) == 0) break; down1 += cfmt.font_tb[COMPOSERFONT].size; } if (down2 > down1) bskip(down2 - down1); } rhythm = rhythm ? 0 : info['R' - 'A']; if ((rhythm || area) && cfmt.infoline) { /* if only one of rhythm or area then do not use ()'s * otherwise output 'rhythm (area)' */ str_font(INFOFONT); bskip(cfmt.font_tb[INFOFONT].size + cfmt.infospace); PUT1("%.1f 0 M ", lwidth); put_inf2r(rhythm, area, A_RIGHT); down1 += cfmt.font_tb[INFOFONT].size + cfmt.infospace; } down2 = 0; } else down2 = cfmt.composerspace + cfmt.font_tb[COMPOSERFONT].size; /* parts */ if (info['P' - 'A']) { down1 = cfmt.partsspace + cfmt.font_tb[PARTSFONT].size - down1; if (down1 > 0) down2 += down1; if (down2 > 0.01) bskip(down2); str_font(PARTSFONT); PUT0("0 0 M "); put_inf(info['P' - 'A']); down2 = 0; } bskip(down2 + cfmt.musicspace); }