FX_BOOL CGdiPrinterDriver::SetDIBits(const CFX_DIBSource* pSource, FX_DWORD color, const FX_RECT* pSrcRect, int left, int top, int blend_type, int alpha_flag, void* pIccTransform) { if (pSource->IsAlphaMask()) { FX_RECT clip_rect(left, top, left + pSrcRect->Width(), top + pSrcRect->Height()); return StretchDIBits(pSource, color, left - pSrcRect->left, top - pSrcRect->top, pSource->GetWidth(), pSource->GetHeight(), &clip_rect, 0, alpha_flag, pIccTransform, FXDIB_BLEND_NORMAL); } ASSERT(pSource != NULL && !pSource->IsAlphaMask() && pSrcRect != NULL); ASSERT(blend_type == FXDIB_BLEND_NORMAL); if (pSource->HasAlpha()) { return FALSE; } CFX_DIBExtractor temp(pSource); CFX_DIBitmap* pBitmap = temp; if (pBitmap == NULL) { return FALSE; } return GDI_SetDIBits(pBitmap, pSrcRect, left, top, pIccTransform); }
void mr_DrawRect(int16 sx, int16 sy, int16 w, int16 h, uint8 cr, uint8 cg, uint8 cb) { uint16 c = MAKERGB(cr, cg, cb); int32 sw, sh; int x, y, r, b, x1, y1, i, j; uint16 * p = w_getScreenBuffer(); mr_getScreenSize(&sw, &sh); x = sx, y = sy, r = sw-1, b = sh-1; x1 = sx+w-1, y1 = sy+h-1; if(clip_rect(&x, &y, &x1, &y1, r, b)) return; h = y1-y+1; w = x1-x+1; for (i=y; i<=y1; i++){ for(j=x; j<=x1; j++) *(p + i*sw + j) = c; } if(showApiLog) LOGI("mr_DrawRect(x:%d, y:%d, w:%d, h:%d)", x, y, w, h); }
void CPDF_RenderStatus::RenderObjectList( const CPDF_PageObjectHolder* pObjectHolder, const CFX_Matrix* pObj2Device) { #if defined _SKIA_SUPPORT_ DebugVerifyDeviceIsPreMultiplied(); #endif CFX_FloatRect clip_rect(m_pDevice->GetClipBox()); CFX_Matrix device2object; device2object.SetReverse(*pObj2Device); device2object.TransformRect(clip_rect); for (const auto& pCurObj : *pObjectHolder->GetPageObjectList()) { if (pCurObj.get() == m_pStopObj) { m_bStopped = TRUE; return; } if (!pCurObj) continue; if (pCurObj->m_Left > clip_rect.right || pCurObj->m_Right < clip_rect.left || pCurObj->m_Bottom > clip_rect.top || pCurObj->m_Top < clip_rect.bottom) { continue; } RenderSingleObject(pCurObj.get(), pObj2Device); if (m_bStopped) return; } #if defined _SKIA_SUPPORT_ DebugVerifyDeviceIsPreMultiplied(); #endif }
void menu::draw() { if(hidden()) { return; } /* if(!dirty()) { for(std::set<int>::const_iterator i = invalid_.begin(); i != invalid_.end(); ++i) { if(*i == -1) { SDL_Rect heading_rect = inner_location(); heading_rect.h = heading_height(); bg_restore(heading_rect); style_->draw_row(*this,0,heading_rect,HEADING_ROW); //update_rect(heading_rect); } else if(*i >= 0 && *i < int(item_pos_.size())) { const unsigned int pos = item_pos_[*i]; const SDL_Rect& rect = get_item_rect(*i); bg_restore(rect); style_->draw_row(*this,pos,rect, (!out_ && pos == selected_) ? SELECTED_ROW : NORMAL_ROW); //update_rect(rect); } } invalid_.clear(); return; } */ invalid_.clear(); bg_restore(); util::scoped_ptr<clip_rect_setter> clipper(NULL); if(clip_rect()) clipper.assign(new clip_rect_setter(/*video().getSurface(),*/ *clip_rect())); draw_contents(); // update_rect(location()); set_dirty(false); }
void MyCEGUIGeometryBuffer::setClippingRegion(const Rect& region) { core::rectf clip_rect( region.d_left, region.d_top, region.d_right, region.d_bottom); if (m_ClipRect != clip_rect) { m_ClipRect = clip_rect; m_ClipRectChanged = true; } }
void combo_drag::handle_move(const SDL_MouseMotionEvent& event) { if (drag_ == PRESSED) { aquire_mouse_lock(); old_location_ = location(); drag_ = PRESSED_MOVE; } const int diff_x = event.x - mouse_x_; const int diff_y = event.y - mouse_y_; if (drag_ == PRESSED_MOVE && std::sqrt(static_cast<float>(diff_x*diff_x + diff_y*diff_y)) > MIN_DRAG_DISTANCE) { return; } drag_ = MOVED; SDL_Rect loc = old_location_; loc.x += diff_x; loc.y += diff_y; // Don't allow moving outside clip are if (clip_rect()) { const SDL_Rect *clip = clip_rect(); if (loc.x < clip->x) loc.x = clip->x; if (loc.x + loc.w > clip->x + clip->w) loc.x = clip->x + clip->w - loc.w; if (loc.y < clip->y) loc.y = clip->y; if (loc.y + loc.h > clip->y + clip->h) loc.y = clip->y + clip->h - loc.h; } set_location(loc); }
void* get_path_iterator( PyObject* path, PyObject* trans, int remove_nans, int do_clip, double rect[4], e_snap_mode snap_mode, double stroke_width, int do_simplify) { agg::trans_affine agg_trans = py_to_agg_transformation_matrix(trans, false); agg::rect_base<double> clip_rect(rect[0], rect[1], rect[2], rect[3]); PathCleanupIterator* pipeline = new PathCleanupIterator( path, agg_trans, remove_nans != 0, do_clip != 0, clip_rect, snap_mode, stroke_width, do_simplify != 0); return (void*)pipeline; }
/* ======================================= 画方框 ======================================= */ CR_API void_t draw_rect ( __CR_IO__ const sIMAGE* dst, __CR_IN__ const sRECT* rect, __CR_IN__ cpix_t color, __CR_IN__ pixdraw_t pixel_draw ) { sRECT clip; sint_t xx, yy; /* 剪裁 */ if (!clip_rect(&clip, rect, &dst->clip_win)) return; /* 上边 */ if (rect->y1 == clip.y1) { yy = clip.y1; for (xx = clip.x1; xx <= clip.x2; xx++) pixel_draw(dst, xx, yy, color); } /* 右边 */ if (rect->x2 == clip.x2) { xx = clip.x2; for (yy = clip.y1; yy <= clip.y2; yy++) pixel_draw(dst, xx, yy, color); } /* 下边 */ if (rect->y2 == clip.y2) { yy = clip.y2; for (xx = clip.x1; xx <= clip.x2; xx++) pixel_draw(dst, xx, yy, color); } /* 左边 */ if (rect->x1 == clip.x1) { xx = clip.x1; for (yy = clip.y1; yy <= clip.y2; yy++) pixel_draw(dst, xx, yy, color); } }
CFX_DIBitmap* CFX_DIBSource::StretchTo(int dest_width, int dest_height, FX_DWORD flags, const FX_RECT* pClip) const { FX_RECT clip_rect(0, 0, FXSYS_abs(dest_width), FXSYS_abs(dest_height)); if (pClip) { clip_rect.Intersect(*pClip); } if (clip_rect.IsEmpty()) { return NULL; } if (dest_width == m_Width && dest_height == m_Height) { return Clone(&clip_rect); } CFX_ImageStretcher stretcher; CFX_BitmapStorer storer; if (stretcher.Start(&storer, this, dest_width, dest_height, clip_rect, flags)) { stretcher.Continue(NULL); } return storer.Detach(); }
void rect_draw(V4i r, u8 color) { rect_tr(&r, PROGRAM->tx, PROGRAM->ty); clip_rect(&r, &PROGRAM->bitmap_rect); if (r.max_x != r.min_x && r.max_y != r.min_y) { // i32 row_pitch = PROGRAM->bitmap_rect.max_x - PROGRAM->bitmap_rect.min_x; // u8 *row = PROGRAM->bitmap->data + r.min_x + (r.min_y * row_pitch); u8 *row = PROGRAM->bitmap->data + r.min_x + (r.min_y * PROGRAM->bitmap->w); i32 w = r.max_x - r.min_x; while (r.max_y != r.min_y) { memset(row, color, w); row += PROGRAM->bitmap->w; // row_pitch; r.max_y--; } } }
CFX_DIBitmap* CFX_DIBSource::StretchTo(int dest_width, int dest_height, uint32_t flags, const FX_RECT* pClip) const { FX_RECT clip_rect(0, 0, FXSYS_abs(dest_width), FXSYS_abs(dest_height)); if (pClip) clip_rect.Intersect(*pClip); if (clip_rect.IsEmpty()) return nullptr; if (dest_width == m_Width && dest_height == m_Height) return Clone(&clip_rect); CFX_BitmapStorer storer; CFX_ImageStretcher stretcher(&storer, this, dest_width, dest_height, clip_rect, flags); if (stretcher.Start()) stretcher.Continue(nullptr); return storer.Detach().release(); }
void TileSelector::drawContents(Renderer2D &out) const { int2 offset = innerOffset(); IRect clip_rect(int2(0, 0), clippedRect().size()); for(int n = 0; n < (int)m_tile_list.size(); n++) { const Tile *tile = m_tile_list[n].tile; IRect tile_rect = tile->rect(); int2 pos = m_tile_list[n].pos - tile_rect.min - offset; if(areOverlapping(clip_rect, tile_rect + pos)) tile->draw(out, pos); } if(m_selection) { int2 pos = m_selection->pos - offset; out.setViewPos(-clippedRect().min - pos + m_selection->tile->rect().min); IBox box(int3(0, 0, 0), m_selection->tile->bboxSize()); drawBBox(out, box); // out.addFilledRect(IRect(pos, pos + m_selection->size)); } }
void VisualServerViewport::_draw_viewport(Viewport *p_viewport) { /* Camera should always be BEFORE any other 3D */ #if 0 bool scenario_draw_canvas_bg=false; int scenario_canvas_max_layer=0; if (!p_viewport->hide_canvas && !p_viewport->disable_environment && scenario_owner.owns(p_viewport->scenario)) { Scenario *scenario=scenario_owner.get(p_viewport->scenario); if (scenario->environment.is_valid()) { if (rasterizer->is_environment(scenario->environment)) { scenario_draw_canvas_bg=rasterizer->environment_get_background(scenario->environment)==VS::ENV_BG_CANVAS; scenario_canvas_max_layer=rasterizer->environment_get_background_param(scenario->environment,VS::ENV_BG_PARAM_CANVAS_MAX_LAYER); } } } bool can_draw_3d=!p_viewport->hide_scenario && camera_owner.owns(p_viewport->camera) && scenario_owner.owns(p_viewport->scenario); if (scenario_draw_canvas_bg) { rasterizer->begin_canvas_bg(); } if (!scenario_draw_canvas_bg && can_draw_3d) { _draw_viewport_camera(p_viewport,false); } else if (true /*|| !p_viewport->canvas_list.empty()*/){ //clear the viewport black because of no camera? i seriously should.. if (p_viewport->render_target_clear_on_new_frame || p_viewport->render_target_clear) { if (p_viewport->transparent_bg) { rasterizer->clear_viewport(Color(0,0,0,0)); } else { Color cc=clear_color; if (scenario_draw_canvas_bg) cc.a=0; rasterizer->clear_viewport(cc); } p_viewport->render_target_clear=false; } } #endif if (p_viewport->clear_mode != VS::VIEWPORT_CLEAR_NEVER) { VSG::rasterizer->clear_render_target(clear_color); if (p_viewport->clear_mode == VS::VIEWPORT_CLEAR_ONLY_NEXT_FRAME) { p_viewport->clear_mode = VS::VIEWPORT_CLEAR_NEVER; } } if (!p_viewport->disable_3d && p_viewport->camera.is_valid()) { VSG::scene->render_camera(p_viewport->camera, p_viewport->scenario, p_viewport->size, p_viewport->shadow_atlas); } if (!p_viewport->hide_canvas) { int i = 0; Map<Viewport::CanvasKey, Viewport::CanvasData *> canvas_map; Rect2 clip_rect(0, 0, p_viewport->size.x, p_viewport->size.y); RasterizerCanvas::Light *lights = NULL; RasterizerCanvas::Light *lights_with_shadow = NULL; RasterizerCanvas::Light *lights_with_mask = NULL; Rect2 shadow_rect; int light_count = 0; for (Map<RID, Viewport::CanvasData>::Element *E = p_viewport->canvas_map.front(); E; E = E->next()) { Transform2D xf = p_viewport->global_transform * E->get().transform; VisualServerCanvas::Canvas *canvas = static_cast<VisualServerCanvas::Canvas *>(E->get().canvas); //find lights in canvas for (Set<RasterizerCanvas::Light *>::Element *F = canvas->lights.front(); F; F = F->next()) { RasterizerCanvas::Light *cl = F->get(); if (cl->enabled && cl->texture.is_valid()) { //not super efficient.. Size2 tsize(VSG::storage->texture_get_width(cl->texture), VSG::storage->texture_get_height(cl->texture)); tsize *= cl->scale; Vector2 offset = tsize / 2.0; cl->rect_cache = Rect2(-offset + cl->texture_offset, tsize); cl->xform_cache = xf * cl->xform; if (clip_rect.intersects_transformed(cl->xform_cache, cl->rect_cache)) { cl->filter_next_ptr = lights; lights = cl; cl->texture_cache = NULL; Transform2D scale; scale.scale(cl->rect_cache.size); scale.elements[2] = cl->rect_cache.pos; cl->light_shader_xform = (cl->xform_cache * scale).affine_inverse(); cl->light_shader_pos = cl->xform_cache[2]; if (cl->shadow_buffer.is_valid()) { cl->shadows_next_ptr = lights_with_shadow; if (lights_with_shadow == NULL) { shadow_rect = cl->xform_cache.xform(cl->rect_cache); } else { shadow_rect = shadow_rect.merge(cl->xform_cache.xform(cl->rect_cache)); } lights_with_shadow = cl; cl->radius_cache = cl->rect_cache.size.length(); } if (cl->mode == VS::CANVAS_LIGHT_MODE_MASK) { cl->mask_next_ptr = lights_with_mask; lights_with_mask = cl; } light_count++; } VSG::canvas_render->light_internal_update(cl->light_internal, cl); } } //print_line("lights: "+itos(light_count)); canvas_map[Viewport::CanvasKey(E->key(), E->get().layer)] = &E->get(); } if (lights_with_shadow) { //update shadows if any RasterizerCanvas::LightOccluderInstance *occluders = NULL; //make list of occluders for (Map<RID, Viewport::CanvasData>::Element *E = p_viewport->canvas_map.front(); E; E = E->next()) { VisualServerCanvas::Canvas *canvas = static_cast<VisualServerCanvas::Canvas *>(E->get().canvas); Transform2D xf = p_viewport->global_transform * E->get().transform; for (Set<RasterizerCanvas::LightOccluderInstance *>::Element *F = canvas->occluders.front(); F; F = F->next()) { if (!F->get()->enabled) continue; F->get()->xform_cache = xf * F->get()->xform; if (shadow_rect.intersects_transformed(F->get()->xform_cache, F->get()->aabb_cache)) { F->get()->next = occluders; occluders = F->get(); } } } //update the light shadowmaps with them RasterizerCanvas::Light *light = lights_with_shadow; while (light) { VSG::canvas_render->canvas_light_shadow_buffer_update(light->shadow_buffer, light->xform_cache.affine_inverse(), light->item_mask, light->radius_cache / 1000.0, light->radius_cache * 1.1, occluders, &light->shadow_matrix_cache); light = light->shadows_next_ptr; } //VSG::canvas_render->reset_canvas(); } VSG::rasterizer->restore_render_target(); #if 0 if (scenario_draw_canvas_bg && canvas_map.front() && canvas_map.front()->key().layer>scenario_canvas_max_layer) { _draw_viewport_camera(p_viewport,!can_draw_3d); scenario_draw_canvas_bg=false; } #endif for (Map<Viewport::CanvasKey, Viewport::CanvasData *>::Element *E = canvas_map.front(); E; E = E->next()) { VisualServerCanvas::Canvas *canvas = static_cast<VisualServerCanvas::Canvas *>(E->get()->canvas); //print_line("canvas "+itos(i)+" size: "+itos(I->get()->canvas->child_items.size())); //print_line("GT "+p_viewport->global_transform+". CT: "+E->get()->transform); Transform2D xform = p_viewport->global_transform * E->get()->transform; RasterizerCanvas::Light *canvas_lights = NULL; RasterizerCanvas::Light *ptr = lights; while (ptr) { if (E->get()->layer >= ptr->layer_min && E->get()->layer <= ptr->layer_max) { ptr->next_ptr = canvas_lights; canvas_lights = ptr; } ptr = ptr->filter_next_ptr; } VSG::canvas->render_canvas(canvas, xform, canvas_lights, lights_with_mask, clip_rect); i++; #if 0 if (scenario_draw_canvas_bg && E->key().layer>=scenario_canvas_max_layer) { _draw_viewport_camera(p_viewport,!can_draw_3d); scenario_draw_canvas_bg=false; } #endif } #if 0 if (scenario_draw_canvas_bg) { _draw_viewport_camera(p_viewport,!can_draw_3d); scenario_draw_canvas_bg=false; } #endif //VSG::canvas_render->canvas_debug_viewport_shadows(lights_with_shadow); } }
Py::Object _path_module::convert_to_svg(const Py::Tuple& args) { args.verify_length(5); PathIterator path(args[0]); agg::trans_affine trans = py_to_agg_transformation_matrix(args[1].ptr(), false); Py::Object clip_obj = args[2]; bool do_clip; agg::rect_base<double> clip_rect(0, 0, 0, 0); if (clip_obj.isNone() || !clip_obj.isTrue()) { do_clip = false; } else { double x1, y1, x2, y2; Py::Tuple clip_tuple(clip_obj); x1 = Py::Float(clip_tuple[0]); y1 = Py::Float(clip_tuple[1]); x2 = Py::Float(clip_tuple[2]); y2 = Py::Float(clip_tuple[3]); clip_rect.init(x1, y1, x2, y2); do_clip = true; } bool simplify; Py::Object simplify_obj = args[3]; if (simplify_obj.isNone()) { simplify = path.should_simplify(); } else { simplify = simplify_obj.isTrue(); } int precision = Py::Int(args[4]); #if PY_VERSION_HEX < 0x02070000 char format[64]; snprintf(format, 64, "%s.%dg", "%", precision); #endif typedef agg::conv_transform<PathIterator> transformed_path_t; typedef PathNanRemover<transformed_path_t> nan_removal_t; typedef PathClipper<nan_removal_t> clipped_t; typedef PathSimplifier<clipped_t> simplify_t; transformed_path_t tpath(path, trans); nan_removal_t nan_removed(tpath, true, path.has_curves()); clipped_t clipped(nan_removed, do_clip, clip_rect); simplify_t simplified(clipped, simplify, path.simplify_threshold()); size_t buffersize = path.total_vertices() * (precision + 5) * 4; char* buffer = (char *)malloc(buffersize); char* p = buffer; const char codes[] = {'M', 'L', 'Q', 'C'}; const int waits[] = { 1, 1, 2, 3}; int wait = 0; unsigned code; double x = 0, y = 0; while ((code = simplified.vertex(&x, &y)) != agg::path_cmd_stop) { if (wait == 0) { *p++ = '\n'; if (code == 0x4f) { *p++ = 'z'; *p++ = '\n'; continue; } *p++ = codes[code-1]; wait = waits[code-1]; } else { *p++ = ' '; } #if PY_VERSION_HEX >= 0x02070000 char* str; str = PyOS_double_to_string(x, 'g', precision, 0, NULL); p += snprintf(p, buffersize - (p - buffer), str); PyMem_Free(str); *p++ = ' '; str = PyOS_double_to_string(y, 'g', precision, 0, NULL); p += snprintf(p, buffersize - (p - buffer), str); PyMem_Free(str); #else char str[64]; PyOS_ascii_formatd(str, 64, format, x); p += snprintf(p, buffersize - (p - buffer), str); *p++ = ' '; PyOS_ascii_formatd(str, 64, format, y); p += snprintf(p, buffersize - (p - buffer), str); #endif --wait; } #if PY3K PyObject* result = PyUnicode_FromStringAndSize(buffer, p - buffer); #else PyObject* result = PyString_FromStringAndSize(buffer, p - buffer); #endif free(buffer); return Py::Object(result, true); }
void VisualServerViewport::_draw_viewport(Viewport *p_viewport, ARVRInterface::Eyes p_eye) { /* Camera should always be BEFORE any other 3D */ bool scenario_draw_canvas_bg = false; //draw canvas, or some layer of it, as BG for 3D instead of in front int scenario_canvas_max_layer = 0; if (!p_viewport->hide_canvas && !p_viewport->disable_environment && VSG::scene->scenario_owner.owns(p_viewport->scenario)) { VisualServerScene::Scenario *scenario = VSG::scene->scenario_owner.get(p_viewport->scenario); if (VSG::scene_render->is_environment(scenario->environment)) { scenario_draw_canvas_bg = VSG::scene_render->environment_get_background(scenario->environment) == VS::ENV_BG_CANVAS; scenario_canvas_max_layer = VSG::scene_render->environment_get_canvas_max_layer(scenario->environment); } } bool can_draw_3d = !p_viewport->disable_3d && !p_viewport->disable_3d_by_usage && VSG::scene->camera_owner.owns(p_viewport->camera); if (p_viewport->clear_mode != VS::VIEWPORT_CLEAR_NEVER) { VSG::rasterizer->clear_render_target(clear_color); if (p_viewport->clear_mode == VS::VIEWPORT_CLEAR_ONLY_NEXT_FRAME) { p_viewport->clear_mode = VS::VIEWPORT_CLEAR_NEVER; } } if (!scenario_draw_canvas_bg && can_draw_3d) { Ref<ARVRInterface> arvr_interface = ARVRServer::get_singleton()->get_primary_interface(); if (p_viewport->use_arvr && arvr_interface.is_valid()) { VSG::scene->render_camera(arvr_interface, p_eye, p_viewport->camera, p_viewport->scenario, p_viewport->size, p_viewport->shadow_atlas); } else { VSG::scene->render_camera(p_viewport->camera, p_viewport->scenario, p_viewport->size, p_viewport->shadow_atlas); } } if (!p_viewport->hide_canvas) { int i = 0; Map<Viewport::CanvasKey, Viewport::CanvasData *> canvas_map; Rect2 clip_rect(0, 0, p_viewport->size.x, p_viewport->size.y); RasterizerCanvas::Light *lights = NULL; RasterizerCanvas::Light *lights_with_shadow = NULL; RasterizerCanvas::Light *lights_with_mask = NULL; Rect2 shadow_rect; int light_count = 0; for (Map<RID, Viewport::CanvasData>::Element *E = p_viewport->canvas_map.front(); E; E = E->next()) { Transform2D xf = p_viewport->global_transform * E->get().transform; VisualServerCanvas::Canvas *canvas = static_cast<VisualServerCanvas::Canvas *>(E->get().canvas); //find lights in canvas for (Set<RasterizerCanvas::Light *>::Element *F = canvas->lights.front(); F; F = F->next()) { RasterizerCanvas::Light *cl = F->get(); if (cl->enabled && cl->texture.is_valid()) { //not super efficient.. Size2 tsize(VSG::storage->texture_get_width(cl->texture), VSG::storage->texture_get_height(cl->texture)); tsize *= cl->scale; Vector2 offset = tsize / 2.0; cl->rect_cache = Rect2(-offset + cl->texture_offset, tsize); cl->xform_cache = xf * cl->xform; if (clip_rect.intersects_transformed(cl->xform_cache, cl->rect_cache)) { cl->filter_next_ptr = lights; lights = cl; cl->texture_cache = NULL; Transform2D scale; scale.scale(cl->rect_cache.size); scale.elements[2] = cl->rect_cache.position; cl->light_shader_xform = (cl->xform_cache * scale).affine_inverse(); cl->light_shader_pos = cl->xform_cache[2]; if (cl->shadow_buffer.is_valid()) { cl->shadows_next_ptr = lights_with_shadow; if (lights_with_shadow == NULL) { shadow_rect = cl->xform_cache.xform(cl->rect_cache); } else { shadow_rect = shadow_rect.merge(cl->xform_cache.xform(cl->rect_cache)); } lights_with_shadow = cl; cl->radius_cache = cl->rect_cache.size.length(); } if (cl->mode == VS::CANVAS_LIGHT_MODE_MASK) { cl->mask_next_ptr = lights_with_mask; lights_with_mask = cl; } light_count++; } VSG::canvas_render->light_internal_update(cl->light_internal, cl); } } //print_line("lights: "+itos(light_count)); canvas_map[Viewport::CanvasKey(E->key(), E->get().layer)] = &E->get(); } if (lights_with_shadow) { //update shadows if any RasterizerCanvas::LightOccluderInstance *occluders = NULL; //make list of occluders for (Map<RID, Viewport::CanvasData>::Element *E = p_viewport->canvas_map.front(); E; E = E->next()) { VisualServerCanvas::Canvas *canvas = static_cast<VisualServerCanvas::Canvas *>(E->get().canvas); Transform2D xf = p_viewport->global_transform * E->get().transform; for (Set<RasterizerCanvas::LightOccluderInstance *>::Element *F = canvas->occluders.front(); F; F = F->next()) { if (!F->get()->enabled) continue; F->get()->xform_cache = xf * F->get()->xform; if (shadow_rect.intersects_transformed(F->get()->xform_cache, F->get()->aabb_cache)) { F->get()->next = occluders; occluders = F->get(); } } } //update the light shadowmaps with them RasterizerCanvas::Light *light = lights_with_shadow; while (light) { VSG::canvas_render->canvas_light_shadow_buffer_update(light->shadow_buffer, light->xform_cache.affine_inverse(), light->item_mask, light->radius_cache / 1000.0, light->radius_cache * 1.1, occluders, &light->shadow_matrix_cache); light = light->shadows_next_ptr; } //VSG::canvas_render->reset_canvas(); } VSG::rasterizer->restore_render_target(); if (scenario_draw_canvas_bg && canvas_map.front() && canvas_map.front()->key().layer > scenario_canvas_max_layer) { if (can_draw_3d) { VSG::scene->render_camera(p_viewport->camera, p_viewport->scenario, p_viewport->size, p_viewport->shadow_atlas); } else { VSG::scene->render_empty_scene(p_viewport->scenario, p_viewport->shadow_atlas); } scenario_draw_canvas_bg = false; } for (Map<Viewport::CanvasKey, Viewport::CanvasData *>::Element *E = canvas_map.front(); E; E = E->next()) { VisualServerCanvas::Canvas *canvas = static_cast<VisualServerCanvas::Canvas *>(E->get()->canvas); //print_line("canvas "+itos(i)+" size: "+itos(I->get()->canvas->child_items.size())); //print_line("GT "+p_viewport->global_transform+". CT: "+E->get()->transform); Transform2D xform = p_viewport->global_transform * E->get()->transform; RasterizerCanvas::Light *canvas_lights = NULL; RasterizerCanvas::Light *ptr = lights; while (ptr) { if (E->get()->layer >= ptr->layer_min && E->get()->layer <= ptr->layer_max) { ptr->next_ptr = canvas_lights; canvas_lights = ptr; } ptr = ptr->filter_next_ptr; } VSG::canvas->render_canvas(canvas, xform, canvas_lights, lights_with_mask, clip_rect); i++; if (scenario_draw_canvas_bg && E->key().layer >= scenario_canvas_max_layer) { if (can_draw_3d) { VSG::scene->render_camera(p_viewport->camera, p_viewport->scenario, p_viewport->size, p_viewport->shadow_atlas); } else { VSG::scene->render_empty_scene(p_viewport->scenario, p_viewport->shadow_atlas); } scenario_draw_canvas_bg = false; } } if (scenario_draw_canvas_bg) { if (can_draw_3d) { VSG::scene->render_camera(p_viewport->camera, p_viewport->scenario, p_viewport->size, p_viewport->shadow_atlas); } else { VSG::scene->render_empty_scene(p_viewport->scenario, p_viewport->shadow_atlas); } scenario_draw_canvas_bg = false; } //VSG::canvas_render->canvas_debug_viewport_shadows(lights_with_shadow); } }
bool Warp::accelerated_cairorender(Context context, cairo_t *cr, int quality, const RendDesc &renddesc_, ProgressCallback *cb)const { Point src_tl=param_src_tl.get(Point()); Point src_br=param_src_br.get(Point()); Point dest_tl=param_dest_tl.get(Point()); Point dest_tr=param_dest_tr.get(Point()); Point dest_bl=param_dest_bl.get(Point()); Point dest_br=param_dest_br.get(Point()); Real horizon=param_horizon.get(Real()); bool clip=param_clip.get(bool()); SuperCallback stageone(cb,0,9000,10000); SuperCallback stagetwo(cb,9000,10000,10000); RendDesc renddesc(renddesc_); // Untransform the render desc if(!cairo_renddesc_untransform(cr, renddesc)) return false; Real pw=(renddesc.get_w())/(renddesc.get_br()[0]-renddesc.get_tl()[0]); Real ph=(renddesc.get_h())/(renddesc.get_br()[1]-renddesc.get_tl()[1]); if(cb && !cb->amount_complete(0,10000)) return false; Point tl(renddesc.get_tl()); Point br(renddesc.get_br()); Rect bounding_rect; Rect render_rect(tl,br); Rect clip_rect(Rect::full_plane()); Rect dest_rect(dest_tl,dest_br); dest_rect.expand(dest_tr).expand(dest_bl); Real zoom_factor(1.0); // Quick exclusion clip, if necessary if(clip && !intersect(render_rect,dest_rect)) { cairo_save(cr); cairo_set_operator(cr, CAIRO_OPERATOR_CLEAR); cairo_paint(cr); cairo_restore(cr); return true; } { Rect other(render_rect); if(clip) other&=dest_rect; Point min(other.get_min()); Point max(other.get_max()); bool init_point_set=false; // Point trans_point[4]; Point p; // Real trans_z[4]; Real z,minz(10000000000000.0f),maxz(0); //! \todo checking the 4 corners for 0<=z<horizon*2 and using //! only 4 corners which satisfy this condition isn't the //! right thing to do. It's possible that none of the 4 //! corners fall within that range, and yet content of the //! tile does. p=transform_forward(min); z=transform_backward_z(p); if(z>0 && z<horizon*2) { if(init_point_set) bounding_rect.expand(p); else bounding_rect=Rect(p); init_point_set=true; maxz=std::max(maxz,z); minz=std::min(minz,z); } p=transform_forward(max); z=transform_backward_z(p); if(z>0 && z<horizon*2) { if(init_point_set) bounding_rect.expand(p); else bounding_rect=Rect(p); init_point_set=true; maxz=std::max(maxz,z); minz=std::min(minz,z); } swap(min[1],max[1]); p=transform_forward(min); z=transform_backward_z(p); if(z>0 && z<horizon*2) { if(init_point_set) bounding_rect.expand(p); else bounding_rect=Rect(p); init_point_set=true; maxz=std::max(maxz,z); minz=std::min(minz,z); } p=transform_forward(max); z=transform_backward_z(p); if(z>0 && z<horizon*2) { if(init_point_set) bounding_rect.expand(p); else bounding_rect=Rect(p); init_point_set=true; maxz=std::max(maxz,z); minz=std::min(minz,z); } if(!init_point_set) { cairo_save(cr); cairo_set_operator(cr, CAIRO_OPERATOR_CLEAR); cairo_paint(cr); cairo_restore(cr); return true; } zoom_factor=(1+(maxz-minz)); } #ifdef ACCEL_WARP_IS_BROKEN return Layer::accelerated_cairorender(context,cr,quality,renddesc, cb); #else /*swap(tl[1],br[1]); bounding_rect .expand(transform_forward(tl)) .expand(transform_forward(br)) ; swap(tl[1],br[1]);*/ //synfig::warning("given window: [%f,%f]-[%f,%f] %dx%d",tl[0],tl[1],br[0],br[1],renddesc.get_w(),renddesc.get_h()); //synfig::warning("Projected: [%f,%f]-[%f,%f]",bounding_rect.get_min()[0],bounding_rect.get_min()[1],bounding_rect.get_max()[0],bounding_rect.get_max()[1]); // If we are clipping, then go ahead and clip to the // source rectangle if(clip) clip_rect&=Rect(src_tl,src_br); // Bound ourselves to the bounding rectangle of // what is under us clip_rect&=context.get_full_bounding_rect();//.expand_x(abs(zoom_factor/pw)).expand_y(abs(zoom_factor/ph)); bounding_rect&=clip_rect; Point min_point(bounding_rect.get_min()); Point max_point(bounding_rect.get_max()); // we're going to divide by the difference of these pairs soon; // if they're the same, we'll be dividing by zero, and we don't // want to do that! // \todo what should we do in this case? if (min_point[0] == max_point[0]) max_point[0] += 0.001; if (min_point[1] == max_point[1]) max_point[1] += 0.001; if(tl[0]>br[0]) { tl[0]=max_point[0]; br[0]=min_point[0]; } else { br[0]=max_point[0]; tl[0]=min_point[0]; } if(tl[1]>br[1]) { tl[1]=max_point[1]; br[1]=min_point[1]; } else { br[1]=max_point[1]; tl[1]=min_point[1]; } const int tmp_d(max(renddesc.get_w(),renddesc.get_h())); Real src_pw=(tmp_d*zoom_factor)/(br[0]-tl[0]); Real src_ph=(tmp_d*zoom_factor)/(br[1]-tl[1]); RendDesc desc(renddesc); desc.clear_flags(); //desc.set_flags(RendDesc::PX_ASPECT); desc.set_tl(tl); desc.set_br(br); desc.set_wh(ceil_to_int(src_pw*(br[0]-tl[0])),ceil_to_int(src_ph*(br[1]-tl[1]))); //synfig::warning("surface to render: [%f,%f]-[%f,%f] %dx%d",desc.get_tl()[0],desc.get_tl()[1],desc.get_br()[0],desc.get_br()[1],desc.get_w(),desc.get_h()); if(desc.get_w()==0 && desc.get_h()==0) { cairo_save(cr); cairo_set_operator(cr, CAIRO_OPERATOR_CLEAR); cairo_paint(cr); cairo_restore(cr); return true; } // Recalculate the pixel widths for the src renddesc src_pw=(desc.get_w())/(desc.get_br()[0]-desc.get_tl()[0]); src_ph=(desc.get_h())/(desc.get_br()[1]-desc.get_tl()[1]); cairo_surface_t* source=cairo_surface_create_similar(cairo_get_target(cr), CAIRO_CONTENT_COLOR_ALPHA, desc.get_w(),desc.get_h()); cairo_surface_t* surface=cairo_surface_create_similar(cairo_get_target(cr), CAIRO_CONTENT_COLOR_ALPHA,renddesc.get_w(), renddesc.get_h()); cairo_t* subcr=cairo_create(source); cairo_scale(subcr, 1/desc.get_pw(), 1/desc.get_ph()); cairo_translate(subcr, -desc.get_tl()[0], -desc.get_tl()[1]); if(!context.accelerated_cairorender(subcr,quality,desc,&stageone)) return false; cairo_destroy(subcr); int surfacew, surfaceh, sourcew, sourceh; CairoSurface csurface(surface); CairoSurface csource(source); csurface.map_cairo_image(); csource.map_cairo_image(); surfacew=csurface.get_w(); surfaceh=csurface.get_h(); sourcew=csource.get_w(); sourceh=csource.get_h(); CairoSurface::pen pen(csurface.begin()); // Do the warp { int x,y; float u,v; Point point,tmp; for(y=0,point[1]=renddesc.get_tl()[1];y<surfaceh;y++,pen.inc_y(),pen.dec_x(x),point[1]+=1.0/ph) { for(x=0,point[0]=renddesc.get_tl()[0];x<surfacew;x++,pen.inc_x(),point[0]+=1.0/pw) { tmp=transform_forward(point); const float z(transform_backward_z(tmp)); if(!clip_rect.is_inside(tmp) || !(z>0 && z<horizon)) { csurface[y][x]=Color::alpha(); continue; } u=(tmp[0]-tl[0])*src_pw; v=(tmp[1]-tl[1])*src_ph; if(u<0 || v<0 || u>=sourcew || v>=sourceh || isnan(u) || isnan(v)) csurface[y][x]=context.get_cairocolor(tmp); else { // CUBIC if(quality<=4) csurface[y][x]=csource.cubic_sample_cooked(u,v); // INTEPOLATION_LINEAR else if(quality<=6) csurface[y][x]=csource.linear_sample_cooked(u,v); else // NEAREST_NEIGHBOR csurface[y][x]=csource[floor_to_int(v)][floor_to_int(u)]; } } if((y&31)==0 && cb) { if(!stagetwo.amount_complete(y,surfaceh)) return false; } } } #endif if(cb && !cb->amount_complete(10000,10000)) return false; csurface.unmap_cairo_image(); csource.unmap_cairo_image(); cairo_surface_destroy(source); cairo_save(cr); cairo_translate(cr, renddesc.get_tl()[0], renddesc.get_tl()[1]); cairo_scale(cr, renddesc.get_pw(), renddesc.get_ph()); cairo_set_source_surface(cr, surface, 0, 0); cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE); cairo_paint(cr); cairo_restore(cr); cairo_surface_destroy(surface); return true; }
void GroupEditor::drawContents(Renderer2D &out) const { int2 offset = innerOffset(); for(int n = 0; n < m_tile_group->entryCount(); n++) m_tile_group->entryTile(n)->m_temp = n; IRect clip_rect(int2(0, 0), clippedRect().size()); for(int n = 0; n < (int)m_tile_list.size(); n++) { const ui::TileList::Entry &entry = m_tile_list[n]; entry.is_selected = m_mode == mAddRemove? m_tile_group->isValidEntryId(entry.tile->m_temp, entry.tile) : entry.group_id == m_selected_group_id; IRect tile_rect = entry.tile->rect(); int2 pos = entry.pos - tile_rect.min - offset; if(areOverlapping(clip_rect, tile_rect + pos)) entry.tile->draw(out, pos); } DTexture::unbind(); for(int n = 0; n < (int)m_tile_list.size(); n++) { const ui::TileList::Entry &entry = m_tile_list[n]; if(!entry.is_selected) continue; Color col = m_tile_group->isEntryDirty(entry.tile->m_temp)? ColorId::red : ColorId::white; int2 pos = entry.pos - offset; out.addRect(IRect(pos, pos + entry.size), col); } if(m_mode == mModify && m_selected_group_id != -1) { IRect edit_rect(clippedRect().max - int2(280, 250), clippedRect().max - int2(5, 0)); int2 center = edit_rect.center(); out.setViewPos(-center); int2 half_size = edit_rect.size() / 2; out.addFilledRect(IRect(-half_size, half_size), FColor(0.3f, 0.3f, 0.3f)); drawBBox(out, IBox({-9, 0, -9}, {9, 1, 9}), ColorId::white); auto font = res::getFont(WindowStyle::fonts[0]); for(int n = 0; n < TileGroup::Group::side_count; n++) { out.setViewPos(-center - worldToScreen(TileGroup::Group::s_side_offsets[n] * 9)); font->draw(out, float2(0, 0), {ColorId::white}, format("%d", m_tile_group->groupSurface(m_selected_group_id, n))); } out.setViewPos(-center +edit_rect.size() / 2); font->draw(out, float2(0, 0), {ColorId::white}, format("setting surface: %d", m_selected_surface_id)); /* const char *names[] = { "", "snow", "gravel", "dirt", "grass", "mud", "mud_cracked", "sand", "green goo", }; out.setViewPos(-int2(bottom_rect.max.x - 200, bottom_rect.min.y)); for(int n = 0; n < arraySize(names); n++) font->draw(int2(0, 10), ColorId::white, m_selected_surface_id == n? "%d: [%s]\n" : "%d: %s\n", n, names[n]); */ out.setViewPos(-clippedRect().min); } if(m_current_entry) m_font->draw(out, float2(5, height() - 20), {ColorId::white, ColorId::black}, format("%s", m_current_entry->tile->resourceName().c_str())); }
void cTextField::draw(){ if(!visible) return; static const sf::Color hiliteClr = {127,127,127}, ipClr = {92, 92, 92}; inWindow->setActive(); rectangle outline = frame; outline.inset(-2,-2); fill_rect(*inWindow, outline, sf::Color::White); frame_rect(*inWindow, outline, sf::Color::Black); std::string contents = getText(); TextStyle style; style.font = FONT_PLAIN; style.pointSize = 12; style.colour = sf::Color::Black; style.lineHeight = 16; size_t ip_offset = 0; hilite_t hilite = {insertionPoint, selectionPoint}; if(selectionPoint < insertionPoint) std::swap(hilite.first,hilite.second); if(haveFocus && contents.length() >= 1 && changeMade) { text_rect = frame; text_rect.inset(2,2); // Determine which line the insertion and selection points are on clip_rect(*inWindow, {0,0,0,0}); // To prevent drawing hilite_t tmp_hilite = hilite; // Manipulate this to ensure that there is a hilited area std::string dummy_str = contents + " "; if(tmp_hilite.first >= tmp_hilite.second) tmp_hilite.second = tmp_hilite.first + 1; std::vector<rectangle> rects = draw_string_hilite(*inWindow, text_rect, dummy_str, style, {tmp_hilite}, {0,0,0}); if(!rects.empty()) { // We only care about the first and last rects. Furthermore, we only really need one point location ip_pos = rects[0].centre(), sp_pos = rects[rects.size() - 1].centre(); if(selectionPoint < insertionPoint) std::swap(ip_pos, sp_pos); // Prioritize selection point being visible. If possible, also keep insertion point visible. // We do this by first ensuring the insertion point is visible, then doing the same // for the selection point. while(!ip_pos.in(frame)) { text_rect.offset(0,-14); ip_pos.y -= 14; sp_pos.y -= 14; } while(!sp_pos.in(frame)) { int shift = selectionPoint < insertionPoint ? 14 : -14; text_rect.offset(0,shift); ip_pos.y += shift; sp_pos.y += shift; } } undo_clip(*inWindow); changeMade = false; } clip_rect(*inWindow, frame); ip_col = ip_row = -1; if(haveFocus) { snippets = draw_string_sel(*inWindow, text_rect, contents, style, {hilite}, hiliteClr); int iSnippet = -1, sum = 0; ip_offset = insertionPoint; for(size_t i = 0; i < snippets.size(); i++) { size_t snippet_len = snippets[i].text.length(); sum += snippet_len; if(sum >= insertionPoint) { iSnippet = i; break; } ip_offset -= snippet_len; } std::string pre_ip = iSnippet >= 0 ? snippets[iSnippet].text.substr(0, ip_offset) : ""; ip_offset = string_length(pre_ip, style); if(ip_timer.getElapsedTime().asMilliseconds() < 500) { // printf("Blink on (%d); ", ip_timer.getElapsedTime().asMilliseconds()); rectangle ipRect = {0, 0, 15, 1}; if(iSnippet >= 0) ipRect.offset(snippets[iSnippet].at.x + ip_offset, snippets[iSnippet].at.y + 1); else ipRect.offset(frame.topLeft()), ipRect.offset(3,2); fill_rect(*inWindow, ipRect, ipClr); } else if(ip_timer.getElapsedTime().asMilliseconds() > 1000) { // printf("Blink off (%d); ", ip_timer.getElapsedTime().asMilliseconds()); ip_timer.restart(); } // Record it so that we can calculate up/down arrow key results ip_col = ip_offset; ip_row = iSnippet; } else { rectangle text_rect = frame; text_rect.inset(2,2); win_draw_string(*inWindow, text_rect, contents, eTextMode::WRAP, style); } undo_clip(*inWindow); }