Beispiel #1
0
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);
}
Beispiel #2
0
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);
}
Beispiel #3
0
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
}
Beispiel #4
0
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;
	}
}
Beispiel #6
0
	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;
    }
Beispiel #8
0
/*
=======================================
    画方框
=======================================
*/
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();
}
Beispiel #10
0
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--;
        }
    }
}
Beispiel #11
0
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();
}
Beispiel #12
0
	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);
	}
}
Beispiel #14
0
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);
	}
}
Beispiel #16
0
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;
}
Beispiel #17
0
	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()));
	}
Beispiel #18
0
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);
}