Example #1
0
//--------------------------------------------------------------
void ofApp::onMessage( ofxLibwebsockets::Event& args ){
    cout<<"got message "<<args.message<<endl;
    
  try{
    // trace out string messages or JSON messages!
    if ( !args.json.isNull() ){
        ofPoint point = ofPoint( args.json["point"]["x"].asFloat(), args.json["point"]["y"].asFloat() );
        
        // for some reason these come across as strings via JSON.stringify!
        int r = ofToInt(args.json["color"]["r"].asString());
        int g = ofToInt(args.json["color"]["g"].asString());
        int b = ofToInt(args.json["color"]["b"].asString());
        ofColor color = ofColor( r, g, b );
        
        int _id = ofToInt(args.json["id"].asString());
        
        map<int, Drawing*>::const_iterator it = drawings.find(_id);
        Drawing * d = it->second;
        d->addPoint(point);
    } else {
    }
    // send all that drawing back to everybody except this one
    vector<ofxLibwebsockets::Connection *> connections = server.getConnections();
    for ( int i=0; i<connections.size(); i++){
        if ( (*connections[i]) != args.conn ){
            connections[i]->send( args.message );
        }
    }
  }
  catch(exception& e){
    ofLogError() << e.what();
  }
}
Example #2
0
//--------------------------------------------------------------
void ofApp::onOpen( ofxLibwebsockets::Event& args ){
    cout<<"new connection open"<<endl;
    cout<<args.conn.getClientIP()<< endl;
    
    Drawing * d = new Drawing();
    d->_id = canvasID++;
    d->color.set(ofRandom(255),ofRandom(255),ofRandom(255));;
    d->conn = &( args.conn );
    
    drawings.insert( make_pair( d->_id, d ));
    
    // send "setup"
    args.conn.send( d->getJSONString("setup") );
    
    // send drawing so far
    map<int, Drawing*>::iterator it = drawings.begin();
    for (it; it != drawings.end(); ++it){
        Drawing * drawing = it->second;
        if ( d != drawing ){
            for ( int i=0; i<drawing->points.size(); i++){
                string x = ofToString(drawing->points[i].x);
                string y = ofToString(drawing->points[i].y);
                server.send( "{\"id\":"+ ofToString(drawing->_id) + ",\"point\":{\"x\":\""+ x+"\",\"y\":\""+y+"\"}," + drawing->getColorJSON() +"}");
            }
        }
    }
}
Example #3
0
	void Run(){
		wxGetApp().m_digitizing->digitized_point = DigitizedPoint(line_for_tool->A->m_p, DigitizeInputType);
		Drawing *pDrawingMode = dynamic_cast<Drawing *>(wxGetApp().input_mode_object);
		if (pDrawingMode != NULL)
		{
			pDrawingMode->AddPoint();
		}
	}
Example #4
0
//--------------------------------------------------------------
void ofApp::mouseDragged(int x, int y, int button){
    ofPoint p(x,y);
    
    map<int, Drawing*>::iterator it = drawings.find(0);
    Drawing * d = it->second;
    d->addPoint(p);
    server.send( "{\"id\":-1,\"point\":{\"x\":\""+ ofToString(x)+"\",\"y\":\""+ofToString(y)+"\"}," + d->getColorJSON() +"}");
}
Example #5
0
//--------------------------------------------------------------
void ofApp::mousePressed(int x, int y, int button){

    ofPoint p(x,y);
    map<int, Drawing*>::iterator it = drawings.find(id);
    if ( it == drawings.end() ) return;
    Drawing * d = it->second;
    d->addPoint(p);
    client.send( "{\"id\":"+ ofToString(id) + ",\"point\":{\"x\":\""+ ofToString(x)+"\",\"y\":\""+ofToString(y)+"\"}," + d->getColorJSON() +"}");
}
Example #6
0
//--------------------------------------------------------------
void ofApp::onMessage( ofxLibwebsockets::Event& args ){
  try{
    cout<<"got message "<<args.message<<endl;
    // trace out string messages or JSON messages!
    if ( !args.json.isNull() ){
        if (!args.json["setup"].isNull()){
            Drawing * d = new Drawing();
            d->_id = args.json["setup"]["id"].asInt();
            // for some reason these come across as strings via JSON.stringify!
            int r = ofToInt(args.json["setup"]["color"]["r"].asString());
            int g = ofToInt(args.json["setup"]["color"]["g"].asString());
            int b = ofToInt(args.json["setup"]["color"]["b"].asString());
            d->color.set(r, g, b);
            drawings.insert( make_pair( d->_id, d ));
            id = d->_id;
            color.set(r, g, b);
            cout << "setup with id:" << id << endl;
        }
        else if (args.json["id"].asInt() != id){
          cout << "received point" << endl;
            ofPoint point = ofPoint( args.json["point"]["x"].asFloat(), args.json["point"]["y"].asFloat() );
            
            // for some reason these come across as strings via JSON.stringify!
            int r = ofToInt(args.json["color"]["r"].asString());
            int g = ofToInt(args.json["color"]["g"].asString());
            int b = ofToInt(args.json["color"]["b"].asString());
            ofColor color = ofColor( r, g, b );
            
            int _id = args.json["id"].asInt();
            
            map<int, Drawing*>::const_iterator it = drawings.find(_id);
            Drawing * d;
            if (it!=drawings.end()){
                d = it->second;
            }
            else {
              d = new Drawing();
              d->_id = _id;
              // for some reason these come across as strings via JSON.stringify!
              int r = ofToInt(args.json["color"]["r"].asString());
              int g = ofToInt(args.json["color"]["g"].asString());
              int b = ofToInt(args.json["color"]["b"].asString());
              d->color.set(r, g, b);
              drawings.insert( make_pair( d->_id, d ));
              cout << "new drawing with id:" << _id << endl;
            }

            d->addPoint(point);
        }
    } else {
    }
  }
  catch(exception& e){
    ofLogError() << e.what();
  }
}
Example #7
0
	void Run(){
		gp_Pnt midpoint((line_for_tool->A->m_p.XYZ() + line_for_tool->B->m_p.XYZ()) /2);

		wxGetApp().m_digitizing->digitized_point = DigitizedPoint(midpoint, DigitizeInputType);
		Drawing *pDrawingMode = dynamic_cast<Drawing *>(wxGetApp().input_mode_object);
		if (pDrawingMode != NULL)
		{
			pDrawingMode->AddPoint();
		}
	}
Example #8
0
void test_lake() {
    sf::RenderWindow window(sf::VideoMode(200, 200), "Map Test");
    Random r;

    window.clear(sf::Color(128, 128, 128));
    Drawing * lake = Drawing::new_lake(r, 100);
	lake->draw(window, 100, 100);

    window_loop(window);
}
Example #9
0
int main(){
	Trigtable::generate();
	Drawing *s;
	SimCtrl sc;
	stringstream evt;
	string resp;
	SockServ socket;
	int cliTmp;

	//espera um socket se conectar (espera ocupada)
	while (!socket.acceptClient() && sc.isRunning()){
		SDL_Delay(200);
		evt << KbdDecoder::decodeKbdEvent();
		EventManager::runEvent(evt, sc);
		evt.clear();
	}

	//espera definir dimensoes do mundo
	while (!sc.isStarted() && sc.isRunning()){
		SDL_Delay(200);
		evt << KbdDecoder::decodeKbdEvent();
		EventManager::runEvent(evt, sc);
		evt.clear();
		socket.recvStart();
		while (socket.hasNext()){
			evt << socket.recvNext(&cliTmp);
			s = EventManager::startSim(evt, sc);
			if (s != NULL)
				break;
		}
		evt.clear();
	}

	//inicia laco de simulacao
	while (sc.isRunning()){
		socket.acceptClient();
		s->clearScr();
		evt.clear();
		evt << KbdDecoder::decodeKbdEvent();
		EventManager::runEvent(evt, sc);
		socket.recvStart();
		while (socket.hasNext()){
			evt.clear();
			evt << socket.recvNext(&cliTmp);
			resp = EventManager::runEvent(evt, sc, cliTmp);
			if (resp.size())
				socket.sends(resp,cliTmp);
		}
		sc.sendEvents(socket);
		sc.sendTimeAlert(socket);
		sc.runStep(*s);
		sc.draw(*s);
		s->updateScr();
	}
}
Example #10
0
void test_shield() {
    sf::RenderWindow window(sf::VideoMode(200, 200), "Wave Test");
    Random r;

    window.clear(sf::Color(128, 128, 128));

    Drawing *shield = Drawing::new_shield(r, 100);
	shield->draw(window, 100, 100);
    window.display();
    window_loop(window);
}
Example #11
0
// Refresh the screen widgets pool, depending on stored drawings
void ScreenBoard::reallocScreenWidgets() {
  QDesktopWidget *desktop = QApplication::desktop();

  int i, screensCount = desktop->numScreens();

  // Delete exceeding screens and resize to screensCount
  for (i = screensCount; i < m_screenWidgets.size(); ++i) {
    m_screenWidgets[i]->hide();
    m_screenWidgets[i]->deleteLater();  // Ensures no event about it is pending.
    // Note that updates may be invoked in event handlers.
  }

  m_screenWidgets.resize(desktop->numScreens());

  // Re-initialize the screen widgets list
  for (i = 0; i < screensCount; ++i) {
    ScreenWidget *screenWidget = m_screenWidgets[i];
    if (screenWidget) screenWidget->drawings().clear();
  }

  // Turn on a ScreenWidget for each screen crossed by any drawing
  int j, drawingsCount = m_drawings.size();
  for (i = 0; i < screensCount; ++i) {
    ScreenWidget *screenWidget = m_screenWidgets[i];
    const QRect &screenGeom    = desktop->screenGeometry(i);

    for (j = 0; j < drawingsCount; ++j) {
      Drawing *drawing = m_drawings[j];
      if (drawing->acceptScreenEvents(screenGeom)) {
        // Allocate the associated screen widget if necessary
        if (!screenWidget) {
          m_screenWidgets[i] = screenWidget = new ScreenWidget(0, m_grabbing);
          if (m_grabbing) screenWidget->setCursor(m_cursor);

          screenWidget->setGeometry(screenGeom);
          screenWidget->show();
        }

        // Add the drawing to the widget
        screenWidget->drawings().push_back(drawing);
      }
    }
  }

  // Remove screens without drawings
  for (i = 0; i < screensCount; ++i) {
    ScreenWidget *screenWidget = m_screenWidgets[i];
    if (screenWidget && screenWidget->drawings().empty()) {
      screenWidget->hide();
      screenWidget->deleteLater();
      m_screenWidgets[i] = 0;
    }
  }
}
// Refresh the pixmap of the displayed screenshot by redraw everything
void EditWindow::refreshScreenshotToShow()
{
    // Take the screenshot without any drawings
    QPixmap screenshotPixmap = screenshot->getImage();
    painterScreenshot->drawPixmap(screenshotPixmap.rect(), screenshotPixmap);

    // Draw every drawing one by one on the clean screenshot
    Drawing* drawing;
    foreach(drawing, newDrawingsList)
    {
        drawing->draw(painterScreenshot);
    }
Example #13
0
	void Run()
	{
		CBox box;
		sketch_for_tools->GetBox(box);
		double centre[3];
		box.Centre(centre);		

		wxGetApp().m_digitizing->digitized_point = DigitizedPoint(gp_Pnt(box.MinX(), centre[1], centre[2]), DigitizeInputType);
		Drawing *pDrawingMode = dynamic_cast<Drawing *>(wxGetApp().input_mode_object);
		if (pDrawingMode != NULL)
		{
			pDrawingMode->AddPoint();
		}
	}
Example #14
0
  void TileRenderer::RenderAtomBG(Drawing & drawing,
                                  SPoint& offset,
                                  SPoint& atomLoc,
                                  u32 color)
  {
    SPoint ulpt(m_windowTL.GetX() + offset.GetY() + atomLoc.GetX() *
                m_atomDrawSize,
                m_windowTL.GetY() + offset.GetY() + atomLoc.GetY() *
                m_atomDrawSize);

    SPoint brpt(ulpt.GetX() + m_atomDrawSize, ulpt.GetY() + m_atomDrawSize);

    if(brpt.GetX() > (s32)m_dimensions.GetX())
    {
      brpt.SetX(m_dimensions.GetX());
    }
    if(brpt.GetY() > (s32)m_dimensions.GetY())
    {
      brpt.SetY(m_dimensions.GetY());
    }

    drawing.FillRect(ulpt.GetX(),ulpt.GetY(),
                     brpt.GetX()-ulpt.GetX(),brpt.GetY()-ulpt.GetY(),
                     color);
  }
Example #15
0
void simple_render(const Drawing& shape, graphics::raster& raster)
{
    for (size_t y = 0; y < raster.height(); ++y) {
        for (size_t x = 0; x < raster.width(); ++x) {
            raster.at(x, y) = shape.color_at({x + .5, y + .5});
        }
    }
}
Example #16
0
void test_drawing2() {
    sf::RenderWindow window(sf::VideoMode(200, 200), "Drawing Test");
    Random r;
//    Drawing *d = Drawing::new_mountain(r, 100);
//    Drawing *d = Drawing::new_tree(r, 100);
//    Drawing *d = Drawing::new_wave(r, 100);
//    Drawing *d = Drawing::new_hill(r, 100);
    Drawing *d = Drawing::new_person(r, 100);
    window.clear(sf::Color(128, 128, 128));
	d->draw(window, 100, 120);

	sf::CircleShape cs(2, 4);
    cs.setPosition(100, 120);
    window.draw(cs);
    
    window_loop(window);
}
Example #17
0
	void Run(){
		wxGetApp().m_digitizing->digitized_point = DigitizedPoint(which->m_p, DigitizeInputType);
		Drawing *pDrawingMode = dynamic_cast<Drawing *>(wxGetApp().input_mode_object);
		if (pDrawingMode != NULL)
		{
			pDrawingMode->AddPoint();
		}

		DigitizeMode *pDigitizeMode = dynamic_cast<DigitizeMode *>(wxGetApp().input_mode_object);
		if (pDigitizeMode != NULL)
		{
			// Tell the DigitizeMode class that we're specifying the
			// location rather than the mouse location over the graphics window.

			pDigitizeMode->DigitizeToLocatedPosition( which->m_p );
		}
	}
Example #18
0
	void Run(){
		Drawing *pDrawingMode = dynamic_cast<Drawing *>(wxGetApp().input_mode_object);
		if (pDrawingMode != NULL)
		{
			wxString message(_("Enter offset in X,Y,Z format (with commas between them)"));
			wxString caption(_("Apply Offset To Selected Location"));
			wxString default_value(_T("0,0,0"));

			wxString value = wxGetTextFromUser(message, caption, default_value);
			wxStringTokenizer tokens(value,_T(" :,\t\n"));
			
			gp_Pnt location(which->m_p);
			for (int i=0; i<3; i++)
			{
				if (tokens.HasMoreTokens())
				{
					double offset = 0.0;
					wxString token = tokens.GetNextToken();
					if (token.ToDouble(&offset))
					{
						offset *= wxGetApp().m_view_units;
						switch(i)
						{
						case 0: 
							location.SetX( location.X() + offset );
							break;

						case 1:
							location.SetY( location.Y() + offset );
							break;

						case 2:
							location.SetZ( location.Z() + offset );
							break;
						}
						
					}
				}
			}

			wxGetApp().m_digitizing->digitized_point = DigitizedPoint(location, DigitizeInputType);
			pDrawingMode->AddPoint();
		}
	}
Example #19
0
	void Run(){
		Drawing *pDrawingMode = dynamic_cast<Drawing *>(wxGetApp().input_mode_object);
		DigitizeMode *pDigitizeMode = dynamic_cast<DigitizeMode *>(wxGetApp().input_mode_object);
		if ((pDrawingMode != NULL) || (pDigitizeMode != NULL))
		{
			gp_Pnt location = HPoint::GetOffset(which->m_p);

			if (pDrawingMode != NULL)
			{
				wxGetApp().m_digitizing->digitized_point = DigitizedPoint(location, DigitizeInputType);
				pDrawingMode->AddPoint();
			}

			if (pDigitizeMode != NULL)
			{
				pDigitizeMode->DigitizeToLocatedPosition( location );
			}
		}
	}
Example #20
0
NAMESPACE_UPP

#define LLOG(x) // LOG(x)

void Print(Report& r, PrinterJob& pd)
{
	Draw& w = pd;
	Size sz = w.GetPageSize();
	Point mg = r.GetMargins();
	Size pgsz = r.GetPage(0).GetSize();
	int	x = Nvl(mg.x, (sz.cx - pgsz.cx) / 2);
	int y = Nvl(mg.y, (sz.cy - pgsz.cy) / 2);
	for(int i = 0; i < pd.GetPageCount(); i++) {
		Drawing iw = r.GetPage(pd[i]);
		Size sz = iw.GetSize();
		w.StartPage();
		w.DrawDrawing(x, y, sz.cx, sz.cy, iw);
		w.EndPage();
	}
}
Example #21
0
//---------------------------------------------- Constructors - destructor
ClearCommand::ClearCommand ( Drawing & rDrawing, string const & rParameters )
: Command ( rDrawing, false ), mList ( rDrawing.GetList( ) )
{
	bool error = ( "" == rParameters ); // TODO accept whitespaces
	if ( !mError && error )
	{
		mError = true;
		mErrorMessage = "CLEAR takes no parameter";
	}
#ifdef DEBUG
	cout << "# Calling constructor of <ClearCommand>" << endl;
#endif
} //----- End of ClearCommand
Example #22
0
		void Ellipse::appendAsXml(SvgElement& parent, Drawing& drawing) {
			SvgElement element = parent.createElement("ellipse");
			assignId(element);
			Point mapped = drawing.map(m_centre);
			element.setAttribute("cx", NumberUtil::formatFloat(mapped.getX()));
			element.setAttribute("cy", NumberUtil::formatFloat(mapped.getY()));
			element.setAttribute("rx", NumberUtil::formatFloat(m_radius));
			element.setAttribute("ry", NumberUtil::formatFloat(m_radius * m_eccentricity));

			if (m_inclination != 0) {
				element.setAttribute("transform", "rotate(" + NumberUtil::formatFloat((float) (m_inclination * 180.0 / M_PI)) + ")");
			}
			setStrokeAndFill(element, drawing);
			parent.appendChild(element);
		}
Example #23
0
//--------------------------------------------------------------
void ofApp::onOpen( ofxLibwebsockets::Event& args ){
    bConnected = true;
    cout<<"new connection open"<<endl;
    cout<<args.conn.getClientIP()<< endl;
    
    // send drawing so far
    map<int, Drawing*>::iterator it = drawings.begin();
    for (it; it != drawings.end(); ++it){
        Drawing * drawing = it->second;
            for ( int i=0; i<(int)drawing->points.size(); i++){
                string x = ofToString(drawing->points[i].x);
                string y = ofToString(drawing->points[i].y);
                client.send( "{\"id\":"+ ofToString(drawing->_id) + ",\"point\":{\"x\":\""+ x+"\",\"y\":\""+y+"\"}," + drawing->getColorJSON() +"}");
            }
    }
}
Example #24
0
void render(const Drawing& shape, graphics::raster& raster, size_t antialias)
{
    for (size_t y = 0; y < raster.height(); ++y) {
        for (size_t x = 0; x < raster.width(); ++x) {
            graphics::color_blender cb;

            for (size_t i = 0; i < antialias; ++i) {
                for (size_t j = 0; j < antialias; ++j) {
                    Drawing::posn point{x + (i + 0.5) / antialias,
                                        y + (j + 0.5) / antialias};
                    cb << shape.color_at(point);
                }
            }

            raster.at(x, y) = cb.get();
        }
    }
}
Example #25
0
void test_drawing() {
    sf::RenderWindow window(sf::VideoMode(200, 200), "Wave Test");
    Random r;
    Drawing *mnt = Drawing::new_mountain(r, 100);
    Drawing *tree = Drawing::new_tree(r, 80);
    Drawing *wave = Drawing::new_wave(r, 80);

    window.clear(sf::Color(128, 128, 128));
	mnt->draw(window, 100, 180);
	tree->draw(window, 110, 100);
	wave->draw(window, 100, 40);

	sf::CircleShape cs(2, 4);
    cs.setPosition(100, 40);
    window.draw(cs);

    
    window.display();
    window_loop(window);
}
Example #26
0
	void Run(){drawing->set_start_pos_not_undoable(next_pos);}
Example #27
0
        Main() 
        {
            isClicked = false;
            screen = Vec2<unsigned int>(800, 600);
            std::setlocale(LC_ALL, "en_US.UTF-8");
            glfwInit();
            glfwWindowHint(GLFW_CLIENT_API, GLFW_OPENGL_API);
            glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
            glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
            glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, GL_TRUE);
            GLFWwindow* window = glfwCreateWindow(screen.x, screen.y, "test", nullptr, nullptr);
            if (window == nullptr)
            {
                printf("cant create window");
                return;
            }
            
            glfwSetWindowSizeCallback(window, windowSizeCallback);
            glfwSetKeyCallback(window, keyCallback);
            glfwSetMouseButtonCallback(window, clickCallback);
            glfwSetCursorPosCallback(window, mouseCallback);
            glfwMakeContextCurrent(window);
            glewExperimental = true;
            glewInit();
            
            //glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
            glDebugMessageCallback(debugCallback, nullptr);
            glEnable(GL_DEBUG_OUTPUT);
            
            
            printf("%s\n", glGetString(GL_VERSION));
            Shader* fs = new Shader("res/shader/fragment.c", true, GL_FRAGMENT_SHADER);
            Shader* vs = new Shader("res/shader/vertex.c", true, GL_VERTEX_SHADER);
            Program* p = new Program();
            p->attach(fs);
            p->attach(vs);
            p->build();
            p->use();
            
            tm = new TextureManager();
            font = new Font(512, "res/font/DroidSans.woff", 32, tm);
            print = new Print(font);
            //print.set(&font, "res/shader/fontVertex.c", "res/shader/fontFragment.c");
            print->setScreenSize(screen);
            glm::vec2* vert = new glm::vec2[1024];
            uint32_t vao;
            glGenVertexArrays(1, &vao);
            glBindVertexArray(vao);
            uint32_t vbo;
            glGenBuffers(1, &vbo);
            glBindBuffer(GL_ARRAY_BUFFER, vbo);
            glEnableVertexAttribArray(0);
            glBufferData(GL_ARRAY_BUFFER, 1024 * sizeof(glm::vec2), vert, GL_DYNAMIC_DRAW);
            glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, 0);
            glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
            glEnable(GL_BLEND);
            glfwSetWindowUserPointer(window, this);
            glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
            
            
            tr = new TileRenderer();
            d = new Drawing(tr);
            tr->setScreenSize(screen);
            //glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
            double time, timeo;
            glfwSwapInterval(0);
            
            while(!glfwWindowShouldClose(window))
            {
                timeo = time;
                time = glfwGetTime();
                glClear(GL_COLOR_BUFFER_BIT);
                
                glBindVertexArray(vao);
                glBindBuffer(GL_ARRAY_BUFFER, vbo);
                d->render();
                //tr->renderTile(t);
                print->printfAt(-0.3f, 0.7f, 16.0f, 16.0f, u8"Fps:%03.3f", 1/(time-timeo));
                glfwSwapBuffers(window);
                glfwWaitEvents();
                
            }

            std::cout << "Hello World. I'm Peach." << std::endl;

        }
Example #28
0
void Circle::draw(Drawing &param_d)
{
    param_d.drawCircle(x, y, radius, color);
}
Example #29
0
void FilterImage::render_cairo(FilterSlot &slot)
{
    if (!feImageHref)
        return;

    //cairo_surface_t *input = slot.getcairo(_input);

    // Viewport is filter primitive area (in user coordinates).
    // Note: viewport calculation in non-trivial. Do not rely
    // on get_matrix_primitiveunits2pb().
    Geom::Rect vp = filter_primitive_area( slot.get_units() );
    slot.set_primitive_area(_output, vp); // Needed for tiling

    double feImageX      = vp.min()[Geom::X];
    double feImageY      = vp.min()[Geom::Y];
    double feImageWidth  = vp.width();
    double feImageHeight = vp.height();

    // feImage is suppose to use the same parameters as a normal SVG image.
    // If a width or height is set to zero, the image is not suppose to be displayed.
    // This does not seem to be what Firefox or Opera does, nor does the W3C displacement
    // filter test expect this behavior. If the width and/or height are zero, we use
    // the width and height of the object bounding box.
    Geom::Affine m = slot.get_units().get_matrix_user2filterunits().inverse();
    Geom::Point bbox_00 = Geom::Point(0,0) * m;
    Geom::Point bbox_w0 = Geom::Point(1,0) * m;
    Geom::Point bbox_0h = Geom::Point(0,1) * m;
    double bbox_width = Geom::distance(bbox_00, bbox_w0);
    double bbox_height = Geom::distance(bbox_00, bbox_0h);

    if( feImageWidth  == 0 ) feImageWidth  = bbox_width;
    if( feImageHeight == 0 ) feImageHeight = bbox_height;

    // Internal image, like <use>
    if (from_element) {
        if (!SVGElem) return;

        // TODO: do not recreate the rendering tree every time
        // TODO: the entire thing is a hack, we should give filter primitives an "update" method
        //       like the one for DrawingItems
        document->ensureUpToDate();

        Drawing drawing;
        Geom::OptRect optarea = SVGElem->visualBounds();
        if (!optarea) return;

        unsigned const key = SPItem::display_key_new(1);
        DrawingItem *ai = SVGElem->invoke_show(drawing, key, SP_ITEM_SHOW_DISPLAY);
        if (!ai) {
            g_warning("feImage renderer: error creating DrawingItem for SVG Element");
            return;
        }
        drawing.setRoot(ai);

        Geom::Rect area = *optarea;
        Geom::Affine user2pb = slot.get_units().get_matrix_user2pb();

        /* FIXME: These variables are currently unused.  Why were they calculated?
        double scaleX = feImageWidth / area.width();
        double scaleY = feImageHeight / area.height();
        */

        Geom::Rect sa = slot.get_slot_area();
        cairo_surface_t *out = cairo_image_surface_create(CAIRO_FORMAT_ARGB32,
            sa.width(), sa.height());
        Inkscape::DrawingContext dc(out, sa.min());
        dc.transform(user2pb); // we are now in primitive units
        dc.translate(feImageX, feImageY);
//        dc.scale(scaleX, scaleY);  No scaling should be done

        Geom::IntRect render_rect = area.roundOutwards();
//        dc.translate(render_rect.min());  This seems incorrect

        // Update to renderable state
        drawing.update(render_rect);
        drawing.render(dc, render_rect);
        SVGElem->invoke_hide(key);

        // For the moment, we'll assume that any image is in sRGB color space
        set_cairo_surface_ci(out, SP_CSS_COLOR_INTERPOLATION_SRGB);

        slot.set(_output, out);
        cairo_surface_destroy(out);
        return;
    }

    // External image, like <image>
    if (!image && !broken_ref) {
        broken_ref = true;

        /* TODO: If feImageHref is absolute, then use that (preferably handling the
         * case that it's not a file URI).  Otherwise, go up the tree looking
         * for an xml:base attribute, and use that as the base URI for resolving
         * the relative feImageHref URI.  Otherwise, if document->base is valid,
         * then use that as the base URI.  Otherwise, use feImageHref directly
         * (i.e. interpreting it as relative to our current working directory).
         * (See http://www.w3.org/TR/xmlbase/#resolution .) */
        gchar *fullname = feImageHref;
        if ( !g_file_test( fullname, G_FILE_TEST_EXISTS ) ) {
            // Try to load from relative postion combined with document base
            if( document ) {
                fullname = g_build_filename( document->getBase(), feImageHref, NULL );
            }
        }
        if ( !g_file_test( fullname, G_FILE_TEST_EXISTS ) ) {
            // Should display Broken Image png.
            g_warning("FilterImage::render: Can not find: %s", feImageHref  );
            return;
        }
        image = Inkscape::Pixbuf::create_from_file(fullname);
        if( fullname != feImageHref ) g_free( fullname );

        if ( !image ) {
            g_warning("FilterImage::render: failed to load image: %s", feImageHref);
            return;
        }

        broken_ref = false;
    }

    if (broken_ref) {
        return;
    }

    cairo_surface_t *image_surface = image->getSurfaceRaw();

    Geom::Rect sa = slot.get_slot_area();
    cairo_surface_t *out = cairo_image_surface_create(CAIRO_FORMAT_ARGB32,
        sa.width(), sa.height());

    // For the moment, we'll assume that any image is in sRGB color space
    // set_cairo_surface_ci(out, SP_CSS_COLOR_INTERPOLATION_SRGB);
    // This seemed like a sensible thing to do but it breaks filters-displace-01-f.svg

    cairo_t *ct = cairo_create(out);
    cairo_translate(ct, -sa.min()[Geom::X], -sa.min()[Geom::Y]);

    // now ct is in pb coordinates, note the feWidth etc. are in user units
    ink_cairo_transform(ct, slot.get_units().get_matrix_user2pb());

    // now ct is in the coordinates of feImageX etc.

    // Now that we have the viewport, we must map image inside.
    // Partially copied from sp-image.cpp.

    // Do nothing if preserveAspectRatio is "none".
    if( aspect_align != SP_ASPECT_NONE ) {

        // Check aspect ratio of image vs. viewport
        double feAspect = feImageHeight/feImageWidth;
        double aspect = (double)image->height()/(double)image->width();
        bool ratio = (feAspect < aspect);

        double ax, ay; // Align side
        switch( aspect_align ) {
            case SP_ASPECT_XMIN_YMIN:
                ax = 0.0;
                ay = 0.0;
                break;
            case SP_ASPECT_XMID_YMIN:
                ax = 0.5;
                ay = 0.0;
                break;
            case SP_ASPECT_XMAX_YMIN:
                ax = 1.0;
                ay = 0.0;
                break;
            case SP_ASPECT_XMIN_YMID:
                ax = 0.0;
                ay = 0.5;
                break;
            case SP_ASPECT_XMID_YMID:
                ax = 0.5;
                ay = 0.5;
                break;
            case SP_ASPECT_XMAX_YMID:
                ax = 1.0;
                ay = 0.5;
                break;
            case SP_ASPECT_XMIN_YMAX:
                ax = 0.0;
                ay = 1.0;
                break;
            case SP_ASPECT_XMID_YMAX:
                ax = 0.5;
                ay = 1.0;
                break;
            case SP_ASPECT_XMAX_YMAX:
                ax = 1.0;
                ay = 1.0;
                break;
            default:
                ax = 0.0;
                ay = 0.0;
                break;
        }

        if( aspect_clip == SP_ASPECT_SLICE ) {
            // image clipped by viewbox

            if( ratio ) {
                // clip top/bottom
                feImageY -= ay * (feImageWidth * aspect - feImageHeight);
                feImageHeight = feImageWidth * aspect;
            } else {
                // clip sides
                feImageX -= ax * (feImageHeight / aspect - feImageWidth); 
                feImageWidth = feImageHeight / aspect;
            }

        } else {
            // image fits into viewbox

            if( ratio ) {
                // fit to height
                feImageX += ax * (feImageWidth - feImageHeight / aspect );
                feImageWidth = feImageHeight / aspect;
            } else {
                // fit to width
                feImageY += ay * (feImageHeight - feImageWidth * aspect);
                feImageHeight = feImageWidth * aspect;
            }
        }
    }

    double scaleX = feImageWidth / image->width();
    double scaleY = feImageHeight / image->height();

    cairo_translate(ct, feImageX, feImageY);
    cairo_scale(ct, scaleX, scaleY);
    cairo_set_source_surface(ct, image_surface, 0, 0);
    cairo_paint(ct);
    cairo_destroy(ct);

    slot.set(_output, out);
}
Example #30
0
	void RollBack(){drawing->set_start_pos_not_undoable(prev_pos);}