void Text::expose(unsigned line, unsigned column) { if (! canvas_) return; String string; if (line < text_->Height()) { string = text_->getNth(line); } FontBoundingBox fbb; font_->font_bbox(fbb); Coord x = columnCoord(string, column) - allocation_->left() + curLowerX_; bool invisibleX = (x < curLowerX_) || ((x + width(' ')) > curUpperX_); Coord y = line * (fbb.ascent() + fbb.descent()); bool invisibleY = (y < curLowerY_) || ((y + fbb.ascent() + fbb.descent()) > curUpperY_); if (invisibleX) { scroll_to(Dimension_X, x - (curUpperX_ - curLowerX_) / 2); } if (invisibleY) { scroll_to(Dimension_Y, height() - y - (curUpperY_ - curLowerY_) / 2); } }
void TextLine::request(Requisition& requisition) const { FontBoundingBox fbb; font_->font_bbox(fbb); Text::request(requisition); Requirement ry(fbb.ascent() + fbb.descent(), 0, 0, 0); requisition.require(Dimension_Y, ry); }
void Text::scroll_backward(DimensionName dimension) { FontBoundingBox fbb; font_->font_bbox(fbb); if (dimension == Dimension_X) { scroll_to(dimension, cur_lower(Dimension_X) - width(' ')); } else { scroll_to(dimension, cur_lower(Dimension_Y) - (fbb.ascent() + fbb.descent())); } }
void Text::drawRegion(const TextRegion& region, unsigned i, Coord x, Coord y, const String& line) const { unsigned line1 = region.line1(); unsigned line2 = region.line2(); unsigned column1 = region.column1(); unsigned column2 = region.column2(); FontBoundingBox fbb; font_->font_bbox(fbb); if ((line1 == i) && (line1 == line2) && (column1 < column2)) { canvas_->fill_rect(columnCoord(line, column1), y - fbb.descent(), columnCoord(line, column2), y + fbb.ascent(), region.color()); } if ((line1 == i) && (line1 < line2)) { canvas_->fill_rect(columnCoord(line, column1), y - fbb.descent(), allocation_->right(), y + fbb.ascent(), region.color()); } if ((line1 < i) && (i < line2)) { canvas_->fill_rect(x, y - fbb.descent(), allocation_->right(), y + fbb.ascent(), region.color()); } if ((line2 == i) && (line1 < line2)) { canvas_->fill_rect(0, y - fbb.descent(), columnCoord(line, column2), y + fbb.ascent(), region.color()); } }
void Text::request(Requisition& requisition) const { FontBoundingBox fbb; font_->font_bbox(fbb); Requirement rx(width(' ') * initialColumns_, fil, width(' ') * (initialColumns_ - 1), 0); Requirement ry((fbb.ascent() + fbb.descent()) * initialLines_, fil, (fbb.ascent() + fbb.descent()) * (initialLines_ - 1), 0); requisition.require(Dimension_X, rx); requisition.require(Dimension_Y, ry); }
bool Text::damaged(unsigned line) const { FontBoundingBox fbb; font_->font_bbox(fbb); Coord base = allocation_->top() + curLowerY_; Coord lineHeight = fbb.ascent() + fbb.descent(); Coord top = base - lineHeight * line; Coord bottom = base - lineHeight * (line + 1); return canvas_->damaged(allocation_->left(), Math::max(bottom, allocation_->bottom()), allocation_->right(), Math::min(top, allocation_->top())); }
void Text::drawLocation(const TextLocation& location, unsigned i, Coord /* x */, Coord y, const String& line) const { FontBoundingBox fbb; font_->font_bbox(fbb); if (location.line_ == i) { Coord lb = columnCoord(line, location.column_); canvas_->fill_rect(lb, y - fbb.descent(), lb + location.width_, y + fbb.ascent(), location.color_); } }
void FieldStringEditor::print(Printer* p, const Allocation& a) const { const Font* f = output_->GetFont(); const Color* fg = output_->GetFgColor(); FontBoundingBox b; f->font_bbox(b); Coord x = a.left(), y = a.bottom() + b.font_descent(); FieldStringEditor* e = (FieldStringEditor*)this; for (const char* s = e->Text(); *s != '\0'; s++) { Coord w = f->width(*s); p->character(f, *s, w, fg, x, y); x += w; } }
Strut::Strut( const Font* font, Coord natural, Coord stretch, Coord shrink ) : Glyph() { font_ = font; Resource::ref(font_); if (font_ != nil) { FontBoundingBox b; font_->font_bbox(b); height_ = b.ascent() + b.descent(); alignment_ = (height_ == 0) ? 0 : b.descent() / height_; } natural_ = natural; stretch_ = stretch; shrink_ = shrink; }
void Text::damage(const TextRegion& region) { if (! canvas_) { return; } FontBoundingBox fbb; font_->font_bbox(fbb); Coord base = allocation_->top() + curLowerY_; Coord lineHeight = fbb.ascent() + fbb.descent(); Coord top = Math::min(base - lineHeight * region.line1(), allocation_->top()); Coord bottom = Math::max(base - lineHeight * (region.line2() + 1), allocation_->bottom()); if ((allocation_->left() <= allocation_->right()) && (bottom <= top)) { canvas_->damage(allocation_->left(), bottom, allocation_->right(), top); } }
void Text::draw(Canvas*, const Allocation&) const { canvas_->push_clipping(); canvas_->clip_rect(allocation_->left(), allocation_->bottom(), allocation_->right(), allocation_->top()); FontBoundingBox fbb; font_->font_bbox(fbb); Coord r = curLowerY_ / (fbb.ascent() + fbb.descent()); unsigned i = unsigned(r); Coord y = allocation_->top() + (r - i) * (fbb.ascent() + fbb.descent()); unsigned max = Math::max(Math::max(selection_.line2(), insertion_.line_), (unsigned) text_->Height() ? (unsigned) text_->Height() - 1 : 0); for (; i <= max; ++i) { y -= fbb.ascent(); if (damaged(i)) { Coord x = allocation_->left() - curLowerX_; if (i < text_->Height()) { const String line = text_->getNth(i); drawRegion(selection_, i, x, y, line); if (! readOnly_) { drawLocation(insertion_, i, x, y, line); } for (GlyphIndex j = 0; j < annotation_.count(); ++j) { drawRegion(*annotation_.item(j), i, x, y, line); } drawLine(i, x, y, line); } else { String line; drawRegion(selection_, i, x, y, line); if (! readOnly_) { drawLocation(insertion_, i, x, y, line); } for (GlyphIndex j = 0; j < annotation_.count(); ++j) { drawRegion(*annotation_.item(j), i, x, y, line); } drawLine(i, x, y, line); } } y -= fbb.descent(); if (y < (allocation_->bottom() - fbb.ascent())) break; } canvas_->pop_clipping(); }
void Text::damage(const TextLocation& location) { if (! canvas_) { return; } //mlh to get horizontal scrolling. Not well understood yet. expose(0, location.column_); FontBoundingBox fbb; font_->font_bbox(fbb); Coord base = allocation_->top() + curLowerY_; Coord lineHeight = fbb.ascent() + fbb.descent(); Coord top = Math::min(base - lineHeight * location.line_, allocation_->top()); Coord bottom = Math::max(base - lineHeight * (location.line_ + 1), allocation_->bottom()); if ((allocation_->left() <= allocation_->right()) && (bottom <= top)) { canvas_->damage(allocation_->left(), bottom, allocation_->right(), top); } }
bool Text::snap( const Event& event, unsigned& line, unsigned& column) const { unsigned originalLine = line; unsigned originalColumn = column; Coord x = event.pointer_x() - allocation_->left() + curLowerX_; Coord y = allocation_->top() + curLowerY_ - event.pointer_y(); FontBoundingBox fbb; font_->font_bbox(fbb); line = Math::max(int(y / (fbb.ascent() + fbb.descent())), 0); if (line < text_->Height()) { const String& string = text_->getNth(line); unsigned i; for (i = 0; i < string.length(); ++i) { x -= width(string[i]) / 2.0; if (x < 0) break; x -= width(string[i]) / 2.0; } column = i; if (i > 0 && string[i-1] == '\n') { --column; } // if (i >= string.length()) // column += (unsigned) ((x + width(' ') / 2) / width(' ')); } else if (text_->Height() > 0) { line = text_->Height()-1; column = text_->getNth(line).length(); //column = (unsigned) ((x + width(' ') / 2) / width(' ')); }else{ line = 0; column = 0; } column = Math::max(column, unsigned(0)); return (line != originalLine) || (column != originalColumn); }
Space::Space(int count, float each, const Font* f, const Color* c) : Glyph() { count_ = count; each_ = each; font_ = f; Resource::ref(font_); color_ = c; Resource::ref(color_); if (font_ != nil) { FontBoundingBox b; font_->font_bbox(b); Coord ascent = b.ascent(); Coord descent = b.descent(); width_ = font_->width(' ') * each_ * count_; height_ = ascent + descent; alignment_ = (height_ == 0) ? 0 : descent / height_; } else { width_ = 0; height_ = 0; alignment_ = 0; } }
Character::Character(long ch, const Font* f, const Color* c) : Glyph() { c_ = ch; font_ = f; Resource::ref(font_); color_ = c; Resource::ref(color_); if (font_ != nil) { FontBoundingBox b; font_->char_bbox(c_, b); left_bearing_ = b.left_bearing(); right_bearing_ = b.right_bearing(); width_ = b.width(); ascent_ = b.font_ascent(); descent_ = b.font_descent(); height_ = ascent_ + descent_; alignment_ = (height_ == 0) ? 0 : descent_ / height_; } else { left_bearing_ = 0; right_bearing_ = 0; ascent_ = 0; descent_ = 0; width_ = 0; height_ = 0; alignment_ = 0; } }
void Text31::init () { LayoutKit* layout = LayoutKit::instance(); PolyGlyph* col = layout->vbox(); PolyGlyph* line = layout->hbox(); FontBoundingBox bbox; _font->font_bbox(bbox); Coord lineheight = bbox.ascent() + bbox.descent(); char ch; for (int i = 0; (*_text)[i] != '\0'; i++) { ch = (*_text)[i]; if (ch == '\n') { line->append(layout->strut(_font)); col->append(layout->fixed_dimension(line, Dimension_Y,lineheight)); line = layout->hbox(); } else if (ch == ' ') { line->append(new Character(' ', _font, _stroke)); } else if (ch != ')' && ch != '(') { if (ch == '\\') { ch = (*_text)[++i]; if (isdigit(ch)) { ch -= '0'; ch *= 8; char digit; digit = (*_text)[i++]; ch = (ch * 8) + digit - '0'; digit = (*_text)[i++]; ch = (ch * 8) + digit - '0'; } } line->append(new Character(ch, _font, _stroke)); } } Transformer fixtext; fixtext.translate(0, bbox.descent()); _t->premultiply(fixtext); _body->append(col); }
Coord Text::height() const { FontBoundingBox fbb; font_->font_bbox(fbb); return text_->Height() * (fbb.ascent() + fbb.descent()); }
Glyph* read_idraw_graphic ( FILE* file, const Brush* pb, const Color* pfg, const Color* pbg, const Font* pf, Stipple* ps ) { skip(file); Transformer tx; Glyph* glyph = nil; const LayoutKit& layout = *LayoutKit::instance(); if (fscanf(file, "%s", buffer) != EOF) { figure& fig = figures[which(figures, buffer)]; if (strcmp(fig.name, "Idraw") == 0) { fscanf(file, "%d", &drawing_version); figures = versions[drawing_version]; } const Brush* b = (fig.brush) ? read_brush(file) : nil; const Color* fg = (fig.foreground) ? read_color(file) : nil; const Color* bg = (fig.background) ? read_color(file) : nil; const Font* f = (fig.font) ? read_font(file) : nil; Stipple* s = (fig.pattern) ? read_stipple(file) : nil; if (fig.transformer) { read_transformer(file, tx); } if (pb) b = pb; if (pfg) fg = pfg; if (pbg) bg = pbg; if (pf) f = pf; if (ps) s = ps; if (fig.name == nil) { ; // error } else if ( strcmp(fig.name, "Idraw") == 0 || strcmp(fig.name, "Pict") == 0 ) { Glyph* pic = layout.overlay(); Glyph* g; do { g = read_idraw_graphic(file, b, fg, bg, f, s); if (g != nil) { pic->append(g); } } while (g != nil); glyph = pic; } else if (strcmp(fig.name, "eop") == 0) { glyph = nil; } else if (strcmp(fig.name, "Text") == 0) { skip(file); fscanf(file, "%s", buffer); getc(file); PolyGlyph* col = layout.vbox_first_aligned(); PolyGlyph* line = layout.hbox_first_aligned(); FontBoundingBox bbox; f->font_bbox(bbox); Coord lineheight = bbox.font_ascent() + bbox.font_descent(); if (_idraw_font_metrics) { lineheight /= fixtextscale; } int c; while ((c = getc(file)) != ']') { if (c == '\n') { line->append(layout.strut(f)); col->append( layout.v_fixed_span(line, lineheight) ); line = layout.hbox(); } else if (c == ' ') { if (_idraw_font_metrics) { line->append( layout.shape_of(new Character(' ', f, fg)) ); } else { line->append(new Character(' ', f, fg)); } } else if (c != ')' && c != '(') { if (c == '\\') { c = getc(file); if (isdigit(c)) { c -= '0'; c = (c * 8) + getc(file) - '0'; c = (c * 8) + getc(file) - '0'; } } line->append(new Character(c, f, fg)); } } Transformer fixtext; if (_idraw_font_metrics) { fixtext.scale(fixtextscale, fixtextscale); } fixtext.translate(0, bbox.font_descent() - lineheight); glyph = new TransformSetter(col, fixtext); } else { skip(file); int c = fig.coords; if (c == -1) { fscanf(file, "%d", &c); } Coord xx, yy; Coord* x = new Coord[c]; Coord* y = new Coord[c]; for (int i = 0; i < c; ++i) { fscanf(file, "%g %g", &xx, &yy); x[i] = xx; y[i] = yy; } const Brush* brush = (b != no_brush) ? b : nil; const Color* stroke = fg; const Color* fill = ( (s != no_stipple) ? dither_color(fg, bg, s->_dither) : nil ); if (strcmp(fig.name, "Line") == 0) { glyph = new Line(brush, stroke, fill, x[0], y[0], x[1], y[1]); } else if (strcmp(fig.name, "BSpl") == 0) { glyph = new Open_BSpline(brush, stroke, fill, x, y, c); } else if (strcmp(fig.name, "CBSpl") == 0) { glyph = new Closed_BSpline(brush, stroke, fill, x, y, c); } else if (strcmp(fig.name, "MLine") == 0) { glyph = new Polyline(brush, stroke, fill, x, y, c); } else if (strcmp(fig.name, "Poly") == 0) { glyph = new Polygon(brush, stroke, fill, x, y, c); } else if (strcmp(fig.name, "Rect") == 0) { glyph = new Rectangle(brush, stroke, fill,x[0],y[0],x[1],y[1]); } else if (strcmp(fig.name, "Circ") == 0) { fscanf(file, "%f", &xx); glyph = new Circle(brush, stroke, fill, x[0], y[0], xx); } else if (strcmp(fig.name, "Elli") == 0) { fscanf(file, "%f %f", &xx, &yy); glyph = new Ellipse(brush, stroke, fill, x[0], y[0], xx, yy); } else { glyph = nil; } delete x; delete y; } for (int extra = fig.skip; extra > 0; --extra) { skip(file); } } if (glyph != nil && !tx.identity()) { glyph = new TransformSetter(glyph, tx); } return glyph; }
int Font::Height() const { FontBoundingBox b; font_bbox(b); return impl_->default_rep()->display_->to_pixels(b.ascent() + b.descent()); }
int Font::Baseline() const { FontBoundingBox b; font_bbox(b); return impl_->default_rep()->display_->to_pixels(b.descent()) - 1; }
void FileChooserImpl::build() { WidgetKit& kit = *kit_; const LayoutKit& layout = *LayoutKit::instance(); Style* s = style_; kit.push_style(); kit.style(s); String caption(""); s->find_attribute("caption", caption); String subcaption("Enter filename:"); s->find_attribute("subcaption", subcaption); String open("Open"); s->find_attribute("open", open); String close("Cancel"); s->find_attribute("cancel", close); long rows = 10; s->find_attribute("rows", rows); const Font* f = kit.font(); FontBoundingBox bbox; f->font_bbox(bbox); Coord height = rows * (bbox.ascent() + bbox.descent()) + 1.0; Coord width; if (!s->find_attribute("width", width)) { width = 16 * f->width('m') + 3.0; } Action* accept = new ActionCallback(FileChooserImpl)( this, &FileChooserImpl::accept_browser ); Action* cancel = new ActionCallback(FileChooserImpl)( this, &FileChooserImpl::cancel_browser ); if (editor_ == nil) { editor_ = DialogKit::instance()->field_editor( *dir_->path(), s, new FieldEditorCallback(FileChooserImpl)( this, &FileChooserImpl::accept_editor, &FileChooserImpl::cancel_editor ) ); } // added by ro2m: check for style for default selection String defsel(""); if(s->find_attribute("defaultSelection", defsel)) { editor_->field(defsel); } fbrowser_ = new FileBrowser(kit_, accept, cancel); fchooser_->remove_all_input_handlers(); fchooser_->append_input_handler(editor_); fchooser_->append_input_handler(fbrowser_); Glyph* g = layout.vbox(); if (caption.length() > 0) { g->append(layout.rmargin(kit.fancy_label(caption), 5.0, fil, 0.0)); } if (subcaption.length() > 0) { g->append(layout.rmargin(kit.fancy_label(subcaption), 5.0, fil, 0.0)); } g->append(layout.vglue(5.0, 0.0, 2.0)); g->append(editor_); g->append(layout.vglue(15.0, 0.0, 12.0)); g->append( layout.hbox( layout.vcenter( kit.inset_frame( layout.margin( layout.natural_span(fbrowser_, width, height), 1.0 ) ), 1.0 ), layout.hspace(4.0), kit.vscroll_bar(fbrowser_->adjustable()) ) ); g->append(layout.vspace(15.0)); if (s->value_is_on("filter")) { FieldEditorAction* action = new FieldEditorCallback(FileChooserImpl)( this, &FileChooserImpl::accept_filter, nil ); filter_ = add_filter( s, "filterPattern", "", "filterCaption", "Filter:", g, action ); if (s->value_is_on("directoryFilter")) { directory_filter_ = add_filter( s, "directoryFilterPattern", "", "directoryFilterCaption", "Directory Filter:", g, action ); } else { directory_filter_ = nil; } } else { filter_ = nil; directory_filter_ = nil; } g->append( layout.hbox( layout.hglue(10.0), layout.vcenter(kit.default_button(open, accept)), layout.hglue(10.0, 0.0, 5.0), layout.vcenter(kit.push_button(close, cancel)), layout.hglue(10.0) ) ); fchooser_->body( layout.back( layout.vcenter(kit.outset_frame(layout.margin(g, 5.0)), 1.0), new Target(nil, TargetPrimitiveHit) ) ); fchooser_->focus(editor_); kit.pop_style(); load(); }
void SymChooserImpl::build() { WidgetKit& kit = *kit_; const LayoutKit& layout = *LayoutKit::instance(); Style* s = style_; kit.push_style(); kit.style(s); String caption(""); s->find_attribute("caption", caption); String subcaption("Enter Symbol name:"); s->find_attribute("subcaption", subcaption); String open("Accept"); s->find_attribute("open", open); String close("Cancel"); s->find_attribute("cancel", close); long rows = 10; s->find_attribute("rows", rows); const Font* f = kit.font(); FontBoundingBox bbox; f->font_bbox(bbox); Coord height = rows * (bbox.ascent() + bbox.descent()) + 1.0; Coord width; if (!s->find_attribute("width", width)) { width = 16 * f->width('m') + 3.0; } int i; Action* accept = new ActionCallback(SymChooserImpl)( this, &SymChooserImpl::accept_browser ); Action* cancel = new ActionCallback(SymChooserImpl)( this, &SymChooserImpl::cancel_browser ); editor_ = DialogKit::instance()->field_editor( "", s, new FieldEditorCallback(SymChooserImpl)( this, &SymChooserImpl::editor_accept, nil ) ); browser_index_ = 0; for (i=0; i < nbrowser_; ++i) { fbrowser_[i] = new FileBrowser(kit_, new SymBrowserAccept(this, i), nil); } fchooser_->remove_all_input_handlers(); fchooser_->append_input_handler(editor_); for (i=0; i < nbrowser_; ++i) { fchooser_->append_input_handler(fbrowser_[i]); } fchooser_->next_focus(); Glyph* g = layout.vbox(); if (caption.length() > 0) { g->append(layout.r_margin(kit.fancy_label(caption), 5.0, fil, 0.0)); } if (subcaption.length() > 0) { g->append(layout.r_margin(kit.fancy_label(subcaption), 5.0, fil, 0.0)); } g->append(layout.vglue(5.0, 0.0, 2.0)); g->append(editor_); g->append(layout.vglue(5.0, 0.0, 2.0)); g->append(makeshowmenu()); g->append(layout.vglue(15.0, 0.0, 12.0)); PolyGlyph* h = layout.hbox(nbrowser_); Glyph* b; for (i=0; i < nbrowser_; ++i) { b = layout.hbox( layout.vcenter( kit.inset_frame( layout.margin( layout.natural_span(fbrowser_[i], width, height), 1.0 ) ), 1.0 ), layout.hspace(4.0), kit.vscroll_bar(fbrowser_[i]->adjustable()) ); h->append(b); } g->append(h); g->append(layout.vspace(15.0)); if (s->value_is_on("filter")) { FieldEditorAction* action = new FieldEditorCallback(SymChooserImpl)( this, &SymChooserImpl::filter_accept, nil ); filter_ = add_filter( s, "filterPattern", "", "filterCaption", "Filter:", g, action ); if (s->value_is_on("directoryFilter")) { directory_filter_ = add_filter( s, "directoryFilterPattern", "", "directoryFilterCaption", "Name Filter:", g, action ); } else { directory_filter_ = nil; } } else { filter_ = nil; directory_filter_ = nil; } g->append( layout.hbox( layout.hglue(10.0), layout.vcenter(kit.default_button(open, accept)), layout.hglue(10.0, 0.0, 5.0), layout.vcenter(kit.push_button(close, cancel)), layout.hglue(10.0) ) ); fchooser_->body( layout.vcenter(kit.outset_frame(layout.margin(g, 5.0)), 1.0) ); kit.pop_style(); load(0); }