void line_break(struct part *p) { struct tag *t; /*printf("-break-\n");*/ if (p->cx + par_format.rightmargin > p->x) p->x = p->cx + par_format.rightmargin; if (nobreak) { /*if (p->y < p->cy) p->y = p->cy;*/ nobreak = 0; p->cx = -1; p->xa = 0; return; } if (!p->data) goto e; /*move_links(p, p->cx, p->cy, 0, p->cy + 1);*/ xpand_lines(p, p->cy + 1); if (p->cx > par_format.leftmargin && LEN(p->cy) > p->cx - 1 && (POS(p->cx-1, p->cy) & 0xff) == ' ') del_chars(p, p->cx-1, p->cy), p->cx--; /*if (LEN(p->cy) > p->x) p->x = LEN(p->cy);*/ if (p->cx > 0) align_line(p, p->cy); if (p->data) for (t = last_tag_for_newline; t && (void *)t != &p->data->tags; t = t->prev) { t->x = X(0); t->y = Y(p->cy + 1); } e: p->cy++; p->cx = -1; p->xa = 0; /*if (p->y < p->cy) p->y = p->cy;*/ memset(p->spaces, 0, p->spl); }
static void init_align_canvas(int x, int y, unsigned int shift) /* Shift Key Status from XEvent */ { int ux; cur_c = &objects; toggle_all_compoundmarkers(); draw_compoundelements(cur_c, ERASE); old_c = copy_compound(&objects); xcmin=ycmin=0; /* get the current page size */ xcmax = paper_sizes[appres.papersize].width; ycmax = paper_sizes[appres.papersize].height; if (!appres.INCHES) { xcmax = (int)(xcmax*2.54*PIX_PER_CM/PIX_PER_INCH); ycmax = (int)(ycmax*2.54*PIX_PER_CM/PIX_PER_INCH); } /* swap height and width if landscape */ if (appres.landscape) { ux = xcmax; xcmax = ycmax; ycmax = ux; } align_ellipse(); align_arc(); align_line(); align_spline(); align_compound(); align_text(); /* * Display messages indicating that distribution or alignment can't be * performed with respect to the canvas. */ if ((cur_halign == ALIGN_DISTRIB_C) || (cur_halign == ALIGN_DISTRIB_E)) put_msg("Can't DISTRIBUTE horizontally with respect to the canvas"); else if (cur_halign == ALIGN_ABUT) put_msg("Can't ABUT horizontally with respect to the canvas"); if ((cur_valign == ALIGN_DISTRIB_C) || (cur_valign == ALIGN_DISTRIB_E)) put_msg("Can't DISTRIBUTE vertically with respect to the canvas"); else if (cur_valign == ALIGN_ABUT) put_msg("Can't ABUT vertically with respect to the canvas"); draw_compoundelements(cur_c, PAINT); toggle_all_compoundmarkers(); clean_up(); set_latestobjects(old_c); set_action_object(F_EDIT, O_ALL_OBJECT); set_modifiedflag(); }
static void init_align(F_line *p, int type, int x, int y, int px, int py) { if (type != O_COMPOUND) return; cur_c = (F_compound *) p; toggle_compoundmarker(cur_c); draw_compoundelements(cur_c, ERASE); old_c = copy_compound(cur_c); compound_bound(cur_c, &xcmin, &ycmin, &xcmax, &ycmax); align_ellipse(); align_arc(); align_line(); align_spline(); align_compound(); align_text(); /* * Perform the distribution of the objects in the compound */ if ( (cur_halign == ALIGN_DISTRIB_C) || (cur_halign == ALIGN_DISTRIB_E) || (cur_halign == ALIGN_ABUT) ) distribute_horizontally(); if ( (cur_valign == ALIGN_DISTRIB_C) || (cur_valign == ALIGN_DISTRIB_E) || (cur_valign == ALIGN_ABUT) ) distribute_vertically(); /* * recompute the compound's bounding box */ compound_bound(cur_c, &cur_c->nwcorner.x, &cur_c->nwcorner.y, &cur_c->secorner.x, &cur_c->secorner.y); draw_compoundelements(cur_c, PAINT); toggle_compoundmarker(cur_c); clean_up(); old_c->next = cur_c; set_latestcompound(old_c); set_action_object(F_EDIT, O_COMPOUND); set_modifiedflag(); }
void put_chars(struct part *p, unsigned char *c, int l) { static struct text_attrib_beginning ta_cache = { -1, { 0, 0, 0, 0 }, { 0, 0, 0, 0 } }; static int bg_cache; static int fg_cache; int bg, fg; int i; struct link *link; struct point *pt; if (l < 0) overalloc(); /*printf("%d-", p->cx);for (i=0; i<l; i++) printf("%c", c[i]); printf("-\n");sleep(1);*/ while (par_format.align != AL_NO && p->cx == -1 && l && *c == ' ') c++, l--; if (!l) return; if (c[0] != ' ' || (c[1] && c[1] != ' ')) { last_tag_for_newline = (void *)&p->data->tags; } if (p->cx < par_format.leftmargin) p->cx = par_format.leftmargin; if (last_link || last_image || last_form || format.link || format.image || format.form) goto process_link; no_l: /*printf("%d %d\n",p->cx, p->cy);*/ if (memcmp(&ta_cache, &format, sizeof(struct text_attrib_beginning))) goto format_change; bg = bg_cache, fg = fg_cache; end_format_change: if (p->cx == par_format.leftmargin && *c == ' ' && par_format.align != AL_NO) c++, l--; if (p->y < p->cy + 1) p->y = p->cy + 1; if (nowrap && p->cx + l > rm(par_format)) return; set_hline(p, p->cx, p->cy, l, c, (((fg&0x08)<<3)|(bg<<3)|(fg&0x07))<<8, 1); p->cx += l; nobreak = 0; if (par_format.align != AL_NO) while (p->cx > rm(par_format) && p->cx > par_format.leftmargin) { int x; /*if (p->cx > p->x) { p->x = p->cx + par_format.rightmargin; if (c[l - 1] == ' ') p->x--; }*/ if (!(x = split_line(p))) break; /*if (LEN(p->cy-1) > p->x) p->x = LEN(p->cy-1);*/ align_line(p, p->cy - 1); nobreak = x - 1; } if ((p->xa += l) - (c[l-1] == ' ' && par_format.align != AL_NO) + par_format.leftmargin + par_format.rightmargin > p->xmax) p->xmax = p->xa - (c[l-1] == ' ' && par_format.align != AL_NO) + par_format.leftmargin + par_format.rightmargin; return; process_link: if ((last_link /*|| last_target*/ || last_image || last_form) && !xstrcmp(format.link, last_link) && !xstrcmp(format.target, last_target) && !xstrcmp(format.image, last_image) && format.form == last_form) { if (!p->data) goto x; link = &p->data->links[p->data->nlinks - 1]; if (!p->data->nlinks) { internal("no link"); goto no_l; } goto set_link; x:; } else { if (last_link) mem_free(last_link); /* !!! FIXME: optimize */ if (last_target) mem_free(last_target); if (last_image) mem_free(last_image); last_link = last_target = last_image = NULL; last_form = NULL; if (!(format.link || format.image || format.form)) goto no_l; if (d_opt->num_links) { unsigned char s[64]; unsigned char *fl = format.link, *ft = format.target, *fi = format.image; struct form_control *ff = format.form; format.link = format.target = format.image = NULL; format.form = NULL; s[0] = '['; snzprint(s + 1, 62, p->link_num); strcat(s, "]"); put_chars(p, s, strlen(s)); if (ff && ff->type == FC_TEXTAREA) line_break(p); if (p->cx == -1) p->cx = par_format.leftmargin; format.link = fl, format.target = ft, format.image = fi; format.form = ff; } p->link_num++; last_link = stracpy(format.link); last_target = stracpy(format.target); last_image = stracpy(format.image); last_form = format.form; if (!p->data) goto no_l; if (!(link = new_link(p->data))) goto no_l; link->num = p->link_num - 1; link->pos = DUMMY; if (!last_form) { link->type = L_LINK; link->where = stracpy(last_link); link->target = stracpy(last_target); } else { link->type = last_form->type == FC_TEXT || last_form->type == FC_PASSWORD || last_form->type == FC_FILE ? L_FIELD : last_form->type == FC_TEXTAREA ? L_AREA : last_form->type == FC_CHECKBOX || last_form->type == FC_RADIO ? L_CHECKBOX : last_form->type == FC_SELECT ? L_SELECT : L_BUTTON; link->form = last_form; link->target = stracpy(last_form->target); } link->where_img = stracpy(last_image); if (link->type != L_FIELD && link->type != L_AREA) { bg = find_nearest_color(&format.clink, 8); fg = find_nearest_color(&format.bg, 8); fg = fg_color(fg, bg); } else { fg = find_nearest_color(&format.fg, 8); bg = find_nearest_color(&format.bg, 8); fg = fg_color(fg, bg); } link->sel_color = ((fg & 8) << 3) | (fg & 7) | (bg << 3); link->n = 0; set_link: if ((unsigned)link->n + (unsigned)l > MAXINT / sizeof(struct point)) overalloc(); pt = mem_realloc(link->pos, (link->n + l) * sizeof(struct point)); link->pos = pt; for (i = 0; i < l; i++) pt[link->n + i].x = X(p->cx) + i, pt[link->n + i].y = Y(p->cy); link->n += l; } goto no_l; format_change: bg = find_nearest_color(&format.bg, 8); fg = find_nearest_color(&format.fg, 16); fg = fg_color(fg, bg); if (format.attr & AT_ITALIC) fg = fg ^ 0x01; if (format.attr & AT_UNDERLINE) fg = (fg ^ 0x04) | 0x08; if (format.attr & AT_BOLD) fg = fg | 0x08; fg = fg_color(fg, bg); if (format.attr & AT_GRAPHICS) bg = bg | 0x10; memcpy(&ta_cache, &format, sizeof(struct text_attrib_beginning)); fg_cache = fg; bg_cache = bg; goto end_format_change; }
/* Fill the sentence with new words: in "page" mode, fills the page with text; in "scroll" mode, just makes one long horizontal sentence. The sentence might have *no* words in it, if no text is currently available. */ static void populate_sentence (state *s, sentence *se) { int i = 0; int left, right, top, x, y; int space = 0; int line_start = 0; Bool done = False; int array_size = 100; se->move_chars_p = (s->mode == SCROLL ? False : (random() % 3) ? False : True); se->alignment = (random() % 3); recolor (s, se); if (se->words) { for (i = 0; i < se->nwords; i++) free_word (s, se->words[i]); free (se->words); } se->words = (word **) calloc (array_size, sizeof(*se->words)); se->nwords = 0; switch (s->mode) { case PAGE: left = random() % (s->xgwa.width / 3); right = s->xgwa.width - (random() % (s->xgwa.width / 3)); top = random() % (s->xgwa.height * 2 / 3); break; case SCROLL: left = 0; right = s->xgwa.width; top = random() % s->xgwa.height; break; default: abort(); break; } x = left; y = top; while (!done) { char *txt = get_word_text (s); word *w; if (!txt) { if (se->nwords == 0) return; /* If the stream is empty, bail. */ else break; /* If EOF after some words, end of sentence. */ } if (! se->font) /* Got a word: need a font now */ { pick_font (s, se); if (y < se->font->ascent) y += se->font->ascent; space = XTextWidth (se->font, " ", 1); } w = new_word (s, se, txt, !se->move_chars_p); /* If we have a few words, let punctuation terminate the sentence: stop gathering more words if the last word ends in a period, etc. */ if (se->nwords >= 4) { char c = w->text[strlen(w->text)-1]; if (c == '.' || c == '?' || c == '!') done = True; } /* If the sentence is kind of long already, terminate at commas, etc. */ if (se->nwords >= 12) { char c = w->text[strlen(w->text)-1]; if (c == ',' || c == ';' || c == ':' || c == '-' || c == ')' || c == ']' || c == '}') done = True; } if (se->nwords >= 25) /* ok that's just about enough out of you */ done = True; if (s->mode == PAGE && x + w->rbearing > right) /* wrap line */ { align_line (s, se, line_start, x, right); line_start = se->nwords; x = left; y += se->font->ascent; /* If we're close to the bottom of the screen, stop, and unread the current word. (But not if this is the first word, otherwise we might just get stuck on it.) */ if (se->nwords > 0 && y + se->font->ascent > s->xgwa.height) { unread_word (s, w); /* done = True; */ break; } } w->target_x = x + w->lbearing; w->target_y = y - w->ascent; x += w->rbearing + space; se->width = x; if (se->nwords >= (array_size - 1)) { array_size += 100; se->words = (word **) realloc (se->words, array_size * sizeof(*se->words)); if (!se->words) { fprintf (stderr, "%s: out of memory (%d words)\n", progname, array_size); exit (1); } } se->words[se->nwords++] = w; } se->width -= space; switch (s->mode) { case PAGE: align_line (s, se, line_start, x, right); if (se->move_chars_p) split_words (s, se); scatter_sentence (s, se); shuffle_words (s, se); break; case SCROLL: aim_sentence (s, se); break; default: abort(); break; } # ifdef DEBUG if (s->debug_p) { fprintf (stderr, "%s: sentence %d:", progname, se->id); for (i = 0; i < se->nwords; i++) fprintf (stderr, " %s", se->words[i]->text); fprintf (stderr, "\n"); } # endif }