void x_window_rep::translate (SI x1, SI y1, SI x2, SI y2, SI dx, SI dy) { ren->set_origin(0,0); begin_draw (); ren->clip (x1, y1, x2, y2); SI X1= x1+ dx; SI Y2= y2+ dy; ren->decode (x1, y1); ren->decode (x2, y2); ren->decode (X1, Y2); dx= X1- x1; dy= Y2- y2; XEvent report; while (XCheckWindowEvent (dpy, win, ExposureMask, &report)) gui->process_event (this, &report); rectangles region (rectangle (x1, y2, x2, y1)); rectangles invalid_intern= invalid_regions & region; rectangles invalid_extern= invalid_regions - invalid_intern; invalid_intern = ::translate (invalid_intern, dx, dy) & region; invalid_regions= invalid_extern | invalid_intern; rectangles extra= thicken (region - ::translate (region, dx, dy), 1, 1); invalid_regions= invalid_regions | extra; if (x1<x2 && y2<y1) XCopyArea (dpy, win, win, gc, x1, y2, x2-x1, y1-y2, X1, Y2); ren->unclip (); end_draw (); }
void PerspectiveObject::draw() { begin_draw(); int box[4]; get_screen_aabb(box); glc_copy_color_buffer_rect(texture, box[0], box[1], box[2], box[3]); glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, texture); glColor4f(1.0f, 0.0f, 0.0f, 1.0f); glBegin(GL_QUADS); glTexCoord2f(back_texcoords[0], back_texcoords[1]); glVertex2d(x, y); glTexCoord2f(back_texcoords[2], back_texcoords[3]); glVertex2d(x + width, y); glTexCoord2f(back_texcoords[4], back_texcoords[5]); glVertex2d(x + width, y + height); glTexCoord2f(back_texcoords[6], back_texcoords[7]); glVertex2d(x, y + height); glEnd(); glDisable(GL_TEXTURE_2D); end_draw(); }
void PerspectiveObject::draw() { int box[4]; get_screen_aabb(box); Texture t = Render::copy_rect(box[0], box[1], box[2], box[3]); begin_draw(); Render::disable_blend(); Render::draw_tex(x, y, x + width, y + height, Color(255, 255, 255, 255), t, back_texcoords[0], back_texcoords[1], back_texcoords[2], back_texcoords[3]); Render::enable_blend(); end_draw(); }
void TextBlitter::draw() { callback_line_count = int(lines.size()); Image * image; if (draw_image == NULL) image = this->image; else image = draw_image; if (!replacer.empty()) draw_image = image = replacer.apply(image, this->image); image->upload_texture(); begin_draw(); int x_add = char_width + x_spacing; int y_add = char_height + y_spacing; int yy = y + y_scroll; if (alignment & ALIGN_VCENTER) yy += height / 2 - lines.size() * char_height / 2 - (lines.size()) * y_spacing / 2; int bottom_y = y + height; int img_width = (image_width / char_width) * char_width; int screen_y1 = 0 - (layer->off_y - frame->off_y); int screen_y2 = screen_y1 + WINDOW_HEIGHT; for (int line_index = 0; line_index < int(lines.size()); ++line_index) { if (yy <= y - y_add || yy >= bottom_y || yy + y_add <= screen_y1 || yy >= screen_y2) { yy += y_add; continue; } const LineReference & line = lines[line_index]; int xx = x + x_scroll; if (alignment & ALIGN_HCENTER) { xx += (width - line.size * x_add) / 2; } else if (alignment & ALIGN_RIGHT) { xx += width - line.size * x_add; } // draw line for (int i = 0; i < line.size; i++) { unsigned char c = (unsigned char)line.start[i]; c -= char_offset; int ci = charmap[c]; int img_x = (ci * char_width) % img_width; img_x = clamp(img_x + x_off, 0, image->width); int img_y = ((ci * char_width) / img_width) * char_height; img_y = clamp(img_y + y_off, 0, image->height); float t_x1 = float(img_x) / float(image->width); float t_x2 = float(img_x+char_width) / float(image->width); float t_y1 = float(img_y) / float(image->height); float t_y2 = float(img_y+char_height) / float(image->height); Color color = blend_color; int yyy = yy; if (anim_type == BLITTER_ANIMATION_SINWAVE) { double t = double(anim_frame / anim_speed + x_add * i); t /= double(wave_freq); yyy += int(sin(t) * wave_height); } else if (has_callback) { callback_line = line_index; callback_char = i; callback_transparency = 0; call_char_callback(); color.set_semi_transparency(callback_transparency); } Render::draw_tex(xx, yyy, xx + char_width, yyy + char_height, color, image->tex, t_x1, t_y1, t_x2, t_y2); xx += x_add; } yy += y_add; } end_draw(); }
void SurfaceObject::draw() { if (!quads.empty()) { begin_draw(); vector<SurfaceQuad>::const_iterator it; for (it = quads.begin(); it != quads.end(); it++) { const SurfaceQuad & quad = *it; float p[8]; for (int i = 0; i < 8; i += 2) { p[i] = quad.points[i].x; p[i+1] = quad.points[i].y; } Render::draw_quad(&p[0], quad.color); } end_draw(); return; } if (!lines.empty()) { lines.clear(); } if (display_selected) displayed_image = selected_image; if (displayed_image == NULL) return; if (use_fbo_blit) { surface_fbo.bind(); int old_offset[2] = {Render::offset[0], Render::offset[1]}; Render::set_view(0, 0, SURFACE_FBO_WIDTH, SURFACE_FBO_HEIGHT); Render::set_offset(0, 0); Render::clear(clear_color); vector<SurfaceBlit>::const_iterator it; for (it = blit_images.begin(); it != blit_images.end(); it++) { const SurfaceBlit & img = *it; if (img.effect == 11) Render::set_effect(Render::SURFACESUBTRACT); int draw_x = img.x + img.image->hotspot_x * img.scale_x; int draw_y = img.y + img.image->hotspot_y * img.scale_y; img.image->draw(draw_x, draw_y, 0.0, img.scale_x, img.scale_y); if (img.effect == 11) Render::disable_effect(); } blit_images.clear(); Render::set_view(0, 0, WINDOW_WIDTH, WINDOW_HEIGHT); Render::set_offset(old_offset[0], old_offset[1]); surface_fbo.unbind(); begin_draw(SURFACE_FBO_WIDTH, SURFACE_FBO_HEIGHT); int x1 = x; int y1 = y; int x2 = x1 + SURFACE_FBO_WIDTH; int y2 = y1 + SURFACE_FBO_HEIGHT; Render::draw_tex(x1, y1, x2, y2, blend_color, surface_fbo.get_tex()); end_draw(); return; } if (use_image_blit) { vector<SurfaceBlit>::const_iterator it; int display_width = displayed_image->width; for (it = blit_images.begin(); it != blit_images.end(); it++) { const SurfaceBlit & img = *it; Image * hh = img.image; // XXX this is a hack, generalize it if (effect == Render::SUBPX) hh->set_filter(true); hh->upload_texture(); Texture t = hh->tex; begin_draw(hh->width, hh->height); int off_x = x + hh->hotspot_x * img.scale_x; int off_y = y + hh->hotspot_y * img.scale_y; int draw_x = img.x + img.scroll_x; int draw_y = img.y + img.scroll_y; int w = hh->width * img.scale_x; int h = hh->height * img.scale_y; Render::draw_tex(draw_x + off_x, draw_y + off_y, draw_x + off_x + w, draw_y + off_y + h, blend_color, t); for (int i = -1; i <= 1; i += 2) { int x1 = draw_x + display_width * i; int y1 = draw_y; int x2 = x1 + hh->width; if (x1 >= 0 && x2 <= display_width) continue; if (x1 >= display_width || x2 <= 0) continue; int xx1 = x1 + off_x; int yy1 = y1 + off_y; Render::draw_tex(xx1, yy1, xx1 + w, yy1 + h, blend_color, t); } end_draw(); } } else { if (displayed_image->handle == NULL) return; SurfaceImage & m = *displayed_image; Image * hh = m.handle; int w = hh->width; int h = hh->height; float scale_x = m.width / float(w); float scale_y = m.height / float(h); Render::enable_scissor(x, y, m.get_display_width(), m.get_display_height()); if ((m.scroll_x == 0 && m.scroll_y == 0) || !m.wrap) { draw_image(hh, x + m.scroll_x, y + m.scroll_y, blend_color, 0.0, scale_x, scale_y, m.has_reverse_x); } else { int start_x = x - (hh->width - m.scroll_x); int start_y = y - (hh->height - m.scroll_y); for (int xx = start_x; xx < x + m.canvas_width; xx += w) for (int yy = start_y; yy < y + m.canvas_height; yy += h) { draw_image(hh, xx, yy, blend_color, 0.0, 1.0, 1.0, m.has_reverse_x); } } Render::disable_scissor(); } }
void stash::render( const float &sx, const float &sy, const float &interlining_pt, const std::string &text ) { float dx = sx, dy = sy, lh; vmetrics( 0, interlining_pt, NULL,NULL, &lh ); lh *= 1.2f; // interleave glRasterPos2f( sx, sy ); std::deque<std::string> tokens = split( text, "/*{|}\r\n" ); begin_draw(); bool italic = false, bold = false; int face = 0; float size = 12.f; for( size_t i = 0; i < tokens.size(); ++i ) { std::string &token = tokens[i]; if( token == "/" ) { if( italic ^= true ) face = 1; else face = 0; continue; } if( token == "*" ) { if( bold ^= true ) face = 2; else face = 0; continue; } if( token == "\r" || token == "\n" ) { dx = sx; dy -= lh; continue; } if( token == "{" || token == "|" ) { ++i; if( i >= tokens.size() ) continue; aliases_it it = aliases.find( tokens[i] ); if( it != aliases.end() ) { face = it->second; continue; } if( as<float>(tokens[ i ]) > 0.f ) size = as<float>(tokens[ i ]); continue; } if( token == "}" ) { continue; } draw_text( face, size, dx,dy, token.c_str(), &dx ); } end_draw(); }
~Surface() { end_draw(); }
int __stdcall wWinMain(HINSTANCE instance, HINSTANCE, wchar_t* cmdline, int cmd_show) { ::CoInitializeEx(NULL, COINIT_MULTITHREADED); try { DCoWindow window; // Create device independent resources. FactoryD2D1 and Geometries are such. auto wic_factory = plx::CreateWICFactory(); #if defined (_DEBUG) auto d2d1_factory = plx::CreateD2D1FactoryST(D2D1_DEBUG_LEVEL_INFORMATION); #else auto d2d1_factory = plx::CreateD2D1FactoryST(D2D1_DEBUG_LEVEL_NONE); #endif const auto circle = D2D1::Ellipse(D2D1::Point2F(50.0f, 50.0f), 49.0f, 49.0f); plx::ComPtr<ID2D1EllipseGeometry> circle_geom; auto hr = d2d1_factory->CreateEllipseGeometry(circle, circle_geom.GetAddressOf()); if (hr != S_OK) throw plx::ComException(__LINE__, hr); // Device dependent resources. #if defined (_DEBUG) auto device3D = plx::CreateDeviceD3D11(D3D11_CREATE_DEVICE_DEBUG); #else auto device3D = plx::CreateDevice3D(0); #endif auto device2D = plx::CreateDeviceD2D1(device3D, d2d1_factory); VisualManager viman(window.window(), window.dpi(), device2D); window.set_visual_manager(&viman); const D2D1_SIZE_F zero_offset = {0}; auto background = viman.make_surface(1.0f, 1.0f); { auto dc = background.begin_draw(D2D1::ColorF(0.3f, 0.3f, 0.3f, 0.7f), zero_offset); background.end_draw(); } viman.set_background_surface(window.window(), background); // scale-dependent resources. auto surface1 = viman.make_surface(100.0f, 100.0f); { auto dc = surface1.begin_draw(D2D1::ColorF(0.0f, 0.0f, 0.0f, 0.0f), zero_offset); plx::ComPtr<ID2D1SolidColorBrush> brush; dc->CreateSolidColorBrush(D2D1::ColorF(0.0f, 0.5f, 1.0f, 0.4f), brush.GetAddressOf()); dc->FillGeometry(circle_geom.Get(), brush.Get()); brush->SetColor(D2D1::ColorF(1.0f, 1.0f, 1.0f)); dc->DrawGeometry(circle_geom.Get(), brush.Get()); surface1.end_draw(); } unsigned int as_width, as_height; auto png1 = plx::CreateWICDecoder( wic_factory, plx::FilePath(L"c:\\test\\images\\diamonds_k.png")); auto png1_cv = plx::CreateWICBitmapBGRA(0, WICBitmapDitherTypeNone, png1, wic_factory); png1_cv->GetSize(&as_width, &as_height); auto sc_width = window.dpi().to_physical_x(as_width * 0.5f); auto sc_height = window.dpi().to_physical_y(as_height * 0.5f); auto surface2 = viman.make_surface(sc_width, sc_height); { auto dc = surface2.begin_draw(D2D1::ColorF(0.0f, 0.0f, 0.4f, 0.0f), zero_offset); auto bmp1 = CreateD2D1Bitmap(dc, png1_cv); auto dr = D2D1::Rect(0.0f, 0.0f, sc_width, sc_height); dc->DrawBitmap(bmp1.Get(), &dr, 1.0f); surface2.end_draw(); } // add the image at the bottom. viman.add_visual(surface2, D2D1::Point2F(0.0f, 0.0f)); auto svg = RealizeSVG( //"C:\\Users\\cpu\\Documents\\GitHub\\nanosvg\\example\\nano.svg", //"C:\\Test\\svg\\2_elipse_red_black.svg", "C:\\Test\\svg\\3_red_arrows_angles.svg", window.dpi(), d2d1_factory); D2D1_RECT_F svg_bounds = {}; hr = svg->GetBounds(nullptr, &svg_bounds); auto surface3 = viman.make_surface( window.dpi().to_physical_x(svg_bounds.right - svg_bounds.left + 1), window.dpi().to_physical_y(svg_bounds.bottom - svg_bounds.top + 1)); { auto dc = surface3.begin_draw( D2D1::ColorF(0.7f, 0.7f, 0.7f, 0.4f), D2D1::SizeF(-svg_bounds.left, -svg_bounds.top)); plx::ComPtr<ID2D1SolidColorBrush> brush; dc->CreateSolidColorBrush( D2D1::ColorF(0.5f, 0.0f, 1.0f, 0.4f), brush.GetAddressOf()); // Now we can paint and we can draw. dc->FillGeometry(svg.Get(), brush.Get()); brush->SetColor(D2D1::ColorF(1.0f, 1.0f, 1.0f)); dc->DrawGeometry(svg.Get(), brush.Get()); surface3.end_draw(); } viman.add_visual(surface3, D2D1::Point2F(10.0f, 80.0f)); // Add some elipses on top. for (int ix = 0; ix != 5; ++ix) { viman.add_visual(surface1, D2D1::Point2F(125.0f * ix, 45.0f * ix)); } viman.commit(); HACCEL accel_table = ::LoadAccelerators(instance, MAKEINTRESOURCE(IDC_VTESTS)); MSG msg; while (::GetMessage(&msg, NULL, 0, 0)) { if (!::TranslateAccelerator(msg.hwnd, accel_table, &msg)) { ::TranslateMessage(&msg); ::DispatchMessage(&msg); } } return (int) msg.wParam; } catch (plx::Exception& ex) { ex; __debugbreak(); return -1; } }