static int ascii_mode_init(EditState *s, ModeSavedData *saved_data) { QEFont *font; QEStyleDef style; int num_width; int ret; ret = text_mode_init(s, saved_data); if (ret) return ret; /* get typical number width */ get_style(s, &style, s->default_style); font = select_font(s->screen, style.font_style, style.font_size); num_width = glyph_width(s->screen, font, '0'); release_font(s->screen, font); s->disp_width = (s->screen->width / num_width) - 10; /* align on 16 byte boundary */ s->disp_width &= ~15; if (s->disp_width < 16) s->disp_width = 16; s->insert = 0; s->hex_mode = 0; s->wrap = WRAP_TRUNCATE; return 0; }
/* * Returns text width. * * There are two problems with text width it's start and it's end. * * At the start the first letter may have bearing_x negative, making it * overflow out of the bouding box and even in case it's possitive the returned * size would be slightly bigger. This one is easy to fix. * * The end of the string is problematic too, some of the glyphs may have * advance smaller than sum of the bitmap width and bearing_x that way we would * return slightly less than is the actuall size of the text bouding box. The * other problem is that the advance is usually grater than the glyph space (as * the exact size of the glyph itself without advance before and space after is * not known), so we likely return some more pixels than is needed, but that's * the joy of life. */ unsigned int GP_TextWidth(const GP_TextStyle *style, const char *str) { unsigned int i, len; style = assert_style(style); if (str == NULL || str[0] == '\0') return 0; /* special case, one letter */ if (str[1] == '\0') { return glyph_width(style, str[0]); } /* first letter */ len = first_glyph_width(style, str[0]) + style->char_xspace; /* middle letters */ for (i = 1; str[i+1] != '\0'; i++) len += glyph_advance_x(style, str[i]) + style->char_xspace; /* last letter */ len += last_glyph_width(style, str[i]); return len; }
static int gtk_get_button_size (struct frame *f, Lisp_Object window, struct toolbar_button *tb, int vert, int pos) { int shadow_thickness = 2; int size; if (tb->blank) { if (!NILP (tb->down_glyph)) size = XINT (tb->down_glyph); else size = DEFAULT_TOOLBAR_BLANK_SIZE; } else { struct window *w = XWINDOW (window); Lisp_Object glyph = get_toolbar_button_glyph (w, tb); /* Unless, of course, the user has done something stupid like change the glyph out from under us. Use a blank placeholder in that case. */ if (NILP (glyph)) return XINT (f->toolbar_size[pos]); if (vert) size = glyph_height (glyph, window); else size = glyph_width (glyph, window); } if (!size) { /* If the glyph doesn't have a size we'll insert a blank placeholder instead. */ return XINT (f->toolbar_size[pos]); } size += shadow_thickness * 2; return (size); }
int draw_vector_char_lookahead(framebuffer_t fb, vector_font_t *font, uint32_t c, char *string, xy_t p, xy_t *off, double scale, col_t colour, double line_thick, const int mode, const int bidi) { letter_t *l; double fixoff, wc1, wc2; unicode_data_t ucd1, ucd2; int i=0, ir=0, found = 0; uint32_t cn; xy_t noff=*off; double scale_mod=1., offb=0., offt=0.; letter_t *ldom; int lowerscale_dom, bidi1, onscreen=1; rect_t bound_box; bound_box = make_rect_off( add_xy(p, *off), set_xy(24. * scale), xy(0.5, 0.5) ); if (check_box_box_intersection(fb.window_dl, bound_box)==0) onscreen = 0; if (onscreen) { ucd1 = get_unicode_data(c); //bidi1 = bidicat_direction(ucd1.bidicat); wc1 = glyph_width(font, off->x, c, scale, mode); draw_vector_char(fb, font, c, p, *off, scale, colour, line_thick, mode, bidi); if (ucd1.uccat == uccat_Ll) // if character is lowercase scale_mod = LOWERCASESCALE; } // Check for insert rect sequence if (c >= cp_ins_start && c < cp_ins_end) // if c is a custom spacing character and cn is a variation selector that indicates its index { ir = parse_insert_rect_charseq(p, off, scale, bidi, c, string); return ir; } do // loop through all following non-spacing (combining) marks { cn = utf8_to_unicode32(&string[i], &i); // lookup next character ucd2 = get_unicode_data(cn); if (ucd2.bidicat==bidicat_NSM) // non-spacing (combining) mark { ir = i+1; if (onscreen) { ldom = get_dominant_letter(font, cn, &lowerscale_dom); if (ucd1.uccat == uccat_Ll) // if character is lowercase wc2 = ((glyph_width(font, off->x, cn, 1., mode) - LETTERSPACING) * LOWERCASESCALE + LETTERSPACING) * scale; else wc2 = glyph_width(font, off->x, cn, scale, mode); noff.x = off->x + (wc1 - wc2) * 0.5 * (bidi == -2 ? -1. : 1.); noff.y = off->y; if (ldom) { if (ldom->bb > 3. && ldom->bt > 6.) noff.y -= offt * scale*scale_mod; if (ldom->bt < 3. && ldom->bb < 0.) noff.y -= offb * scale*scale_mod; } draw_vector_char(fb, font, cn, p, noff, scale*scale_mod, colour, line_thick, mode, bidi); if (ldom) { if (ldom->bb > 3. && ldom->bt > 6.) offt += ldom->bt - 6.; if (ldom->bt < 3. && ldom->bb < 0.) offb += ldom->bb; } } } i++; } while (ucd2.bidicat==bidicat_NSM); return ir; }
void cursor_processing(framebuffer_t fb, vector_font_t *font, char *string, uint32_t c, xy_t p, xy_t off, double scale, xy_t expected_pos, int is, int curpos, int recur, const int mode, int bidi, int bidi_change, double line_thick, double *closest_deltapos) { static int32_t sel0=0, sel1=0, newline=0; static xy_t p0, p1; rect_t box; int isa = is + string - cur_textedit->string; double wc1; if (is0_col(text_sel_col)) text_sel_col = make_colour(0.0033, 0.028, 0.1, 1.); if (recur==0 && is==0) // if it's the first run of this function for this string in this loop { sel0 = cur_textedit->sel0; sel1 = cur_textedit->sel1; minmax_i32(&sel0, &sel1); newline = 0; } if (recur > 0 && is==0) newline = 1; if (newline) { newline = 0; p0 = add_xy(p, off); } if (sel0 < sel1) // if there's a selection to display { if (sel0==isa) p0 = add_xy(p, off); if (sel1==isa || (c=='\n' && isa > sel0)) { p1 = add_xy(p, off); box.p0 = add_xy(p0, xy(-LETTERSPACING*0.5*scale * (bidi == -2 ? -1. : 1.), 2.*scale)); box.p1 = add_xy(p1, xy(-LETTERSPACING*0.5*scale * (bidi == -2 ? -1. : 1.), -8.*scale)); // draw_rect_full(fb, box, line_thick, text_sel_col, 1.); if (c=='\n') newline = 1; if (sel1==isa) sel0 = sel1 = 0; } } if (isa >= sel0 && isa <= sel1 && sel0 < sel1 && bidi_change==0) // display selection one character at a time { wc1 = glyph_width(font, off.x, c, scale, mode); box.p0 = add_xy(add_xy(p, off), xy(-LETTERSPACING*0.5*scale * (bidi == -2 ? -1. : 1.), 2.*scale)); box.p1 = add_xy(box.p0, xy(wc1 * (bidi == -2 ? -1. : 1.), -10.*scale)); draw_rect_full(fb, box, line_thick, text_sel_col, cur_blend, 1.); } if (cur_textedit->click_on==0 && is==curpos) // if the cursor is on the current character { if (cur_textedit->read_only==0) draw_textedit_cursor(fb, add_xy(p, off), scale, bidi, bidi_change, line_thick); cur_textedit->cur_screen_pos = div_xy(off, set_xy(scale)); } if (cur_textedit->click_on) check_closest_cursor(off, scale, expected_pos, &closest_deltapos[0], isa, &cur_textedit->curpos); // find the position in the line above and below expected_pos = add_xy( mul_xy(cur_textedit->cur_screen_pos_prev, set_xy(scale)) , xy(0., LINEVSPACING * -scale) ); expected_pos = add_xy( mul_xy(xy(0.5*LETTERSPACING * (bidi == -2 ? -1. : 1.), 3.), set_xy(scale)) , expected_pos ); //expected_pos.y = MAXN(0., expected_pos.y); check_closest_cursor(off, scale, expected_pos, &closest_deltapos[1], isa, &cur_textedit->curpos_up); expected_pos = add_xy( mul_xy(cur_textedit->cur_screen_pos_prev, set_xy(scale)) , xy(0., LINEVSPACING * scale) ); expected_pos = add_xy( mul_xy(xy(0.5*LETTERSPACING * (bidi == -2 ? -1. : 1.), 3.), set_xy(scale)) , expected_pos ); check_closest_cursor(off, scale, expected_pos, &closest_deltapos[2], isa, &cur_textedit->curpos_down); }
int draw_vector_char(framebuffer_t fb, vector_font_t *font, uint32_t c, xy_t p, xy_t off, double scale, col_t colour, double line_thick, const int mode, const int bidi) { letter_t *l; double fixoff, wc1, wc2; unicode_data_t ucd; int found = 0; // Algorithmic substitution if (bidi == -2) c = substitute_rtl_punctuation(c); process_one_glyph(font, get_letter_index(font, c)); l = get_letter(font, c); if (l) if (l->obj) { found = 1; fixoff = 0.; if ((mode&12)==MONOSPACE || ((mode&12)==MONODIGITS && c>='0' && c<='9')) fixoff = 0.5 * (4. - l->width); if (bidi == -2) fixoff -= l->br; else fixoff -= l->bl; draw_vobj(fb, l->obj, xy(p.x + off.x + fixoff*scale, p.y + off.y), scale, 0., line_thick, colour); } // Alias if (found==0 && l) if (l->alias) found |= draw_vector_char(fb, font, l->alias, p, off, scale, colour, line_thick, mode, bidi); // Combo if (found==0) { ucd = get_unicode_data(c); if (/*ucd.decomp_type == decomp_canonical &&*/ ucd.combo1) // if we have a valid combo for this character { wc1 = glyph_width(font, off.x, ucd.combo1, scale, mode); found |= draw_vector_char(fb, font, ucd.combo1, p, off, scale, colour, line_thick, mode, bidi); if (ucd.uccat == uccat_Ll) // if character is lowercase { wc2 = ((glyph_width(font, off.x, ucd.combo2, 1., mode) - LETTERSPACING) * LOWERCASESCALE + LETTERSPACING) * scale; scale *= LOWERCASESCALE; } else wc2 = glyph_width(font, off.x, ucd.combo2, scale, mode); if (bidi == -2) off.x -= (wc1 - wc2) * 0.5; else off.x += (wc1 - wc2) * 0.5; found |= draw_vector_char(fb, font, ucd.combo2, p, off, scale, colour, line_thick, mode, bidi); } } // Upper case if (found==0) if (ucd.upper_map) found |= draw_vector_char(fb, font, ucd.upper_map, p, off, scale*LOWERCASESCALE, colour, line_thick, mode, bidi); // Decomposed CJK if (found==0) found |= draw_cjkdec_glyph(fb, font, c, add_xy(p, off), scale, colour, line_thick, mode); return found; }