int main(int argc, char ** argv ) { SDL_Event ev; atexit(cleanup); init(); render_pattern(); while(1) { /* Check for events */ while(SDL_PollEvent(&ev)) { switch(ev.type) { case SDL_QUIT: exit(0); break; case SDL_KEYUP: if(ev.key.keysym.sym == SDLK_F12) return 0; break; } } do_frame(); SDL_Flip(screen); // shouldn't really need to do this SDL_Delay(20); } return 0; }
void cairo_renderer<T>::process(polygon_pattern_symbolizer const& sym, mapnik::feature_impl & feature, proj_transform const& prj_trans) { composite_mode_e comp_op = get<composite_mode_e, keys::comp_op>(sym, feature, common_.vars_); std::string filename = get<std::string, keys::file>(sym, feature, common_.vars_); value_bool clip = get<value_bool, keys::clip>(sym, feature, common_.vars_); value_double simplify_tolerance = get<value_double, keys::simplify_tolerance>(sym, feature, common_.vars_); value_double smooth = get<value_double, keys::smooth>(sym, feature, common_.vars_); value_double opacity = get<value_double, keys::opacity>(sym, feature, common_.vars_); agg::trans_affine image_tr = agg::trans_affine_scaling(common_.scale_factor_); auto image_transform = get_optional<transform_type>(sym, keys::image_transform); if (image_transform) evaluate_transform(image_tr, feature, common_.vars_, *image_transform); cairo_save_restore guard(context_); context_.set_operator(comp_op); boost::optional<mapnik::marker_ptr> marker = mapnik::marker_cache::instance().find(filename,true); if (!marker || !(*marker)) return; unsigned offset_x=0; unsigned offset_y=0; box2d<double> const& clip_box = clipping_extent(common_); pattern_alignment_enum alignment = get<pattern_alignment_enum, keys::alignment>(sym, feature, common_.vars_); if (alignment == LOCAL_ALIGNMENT) { double x0 = 0.0; double y0 = 0.0; if (feature.num_geometries() > 0) { using clipped_geometry_type = agg::conv_clip_polygon<geometry_type>; using path_type = transform_path_adapter<view_transform,clipped_geometry_type>; clipped_geometry_type clipped(feature.get_geometry(0)); clipped.clip_box(clip_box.minx(), clip_box.miny(), clip_box.maxx(), clip_box.maxy()); path_type path(common_.t_, clipped, prj_trans); path.vertex(&x0, &y0); } offset_x = std::abs(clip_box.width() - x0); offset_y = std::abs(clip_box.height() - y0); } if ((*marker)->is_bitmap()) { cairo_pattern pattern(**((*marker)->get_bitmap_data()), opacity); pattern.set_extend(CAIRO_EXTEND_REPEAT); pattern.set_origin(offset_x, offset_y); context_.set_pattern(pattern); } else { mapnik::rasterizer ras; image_ptr image = render_pattern(ras, **marker, image_tr, 1.0); // cairo_pattern pattern(*image, opacity); pattern.set_extend(CAIRO_EXTEND_REPEAT); pattern.set_origin(offset_x, offset_y); context_.set_pattern(pattern); } agg::trans_affine tr; auto geom_transform = get_optional<transform_type>(sym, keys::geometry_transform); if (geom_transform) { evaluate_transform(tr, feature, common_.vars_, *geom_transform, common_.scale_factor_); } vertex_converter<cairo_context,clip_poly_tag,transform_tag,affine_transform_tag,simplify_tag,smooth_tag> converter(clip_box, context_,sym,common_.t_,prj_trans,tr,feature,common_.vars_,common_.scale_factor_); if (prj_trans.equal() && clip) converter.set<clip_poly_tag>(); //optional clip (default: true) converter.set<transform_tag>(); //always transform converter.set<affine_transform_tag>(); if (simplify_tolerance > 0.0) converter.set<simplify_tag>(); // optional simplify converter if (smooth > 0.0) converter.set<smooth_tag>(); // optional smooth converter for ( geometry_type & geom : feature.paths()) { if (geom.size() > 2) { converter.apply(geom); } } // fill polygon context_.set_fill_rule(CAIRO_FILL_RULE_EVEN_ODD); context_.fill(); }
void agg_renderer<T0,T1>::process(line_pattern_symbolizer const& sym, mapnik::feature_impl & feature, proj_transform const& prj_trans) { using color = agg::rgba8; using order = agg::order_rgba; using blender_type = agg::comp_op_adaptor_rgba_pre<color, order>; using pattern_filter_type = agg::pattern_filter_bilinear_rgba8; using pattern_type = agg::line_image_pattern<pattern_filter_type>; using pixfmt_type = agg::pixfmt_custom_blend_rgba<blender_type, agg::rendering_buffer>; using renderer_base = agg::renderer_base<pixfmt_type>; using renderer_type = agg::renderer_outline_image<renderer_base, pattern_type>; using rasterizer_type = agg::rasterizer_outline_aa<renderer_type>; std::string filename = get<std::string>(sym, keys::file, feature, common_.vars_); if (filename.empty()) return; boost::optional<mapnik::marker_ptr> marker_ptr = marker_cache::instance().find(filename, true); if (!marker_ptr || !(*marker_ptr)) return; boost::optional<image_ptr> pat; // TODO - re-implement at renderer level like polygon_pattern symbolizer double opacity = get<value_double>(sym, keys::opacity, feature, common_.vars_,1.0); if ((*marker_ptr)->is_bitmap()) { pat = (*marker_ptr)->get_bitmap_data(); } else { agg::trans_affine image_tr = agg::trans_affine_scaling(common_.scale_factor_); auto image_transform = get_optional<transform_type>(sym, keys::image_transform); if (image_transform) evaluate_transform(image_tr, feature, common_.vars_, *image_transform); pat = render_pattern(*ras_ptr, **marker_ptr, image_tr, 1.0); } if (!pat) return; bool clip = get<value_bool>(sym, keys::clip, feature, common_.vars_, false); double offset = get<value_double>(sym, keys::offset, feature, common_.vars_, 0.0); double simplify_tolerance = get<value_double>(sym, keys::simplify_tolerance, feature, common_.vars_, 0.0); double smooth = get<value_double>(sym, keys::smooth, feature, common_.vars_, false); agg::rendering_buffer buf(current_buffer_->raw_data(),current_buffer_->width(),current_buffer_->height(), current_buffer_->width() * 4); pixfmt_type pixf(buf); pixf.comp_op(static_cast<agg::comp_op_e>(get<composite_mode_e>(sym, keys::comp_op, feature, common_.vars_, src_over))); renderer_base ren_base(pixf); agg::pattern_filter_bilinear_rgba8 filter; pattern_source source(*(*pat), opacity); pattern_type pattern (filter,source); renderer_type ren(ren_base, pattern); rasterizer_type ras(ren); agg::trans_affine tr; auto transform = get_optional<transform_type>(sym, keys::geometry_transform); if (transform) evaluate_transform(tr, feature, common_.vars_, *transform, common_.scale_factor_); box2d<double> clip_box = clipping_extent(common_); if (clip) { double padding = (double)(common_.query_extent_.width()/pixmap_.width()); double half_stroke = (*marker_ptr)->width()/2.0; if (half_stroke > 1) padding *= half_stroke; if (std::fabs(offset) > 0) padding *= std::fabs(offset) * 1.2; padding *= common_.scale_factor_; clip_box.pad(padding); } using conv_types = boost::mpl::vector<clip_line_tag, transform_tag, affine_transform_tag, simplify_tag,smooth_tag, offset_transform_tag>; vertex_converter<box2d<double>, rasterizer_type, line_pattern_symbolizer, view_transform, proj_transform, agg::trans_affine, conv_types, feature_impl> converter(clip_box,ras,sym,common_.t_,prj_trans,tr,feature,common_.vars_,common_.scale_factor_); if (clip) converter.set<clip_line_tag>(); //optional clip (default: true) converter.set<transform_tag>(); //always transform if (simplify_tolerance > 0.0) converter.set<simplify_tag>(); // optional simplify converter if (std::fabs(offset) > 0.0) converter.set<offset_transform_tag>(); // parallel offset converter.set<affine_transform_tag>(); // optional affine transform if (smooth > 0.0) converter.set<smooth_tag>(); // optional smooth converter for (geometry_type & geom : feature.paths()) { if (geom.size() > 1) { converter.apply(geom); } } }
int main(int argc,char **argv) { WNDCLASS wnd; HRESULT hr; RECT rect; MSG msg; char *a; int i; for (i=1;i < argc;) { a = argv[i++]; if (*a == '-') { do { a++; } while (*a == '-'); if (!strcmp(a,"nodpiaware")) { gdi_no_dpiaware = true; } else if (!strcmp(a,"dpiaware")) { gdi_no_dpiaware = false; } else { fprintf(stderr,"Unhandled switch %s\n",a); return 1; } } else { fprintf(stderr,"Unhandled arg %s\n",a); return 1; } } if (sizeof(rgb24bpp_t) != 3) fprintf(stderr,"WARNING: uint24_t is not 3 bytes long, it is %u bytes\n",(unsigned int)sizeof(rgb24bpp_t)); /* Please don't scale me in the name of "DPI awareness" */ if (!gdi_no_dpiaware) win32_dpi_aware(); /* Bring up DirectX */ /* NTS: On multi-monitor setups, this will create an "emulated" object. Hardware accel won't be possible unless we enum monitors. */ if ((hr=DirectDrawCreate(NULL,&ddraw1,NULL)) != DD_OK) { fprintf(stderr,"DirectDrawCreate failed, HRESULT=0x%08lx\n",hr); return 1; } if ((hr=ddraw1->QueryInterface(IID_IDirectDraw2,(void**)(&ddraw))) != S_OK) { fprintf(stderr,"Unable to query IDirectDraw2 from IDirectDraw, HR=0x%08lx\n",hr); return 1; } ddraw1->Release(); ddraw1 = NULL; if ((hr=ddraw->SetCooperativeLevel(hwndMain,ddrawCooperativeLevel=DDSCL_NORMAL)) != DD_OK) { fprintf(stderr,"Unable to ask for Normal cooperative mode, HR=0x%08lx\n",hr); return 1; } myInstance = GetModuleHandle(NULL); memset(&wnd,0,sizeof(wnd)); wnd.lpfnWndProc = WndProc; wnd.hInstance = myInstance; wnd.lpszClassName = hwndMainClass; wnd.hCursor = LoadCursor(NULL,IDC_ARROW); if (!RegisterClass(&wnd)) { fprintf(stderr,"RegisterClass() failed\n"); return 1; } rect.top = 0; rect.left = 0; rect.right = 640; rect.bottom = 480; AdjustWindowRect(&rect,WS_OVERLAPPEDWINDOW,FALSE); hwndMain = CreateWindow(hwndMainClass,hwndMainTitle, hwndMainStyle=WS_OVERLAPPEDWINDOW, CW_USEDEFAULT,CW_USEDEFAULT, rect.right - rect.left,rect.bottom - rect.top, NULL,NULL, myInstance,NULL); if (!hwndMain) { fprintf(stderr,"CreateWindow() failed\n"); return 1; } if (!init_dx_primary_surface()) { fprintf(stderr,"Failed to init primary surface\n"); return 1; } GetClientRect(hwndMain,&rect); if (!init_bitmap(rect.right,rect.bottom)) { fprintf(stderr,"nit_bitmap() failed for %ux%u\n",(unsigned int)rect.right,(unsigned int)rect.bottom); return 1; } if (lock_bitmap()) { render_pattern(dx_bitmap); unlock_bitmap(); } ShowWindow(hwndMain,SW_SHOW); UpdateWindow(hwndMain); while (GetMessage(&msg,NULL,0,0)) { TranslateMessage(&msg); DispatchMessage(&msg); } free_dx_primary_surface(); free_bitmap(); if (ddraw != NULL) { ddraw->RestoreDisplayMode(); ddraw->Release(); ddraw = NULL; } if (menuDisplayModes != NULL) { DestroyMenu(menuDisplayModes); menuDisplayModes = NULL; } return 0; }
static LRESULT CALLBACK WndProc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam) { switch (uMsg) { case WM_CREATE: break; case WM_PAINT: { PAINTSTRUCT ps; BeginPaint(hwnd,&ps); EndPaint(hwnd,&ps); if (ddsurfacePrimary == NULL) { unlock_bitmap(); free_bitmap(); free_dx_primary_surface(); init_dx_primary_surface(); RECT rct; GetClientRect(hwndMain,&rct); if (!init_bitmap(rct.right,rct.bottom)) fprintf(stderr,"WARNING WM_RESIZE init_bitmap(%u,%u) failed\n", (unsigned int)rct.right,(unsigned int)rct.bottom); if (lock_bitmap()) { render_pattern(dx_bitmap); unlock_bitmap(); } } update_screen(); } break; case WM_DISPLAYCHANGE: { announce_fmt = true; unlock_bitmap(); free_bitmap(); free_dx_primary_surface(); init_dx_primary_surface(); RECT rct; GetClientRect(hwndMain,&rct); if (!init_bitmap(rct.right,rct.bottom)) fprintf(stderr,"WARNING WM_RESIZE init_bitmap(%u,%u) failed\n", (unsigned int)rct.right,(unsigned int)rct.bottom); if (lock_bitmap()) { render_pattern(dx_bitmap); unlock_bitmap(); } InvalidateRect(hwndMain,NULL,FALSE); // DWM compositor-based versions set WM_PAINT such that only the affected area will repaint } return DefWindowProc(hwnd,uMsg,wParam,lParam); case WM_SIZE: if (!init_bitmap(LOWORD(lParam),HIWORD(lParam))) fprintf(stderr,"WARNING WM_RESIZE init_bitmap(%u,%u) failed\n", LOWORD(lParam),HIWORD(lParam)); if (lock_bitmap()) { render_pattern(dx_bitmap); unlock_bitmap(); } InvalidateRect(hwndMain,NULL,FALSE); // DWM compositor-based versions set WM_PAINT such that only the affected area will repaint break; case WM_RBUTTONUP: populateDisplayModes(); if (menuDisplayModes != NULL) { POINT pt; GetCursorPos(&pt); TrackPopupMenu(menuDisplayModes,TPM_LEFTALIGN|TPM_TOPALIGN|TPM_RIGHTBUTTON,pt.x,pt.y,0,hwnd,NULL); } break; case WM_COMMAND: if (wParam >= 4000 && wParam < (WPARAM)(4000+displayModesCount)) { DDSURFACEDESC devmode = displayModes[wParam-4000]; HRESULT hr; fprintf(stderr,"Setting display to %u x %u x %ubpp\n", (unsigned int)devmode.dwWidth, (unsigned int)devmode.dwHeight, (unsigned int)devmode.ddpfPixelFormat.dwRGBBitCount); if ((hr=ddraw->SetDisplayMode(devmode.dwWidth,devmode.dwHeight,devmode.ddpfPixelFormat.dwRGBBitCount,devmode.dwRefreshRate,0)) != DD_OK) fprintf(stderr,"Failed to set display mode HR=0x%08lx\n",hr); if (hr == DDERR_NOEXCLUSIVEMODE) { // NTS: Windows 95/98/ME DirectX demands we enter Exclusive cooperative mode before it allows mode changes that change bit depth fprintf(stderr,"Sorry, Windows demands we set the cooperative mode to Exclusive\n"); // Windows 9x/ME behavior for NORMAL cooperative mode DirectX apps try_exclusive_mode(); if ((hr=ddraw->SetDisplayMode(devmode.dwWidth,devmode.dwHeight,devmode.ddpfPixelFormat.dwRGBBitCount,devmode.dwRefreshRate,0)) != DD_OK) fprintf(stderr,"Failed to set display mode HR=0x%08lx\n",hr); } if (hr == DD_OK) { if (is_exclusive_mode()) { // NTS: When we're in Exclusive Fullscreen mode, Windows doesn't broadcast WM_DISPLAYCHANGE or WM_PAINT the way it normally does while we're active. // So for our display code to work we have to poke and prod the window manager and make our window fullscreen, with focus. unlock_bitmap(); free_bitmap(); free_dx_primary_surface(); init_dx_primary_surface(); RECT rct; GetClientRect(hwndMain,&rct); if (!init_bitmap(rct.right,rct.bottom)) fprintf(stderr,"WARNING WM_RESIZE init_bitmap(%u,%u) failed\n", (unsigned int)rct.right,(unsigned int)rct.bottom); if (lock_bitmap()) { render_pattern(dx_bitmap); unlock_bitmap(); } InvalidateRect(hwndMain,NULL,FALSE); // DWM compositor-based versions set WM_PAINT such that only the affected area will repaint try_exclusive_mode(); } hasSetMode = true; } } else if (wParam == 5000) { try_exclusive_mode(); update_screen(); } else if (wParam == 5001) { leave_exclusive_mode(); } else if (wParam == 5002) { leave_exclusive_mode(); ddraw->RestoreDisplayMode(); } else { return DefWindowProc(hwnd,uMsg,wParam,lParam); } break; case WM_KEYDOWN: switch (wParam) { case VK_ESCAPE: PostMessage(hwnd,WM_CLOSE,0,0); break; case VK_SPACE: if ((++pattern) >= 2) pattern = 0; if (lock_bitmap()) { render_pattern(dx_bitmap); unlock_bitmap(); } InvalidateRect(hwndMain,NULL,FALSE); // DWM compositor-based versions set WM_PAINT such that only the affected area will repaint break; } break; case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hwnd,uMsg,wParam,lParam); } return 0; }
void update_screen() { IDirectDrawSurface *dst; RECT dstRect; RECT srcRect; HRESULT hr; POINT pt; // NTS: dx_bitmap.is_valid() is not a valid test because base==canvas==NULL unless surface is locked if (ddsurfaceBMP == NULL) return; // NTS: We must provide a source rect, else Windows XP in 24bpp mode will conveniently choose to render the // right half (where extra padding+junk exist) rather than from the left side. Provide a source rect // to make it 100% clear which part of the surface we want blitted to screen. pt.x = pt.y = 0; ClientToScreen(hwndMain,&pt); GetClientRect(hwndMain,&dstRect); OffsetRect(&dstRect,pt.x,pt.y); srcRect.top = srcRect.left = 0; srcRect.right = dx_bitmap.width; srcRect.bottom = dx_bitmap.height; if (ddsurfaceGDI != NULL) dst = ddsurfaceGDI; else if (ddsurfacePrimary != NULL) dst = ddsurfacePrimary; else dst = NULL; if (dst != NULL) hr = dst->Blt(&dstRect,ddsurfaceBMP,&srcRect,0,NULL); else hr = DD_OK; if (hr == DDERR_SURFACELOST) { fprintf(stderr,"Whoops, the primary surface was lost.\n"); if ((hr=dst->Restore()) != DD_OK) { fprintf(stderr,"Unable to restore surface hr=0x%08lx.\n",hr); unlock_bitmap(); free_bitmap(); free_dx_primary_surface(); init_dx_primary_surface(); RECT rct; GetClientRect(hwndMain,&rct); if (!init_bitmap(rct.right,rct.bottom)) fprintf(stderr,"WARNING WM_RESIZE init_bitmap(%u,%u) failed\n", (unsigned int)rct.right,(unsigned int)rct.bottom); if (lock_bitmap()) { render_pattern(dx_bitmap); unlock_bitmap(); } InvalidateRect(hwndMain,NULL,FALSE); // DWM compositor-based versions set WM_PAINT such that only the affected area will repaint } } else if (hr != DD_OK) { fprintf(stderr,"DirectX blit failed, HR=0x%08lx\n",hr); } }