void draw_rectangle(int x, int y, int w, int h, color_t border, color_t back) { // Background parts const wchar_t kLowerRightQuad = 0x2597, kLowerHalf = 0x2584, kLowerLeftQuad = 0x2596, kRightHalf = 0x2590, kFullBlock = 0x2588, kLeftHalf = 0x258C, kUpperRightQuad = 0x259D, kUpperHalf = 0x2580, kUpperLeftQuad = 0x2598; // Border parts const wchar_t kUpperLeftCorner = 0x250C, kHorisontal = 0x2500, kUpperRightCorner = 0x2510, kVertical = 0x2502, /* none */ /* kVertical */ kLowerLeftCorner = 0x2514, /* kHorisontal */ kLowerRightCorner = 0x2518; // FIXME terminal_blending(BLENDING_ADDITIVE); // First, background if (color_alpha(back) > 0) { terminal_color(back); for ( int i = x+1; i < (x+w)-1; i++ ) { for ( int j = y+1; j < (y+h)-1; j++ ) { terminal_put(i, j, kFullBlock); } terminal_put(i, y, kLowerHalf); terminal_put(i, y+h-1, kUpperHalf); } for ( int j = y+1; j < (y+h)-1; j++ ) { terminal_put(x, j, kRightHalf); terminal_put(x+w-1, j, kLeftHalf); } terminal_put(x, y, kLowerRightQuad); terminal_put(x+w-1, y, kLowerLeftQuad); terminal_put(x, y+h-1, kUpperRightQuad); terminal_put(x+w-1, y+h-1, kUpperLeftQuad); } // Then, border terminal_color(border); for ( int i = x+1; i < (x+w)-1; i++ ) { terminal_put(i, y, kHorisontal); terminal_put(i, y+h-1, kHorisontal); } for ( int j = y+1; j < (y+h)-1; j++ ) { terminal_put(x, j, kVertical); terminal_put(x+w-1, j, kVertical); } terminal_put(x, y, kUpperLeftCorner); terminal_put(x+w-1, y, kUpperRightCorner); terminal_put(x, y+h-1, kLowerLeftCorner); terminal_put(x+w-1, y+h-1, kLowerRightCorner); }
static Sk4f overlay_4f(const Sk4f& s, const Sk4f& d) { Sk4f sa = alpha(s); Sk4f da = alpha(d); Sk4f two = Sk4f(2); Sk4f rc = (two * d <= da).thenElse(two * s * d, sa * da - two * (da - d) * (sa - s)); return pin_1(s + d - s * da + color_alpha(rc - d * sa, 0)); }
static Sk4f colorburn_4f(const Sk4f& s, const Sk4f& d) { Sk4f sa = alpha(s); Sk4f da = alpha(d); Sk4f isa = Sk4f(1) - sa; Sk4f ida = Sk4f(1) - da; Sk4f srcover = s + d * isa; Sk4f dstover = d + s * ida; Sk4f otherwise = sa * (da - Sk4f::Min(da, (da - d) * sa / s)) + s * ida + d * isa; // Order matters here, preferring d==da over s==0. auto colors = (d == da).thenElse(dstover, (s == Sk4f(0)).thenElse(srcover, otherwise)); return color_alpha(colors, srcover); }
static Sk4f saturation_4f(const Sk4f& s, const Sk4f& d) { float sa = s[SkPM4f::A]; float sr = s[SkPM4f::R]; float sg = s[SkPM4f::G]; float sb = s[SkPM4f::B]; float da = d[SkPM4f::A]; float dr = d[SkPM4f::R]; float dg = d[SkPM4f::G]; float db = d[SkPM4f::B]; float Dr = dr; float Dg = dg; float Db = db; SetSat(&Dr, &Dg, &Db, Sat(sr, sg, sb) * da); SetLum(&Dr, &Dg, &Db, sa * da, Lum(dr, dg, db) * sa); return color_alpha(s * inv_alpha(d) + d * inv_alpha(s) + set_argb(0, Dr, Dg, Db), sa + da - sa * da); }
static Sk4f hue_4f(const Sk4f& s, const Sk4f& d) { float sa = s[SkPM4f::A]; float sr = s[SkPM4f::R]; float sg = s[SkPM4f::G]; float sb = s[SkPM4f::B]; float da = d[SkPM4f::A]; float dr = d[SkPM4f::R]; float dg = d[SkPM4f::G]; float db = d[SkPM4f::B]; float Sr = sr; float Sg = sg; float Sb = sb; SetSat(&Sr, &Sg, &Sb, Sat(dr, dg, db) * sa); SetLum(&Sr, &Sg, &Sb, sa * da, Lum(dr, dg, db) * sa); return color_alpha(s * inv_alpha(d) + d * inv_alpha(s) + set_argb(0, Sr, Sg, Sb), sa + da - sa * da); }
static Sk4f luminosity_4f(const Sk4f& s, const Sk4f& d) { float sa = s[SkPM4f::A]; float sr = s[SkPM4f::R]; float sg = s[SkPM4f::G]; float sb = s[SkPM4f::B]; float da = d[SkPM4f::A]; float dr = d[SkPM4f::R]; float dg = d[SkPM4f::G]; float db = d[SkPM4f::B]; float Dr = dr; float Dg = dg; float Db = db; SetLum(&Dr, &Dg, &Db, sa * da, Lum(sr, sg, sb) * da); Sk4f res = color_alpha(s * inv_alpha(d) + d * inv_alpha(s) + set_argb(0, Dr, Dg, Db), sa + da - sa * da); // Can return tiny negative values ... return Sk4f::Max(res, Sk4f(0)); }
static Sk4f color_4f(const Sk4f& s, const Sk4f& d) { float sa = s[SkPM4f::A]; float sr = s[SkPM4f::R]; float sg = s[SkPM4f::G]; float sb = s[SkPM4f::B]; float da = d[SkPM4f::A]; float dr = d[SkPM4f::R]; float dg = d[SkPM4f::G]; float db = d[SkPM4f::B]; float Sr = sr; float Sg = sg; float Sb = sb; SetLum(&Sr, &Sg, &Sb, sa * da, Lum(dr, dg, db) * sa); Sk4f res = color_alpha(s * inv_alpha(d) + d * inv_alpha(s) + set_argb(0, Sr, Sg, Sb), sa + da - sa * da); // Can return tiny negative values ... return Sk4f::Max(res, Sk4f(0)); }
static Sk4f softlight_4f(const Sk4f& s, const Sk4f& d) { Sk4f sa = alpha(s); Sk4f da = alpha(d); Sk4f isa = Sk4f(1) - sa; Sk4f ida = Sk4f(1) - da; // Some common terms. Sk4f m = (da > Sk4f(0)).thenElse(d / da, Sk4f(0)); Sk4f s2 = Sk4f(2) * s; Sk4f m4 = Sk4f(4) * m; // The logic forks three ways: // 1. dark src? // 2. light src, dark dst? // 3. light src, light dst? Sk4f darkSrc = d * (sa + (s2 - sa) * (Sk4f(1) - m)); // Used in case 1. Sk4f darkDst = (m4 * m4 + m4) * (m - Sk4f(1)) + Sk4f(7) * m; // Used in case 2. Sk4f liteDst = m.sqrt() - m; // Used in case 3. Sk4f liteSrc = d * sa + da * (s2 - sa) * (Sk4f(4) * d <= da).thenElse(darkDst, liteDst); // Case 2 or 3? return color_alpha(s * ida + d * isa + (s2 <= sa).thenElse(darkSrc, liteSrc), // Case 1 or 2/3? s + d * isa); }
virtual void on_draw() { typedef agg::pixfmt_bgr24 pixfmt; typedef agg::renderer_base<pixfmt> renderer_base; pixfmt pixf(rbuf_window()); renderer_base rb(pixf); rb.clear(agg::rgba(1.0, 1.0, 1.0)); agg::trans_affine src_mtx; src_mtx *= agg::trans_affine_translation(-initial_width()/2, -initial_height()/2); src_mtx *= agg::trans_affine_rotation(10.0 * agg::pi / 180.0); src_mtx *= agg::trans_affine_translation(initial_width()/2, initial_height()/2); src_mtx *= trans_affine_resizing(); agg::trans_affine img_mtx = src_mtx; img_mtx.invert(); typedef agg::span_allocator<agg::rgba8> span_alloc; unsigned i; unsigned char brightness_alpha_array[agg::span_conv_brightness_alpha_rgb8::array_size]; for(i = 0; i < agg::span_conv_brightness_alpha_rgb8::array_size; i++) { brightness_alpha_array[i] = agg::int8u(m_alpha.value(double(i) / double(agg::span_conv_brightness_alpha_rgb8::array_size)) * 255.0); } agg::span_conv_brightness_alpha_rgb8 color_alpha(brightness_alpha_array); typedef agg::image_accessor_clip<pixfmt> img_source_type; typedef agg::span_interpolator_linear<> interpolator_type; typedef agg::span_image_filter_rgb_bilinear<img_source_type, interpolator_type> span_gen; typedef agg::span_converter<span_gen, agg::span_conv_brightness_alpha_rgb8> span_conv; span_alloc sa; interpolator_type interpolator(img_mtx); pixfmt img_pixf(rbuf_img(0)); img_source_type img_src(img_pixf, agg::rgba(0,0,0,0)); span_gen sg(img_src, interpolator); span_conv sc(sg, color_alpha); agg::ellipse ell; agg::rasterizer_scanline_aa<> ras; agg::scanline_u8 sl; for(i = 0; i < 50; i++) { ell.init(m_x[i], m_y[i], m_rx[i], m_ry[i], 50); ras.add_path(ell); agg::render_scanlines_aa_solid(ras, sl, rb, m_colors[i]); } ell.init(initial_width() / 2.0, initial_height() / 2.0, initial_width() / 1.9, initial_height() / 1.9, 200); agg::conv_transform<agg::ellipse> tr(ell, src_mtx); ras.add_path(tr); agg::render_scanlines_aa(ras, sl, rb, sa, sc); agg::render_ctrl(ras, sl, rb, m_alpha); }
static Sk4f color_alpha(const Sk4f& color, const Sk4f& newAlpha) { return color_alpha(color, newAlpha[3]); }
static Sk4f exclusion_4f(const Sk4f& s, const Sk4f& d) { Sk4f product = s * d; return s + d - product - color_alpha(product, 0); }
static Sk4f difference_4f(const Sk4f& s, const Sk4f& d) { Sk4f min = Sk4f::Min(s * alpha(d), d * alpha(s)); return s + d - min - color_alpha(min, 0); }
void builder::node(string str, bool add_space) { string::size_type n, m; string s(str); while (true) { if (s.empty()) { break; } else if ((n = s.find("%{F-}")) == 0) { color_close(!m_lazy); s.erase(0, 5); } else if ((n = s.find("%{F#")) == 0 && (m = s.find("}")) != string::npos) { if (m - n - 4 == 2) color_alpha(s.substr(n + 3, m - 3)); else color(s.substr(n + 3, m - 3)); s.erase(n, m + 1); } else if ((n = s.find("%{B-}")) == 0) { background_close(!m_lazy); s.erase(0, 5); } else if ((n = s.find("%{B#")) == 0 && (m = s.find("}")) != string::npos) { background(s.substr(n + 3, m - 3)); s.erase(n, m + 1); } else if ((n = s.find("%{T-}")) == 0) { font_close(!m_lazy); s.erase(0, 5); } else if ((n = s.find("%{T")) == 0 && (m = s.find("}")) != string::npos) { font(std::atoi(s.substr(n + 3, m - 3).c_str())); s.erase(n, m + 1); } else if ((n = s.find("%{U-}")) == 0) { line_color_close(!m_lazy); s.erase(0, 5); } else if ((n = s.find("%{U#")) == 0 && (m = s.find("}")) != string::npos) { line_color(s.substr(n + 3, m - 3)); s.erase(n, m + 1); } else if ((n = s.find("%{+u}")) == 0) { underline(); s.erase(0, 5); } else if ((n = s.find("%{+o}")) == 0) { overline(); s.erase(0, 5); } else if ((n = s.find("%{-u}")) == 0) { underline_close(true); s.erase(0, 5); } else if ((n = s.find("%{-o}")) == 0) { overline_close(true); s.erase(0, 5); } else if ((n = s.find("%{A}")) == 0) { cmd_close(true); s.erase(0, 4); } else if ((n = s.find("%{")) == 0 && (m = s.find("}")) != string::npos) { append(s.substr(n, m + 1)); s.erase(n, m + 1); } else if ((n = s.find("%{")) > 0) { append(s.substr(0, n)); s.erase(0, n); } else break; } if (!s.empty()) append(s); if (add_space) space(); }