int main() { { TimeCheck time; auto surface = create_surface(CAIRO_FORMAT_ARGB32, SURFACE_SIZE{ 256, 256 }); auto cr = create(surface); line_width(cr, 30.0); line_cap(cr, CAIRO_LINE_CAP_BUTT); /* default */ move_to(cr, POINT{ 64.0, 50.0 }); line_to(cr, POINT{ 64.0, 200.0 }); stroke(cr); line_cap(cr, CAIRO_LINE_CAP_ROUND); move_to(cr, POINT{ 128.0, 50.0 }); line_to(cr, POINT{ 128.0, 200.0 }); stroke(cr); line_cap(cr, CAIRO_LINE_CAP_SQUARE); move_to(cr, POINT{ 192.0, 50.0 }); line_to(cr, POINT{ 192.0, 200.0 }); stroke(cr); /* draw helping lines */ source(cr, RGB{ 1, 0.2, 0.2 }); line_width(cr, 2.56); move_to(cr, POINT{ 64.0, 50.0 }); line_to(cr, POINT{ 64.0, 200.0 }); move_to(cr, POINT{ 128.0, 50.0 }); line_to(cr, POINT{ 128.0, 200.0 }); move_to(cr, POINT{ 192.0, 50.0 }); line_to(cr, POINT{ 192.0, 200.0 }); stroke(cr); write_to_png(surface, "image.png"); } return 0; }
std::string make_text_ellipsis(const std::string &text, int font_size, int max_width, bool with_tags, bool parse_for_style) { static const std::string ellipsis = "..."; SDL_Color unused_color; int unused_int; int style = TTF_STYLE_NORMAL; if(parse_for_style) parse_markup(text.begin(), text.end(), &unused_int, &unused_color, &style); if(line_width(with_tags ? text : del_tags(text), font_size, style) <= max_width) return text; if(line_width(ellipsis, font_size, style) > max_width) return ""; std::string current_substring; utils::utf8_iterator itor(text); for(; itor != utils::utf8_iterator::end(text); ++itor) { std::string tmp = current_substring; tmp.append(itor.substr().first, itor.substr().second); tmp += ellipsis; if (line_width(with_tags ? tmp : del_tags(tmp), font_size, style) > max_width) { return current_substring + ellipsis; } current_substring.append(itor.substr().first, itor.substr().second); } return text; // Should not happen }
void snap_line_width(std::shared_ptr< cairo_t>& cr) { double x_width = line_width(cr); double y_width = x_width; user_to_device_distance(cr, x_width, y_width); /* If the line width is less than 1 then it will round to 0 and * disappear. Instead, we clamp it to 1.0, but we must preserve * its sign for the case of a reflecting transformation. */ double x_width_snapped = floor(x_width + 0.5); if (fabs(x_width_snapped) < 1.0) { if (x_width > 0) x_width_snapped = 1.0; else x_width_snapped = -1.0; } double y_width_snapped = floor(y_width + 0.5); if (fabs(y_width_snapped) < 1.0) { if (y_width > 0) y_width_snapped = 1.0; else y_width_snapped = -1.0; } double x_error = fabs(x_width - x_width_snapped); double y_error = fabs(y_width - y_width_snapped); device_to_user_distance(cr, x_width_snapped, y_width_snapped); if (x_error > y_error) line_width(cr, x_width_snapped); else line_width(cr, y_width_snapped); }
int main() { { TimeCheck time; auto surface = create_surface(CAIRO_FORMAT_ARGB32, SURFACE_SIZE{ 256, 256 }); auto cr = create(surface); arc(cr, POINT{ 128.0, 128.0 }, 76.8, DEGRESS{ 0 }, DEGRESS{ 360 }); clip(cr); new_path(cr); /* current path is not consumed by cairo_clip() */ rectangle(cr, POINT{ 0, 0 }, SIZE{ 255, 255 }); fill(cr); source(cr, RGB{ 0, 1, 0 }); move_to(cr, POINT{ 0, 0 }); line_to(cr, POINT{ 256, 256 }); move_to(cr, POINT{ 256, 0 }); line_to(cr, POINT{ 0, 256 }); line_width(cr, 10.0); stroke(cr); write_to_png(surface, "image.png"); } return 0; }
void draw_nested(std::shared_ptr< cairo_t>& cr, const nested_style_t& style, const snapping_t& snapping) { #define NUM_BOXES 5 #define BOX_WIDTH 13 /* We need non-integer scale factors to demonstrate anything interesting. */ #define SCALE_TWEAK 1.11 double mscale, offset = SCALE_TWEAK * BOX_WIDTH / 2.0; save(cr); { line_width(cr, 1.0); for (int i = 0; i < NUM_BOXES; i++) { save(cr); { mscale = SCALE_TWEAK * (NUM_BOXES - i); scale(cr, SCALE{ mscale, mscale }); rectangle(cr, POINT{ 0, 0 }, SIZE{ BOX_WIDTH, BOX_WIDTH }); if (style == NESTED_FILLS) { if (snapping == SNAPPING) snap_path_for_fill(cr); if (i % 2 == 0) source(cr, RGB{ 1, 1, 1 }); else source(cr, RGB{ 0, 0, 0 }); fill(cr); } else { if (snapping == SNAPPING) snap_path_for_stroke(cr); source(cr, RGB{ 1, 1, 1 }); stroke(cr); } } restore(cr); translate(cr, POINT{ offset, offset }); } } restore(cr); }
void snap_point_for_stroke(std::shared_ptr< cairo_t>& cr, double& x, double& y) { /* * Round in device space after adding the fractional portion of * one-half the (device space) line width. */ double x_width_dev_2 = line_width(cr); double y_width_dev_2 = x_width_dev_2; user_to_device_distance(cr, x_width_dev_2, y_width_dev_2); x_width_dev_2 *= 0.5; y_width_dev_2 *= 0.5; double x_offset = x_width_dev_2 - (int)(x_width_dev_2); double y_offset = y_width_dev_2 - (int)(y_width_dev_2); user_to_device(cr, x, y); x = floor(x + x_offset + 0.5); y = floor(y + y_offset + 0.5); x -= x_offset; y -= y_offset; device_to_user(cr, x, y); }
void LcCairoPainter::scale(double s) { cairo_scale(_cr, s, s); line_width(_lineWidth); }
SDL_Rect draw_text_line(surface gui_surface, const SDL_Rect& area, int size, const SDL_Color& colour, const std::string& text, int x, int y, bool use_tooltips, int style) { if (gui_surface.null()) { text_surface const &u = text_cache::find(text_surface(text, size, colour, style)); SDL_Rect res = {0, 0, u.width(), u.height()}; return res; } if(area.w == 0) { // no place to draw SDL_Rect res = {0,0,0,0}; return res; } const std::string etext = make_text_ellipsis(text, size, area.w); // for the main current use, we already parsed markup surface surface(render_text(etext,size,colour,style,false)); if(surface == NULL) { SDL_Rect res = {0,0,0,0}; return res; } SDL_Rect dest; if(x!=-1) { dest.x = x; #ifdef HAVE_FRIBIDI // Oron -- Conditional, until all draw_text_line calls have fixed area parameter if(getenv("NO_RTL") == NULL) { bool is_rtl = text_cache::find(text_surface(text, size, colour, style)).is_rtl(); if(is_rtl) dest.x = area.x + area.w - surface->w - (x - area.x); } #endif } else dest.x = (area.w/2)-(surface->w/2); if(y!=-1) dest.y = y; else dest.y = (area.h/2)-(surface->h/2); dest.w = surface->w; dest.h = surface->h; if(line_width(text, size) > area.w) { tooltips::add_tooltip(dest,text); } if(dest.x + dest.w > area.x + area.w) { dest.w = area.x + area.w - dest.x; } if(dest.y + dest.h > area.y + area.h) { dest.h = area.y + area.h - dest.y; } if(gui_surface != NULL) { SDL_Rect src = dest; src.x = 0; src.y = 0; SDL_BlitSurface(surface,&src,gui_surface,&dest); } if(use_tooltips) { tooltips::add_tooltip(dest,text); } return dest; }
void grid_node_t::do_process( const render::context_t& context) { Imath::Color4f color( get_value<Imath::Color4f>( param( "bgcol"))); boost::gil::fill_pixels( image_view(), image::pixel_t( color.r, color.g, color.b, color.a)); Imath::V2f size( get_absolute_value<Imath::V2f>( param( "size"))); Imath::V2f translate( get_absolute_value<Imath::V2f>( param( "translate"))); Imath::V2f line_width( get_absolute_value<Imath::V2f>( param( "linewidth"))); color = get_value<Imath::Color4f>( param( "fgcol")); // adjust params size.x = size.x / context.subsample / aspect_ratio(); size.y /= context.subsample; if( size.x == 0 || size.y == 0) return; translate.x = translate.x / context.subsample / aspect_ratio(); translate.y /= context.subsample; line_width.x = line_width.x / context.subsample / aspect_ratio(); line_width.y /= context.subsample; if( line_width.x == 0 || line_width.y == 0) return; // setup agg typedef image::agg_rgba32f_renderer_t ren_base_type; typedef ren_base_type::color_type color_type; typedef agg::renderer_scanline_aa_solid<ren_base_type> renderer_type; ren_base_type ren_base( image_view()); renderer_type ren( ren_base); agg::rasterizer_scanline_aa<> ras; ras.gamma( agg::gamma_none()); agg::scanline_u8 sl; ras.reset(); agg::path_storage path; agg::conv_stroke<agg::path_storage> stroke_conv( path); // Vertical stroke_conv.width( line_width.x); int w = image_view().width(); int h = image_view().height(); Imath::Box2f area( defined().min - translate, defined().max - translate); float x = Imath::Math<float>::floor( area.min.x / size.x) * size.x; for( ; x < area.max.x + line_width.x; x += size.x) { path.move_to( x - area.min.x, 0); path.line_to( x - area.min.x, h); } ras.add_path( stroke_conv); ren.color( image::pixel_t( color.r, color.g, color.b, color.a)); agg::render_scanlines( ras, sl, ren); // Horizontal path.remove_all(); stroke_conv.width( line_width.y); float y = Imath::Math<float>::floor( area.min.y / size.y) * size.y; for( ; y < area.max.y + line_width.y; y += size.y) { path.move_to( 0, y - area.min.y); path.line_to( w, y - area.min.y); } ras.add_path( stroke_conv); ren.color( image::pixel_t( color.r, color.g, color.b, color.a)); agg::render_scanlines( ras, sl, ren); }
double TF3D::width(std::string str) { return line_width(font, str.c_str()); }
ICOS_Float voigt::line_end(ICOS_Float *a) { return (nu_P + GlobalData.LeftLineMarginMultiplier*line_width(a)); }
ICOS_Float voigt::line_start(ICOS_Float*a) { return (nu_P - GlobalData.RightLineMarginMultiplier*line_width(a)); }