Esempio n. 1
0
bool ComplexXMLWithMixedElementsAndNodesWithoutAttributes() {
	// Children lists for a and b elements
	nodeList la = nodeList();
	nodeList lc = nodeList();
	Node* b = new TextNode(string("Blorg1"));
	Node* d = new TextNode(string("Blorg2"));
	Node* e = new TextNode(string("Blorg3"));
	la.push_back(b);
	lc.push_back(d);
	ElementName ena = ElementName(string("xml"), string("xml"));
	ElementName enc = ElementName(string("yoyo"), string("yoyo"));
	Node* c = Element::createElement(&enc, NULL, &lc);
	la.push_back(c);
	la.push_back(e);
	Node* a = Element::createElement(&ena, NULL, &la);
	
	
	string expected = "<xml>\nBlorg1\n<yoyo>\nBlorg2\n</yoyo>\nBlorg3\n</xml>";
	string result = a->toXML();
	
	if (result != expected) {
		fail("ComplexXMLWithMixedElementsAndNodesWithoutAttributes (to_xml)", "toXML did not answer expected result." << std::endl
		 << "Expected : " << std::endl << expected << std::endl
		 << "Got: " << std::endl << result << std::endl)
	}
	
	delete a;
	delete b;
	delete c;
	delete d;
	return true;
}
Esempio n. 2
0
bool ComplexXMLWithMixedElementsAndNodesWithAttributes() {
	// Children lists for a and b elements
	nodeList la = nodeList();
	nodeList lc = nodeList();
	Node* b = new TextNode(string("Blorg1"));
	Node* d = new TextNode(string("Blorg2"));
	Node* e = new TextNode(string("Blorg3"));
	la.push_back(b);
	lc.push_back(d);
	attributesMap attrMapa, attrMapc;
	//* Recall: The attributes will be output in alphabetical order, not in the order of addition to the attributesMap
	attrMapa["blorg1"] = "blurp";
	attrMapa["huhu"] = "haha";
	attrMapc["numeric"] = "42";
	attrMapc["vulgar"] = "Hey, you touch my tralala.";
	attrMapc["type"] = "xml";

	ElementName ena = ElementName(string("blorg"), string("xml"));
	ElementName enc = ElementName(string("blorg"), string("yoyo"));
	Node* c = Element::createElement(&enc, &attrMapc, &lc);
	la.push_back(c);
	la.push_back(e);
	Node* a = Element::createElement(&ena, &attrMapa, &la);
	
	string expected = "<xml blorg1=\"blurp\" huhu=\"haha\">\nBlorg1\n<yoyo numeric=\"42\" type=\"xml\" vulgar=\"Hey, you touch my tralala.\">\nBlorg2\n</yoyo>\nBlorg3\n</xml>";
	string result = a->toXML();
	
	if (result != expected) {
		fail("ComplexXMLWithMixedElementsAndNodesWithoutAttributes (to_xml)", "toXML did not answer expected result." << std::endl
		 << "\n------------------------\nExpected : " << std::endl << expected << std::endl
		 << "------------------------\nGot: " << std::endl << result << std::endl)
	}
	
	delete a;
	delete b;
	delete c;
	delete d;
	return true;
}
Esempio n. 3
0
File: CGUI.cpp Progetto: 2asoft/0ad
void CGUI::Xeromyces_ReadSprite(XMBElement Element, CXeromyces* pFile)
{
	CGUISprite* Sprite = new CGUISprite;

	// Get name, we know it exists because of DTD requirements
	CStr name = Element.GetAttributes().GetNamedItem(pFile->GetAttributeID("name"));

	if (m_Sprites.find(name) != m_Sprites.end())
		LOGWARNING("GUI sprite name '%s' used more than once; first definition will be discarded", name.c_str());

	SGUIImageEffects* effects = NULL;

	for (XMBElement child : Element.GetChildNodes())
	{
		CStr ElementName(pFile->GetElementString(child.GetNodeName()));

		if (ElementName == "image")
			Xeromyces_ReadImage(child, pFile, *Sprite);
		else if (ElementName == "effect")
		{
			if (effects)
				LOGERROR("GUI <sprite> must not have more than one <effect>");
			else
			{
				effects = new SGUIImageEffects;
				Xeromyces_ReadEffects(child, pFile, *effects);
			}
		}
		else
			debug_warn(L"Invalid data - DTD shouldn't allow this");
	}

	// Apply the effects to every image (unless the image overrides it with
	// different effects)
	if (effects)
		for (SGUIImage* const& img : Sprite->m_Images)
			if (!img->m_Effects)
				img->m_Effects = new SGUIImageEffects(*effects); // do a copy just so it can be deleted correctly later

	delete effects;

	m_Sprites[name] = Sprite;
}
Esempio n. 4
0
bool simpleToXMLWithoutAttributes() {
	nodeList l = nodeList();
	Node* b = new TextNode(string("Blorg"));
	l.push_back(b);
	ElementName en = ElementName(string("xml"), string("xml"));
	Node* a = Element::createElement(&en, NULL, &l);
	
	string expected = "<xml>\nBlorg\n</xml>";
	string result = a->toXML();
	
	if (result != expected) {
		fail("simpleToXMLWithoutAttributes (to_xml)", "toXML did not answer expected result." << std::endl
		 << "Expected : " << std::endl << expected << std::endl
		 << "Got: " << std::endl << result << std::endl)
	}
	
	delete b;
	delete a;
	return true;
}
IEntityComponent* AbstractEntityFactory::createComponent(tinyxml2::XMLElement* componentNode)
{
	IEntityComponent* newComponent = 0;

	std::string ElementName(componentNode->Value());

	auto iter = _entityComponentCreators.find(ElementName);
	if (iter != _entityComponentCreators.end())
	{
		CreatorFunction creator = iter->second;
		newComponent = (this->*creator)();

		newComponent->initilize(componentNode);
	}
	else
	{
		OutputDebugString("Error No creator function \n");
		//TODO : Error crash
	}

	return newComponent;
}
QString ComponentEditorWidget::commitMetadata() noexcept {
  try {
    QScopedPointer<CmdComponentEdit> cmd(new CmdComponentEdit(*mComponent));
    try {
      // throws on invalid name
      cmd->setName("", ElementName(mUi->edtName->text().trimmed()));
    } catch (const Exception& e) {
    }
    cmd->setDescription("", mUi->edtDescription->toPlainText().trimmed());
    cmd->setKeywords("", mUi->edtKeywords->text().trimmed());
    try {
      // throws on invalid version
      cmd->setVersion(Version::fromString(mUi->edtVersion->text().trimmed()));
    } catch (const Exception& e) {
    }
    cmd->setAuthor(mUi->edtAuthor->text().trimmed());
    cmd->setDeprecated(mUi->cbxDeprecated->isChecked());
    cmd->setCategories(mCategoriesEditorWidget->getUuids());
    cmd->setIsSchematicOnly(mUi->cbxSchematicOnly->isChecked());
    try {
      // throws on invalid prefix
      cmd->setPrefix("", ComponentPrefix(mUi->edtPrefix->text().trimmed()));
    } catch (const Exception& e) {
    }
    cmd->setDefaultValue(mUi->edtDefaultValue->toPlainText().trimmed());
    cmd->setAttributes(mUi->attributesEditorWidget->getAttributeList());

    // Commit all changes.
    mUndoStack->execCmd(cmd.take());  // can throw

    // Reload metadata into widgets to discard invalid input.
    updateMetadata();
  } catch (const Exception& e) {
    return e.getMsg();
  }
  return QString();
}
Esempio n. 7
0
bool simpleToXMLWithAttributes() {
	nodeList l = nodeList();
	Node* b = new TextNode(string("Blorg"));
	l.push_back(b);
	ElementName en = ElementName(string("xml"), string("xml"));
	attributesMap attrMap;
	attrMap["blorg1"] = "blurp";
	attrMap["huhu"] = "haha";
	attrMap["numeric"] = "42";
	Node* a = Element::createElement(&en, &attrMap, &l);
	
	string expected = "<xml blorg1=\"blurp\" huhu=\"haha\" numeric=\"42\">\nBlorg\n</xml>";
	string result = a->toXML();
	
	if (result != expected) {
		fail("simpleToXMLWithAttributes (to_xml)", "toXML did not answer expected result." << std::endl
		 << "Expected : " << std::endl << expected << std::endl
		 << "Got: " << std::endl << result << std::endl)
	}
	
	delete b;
	delete a;
	return true;
}
Esempio n. 8
0
/* Calculate Element forces, stresses, and strain energy
*/
void Interface2D::ForceStress(double *rm,int np,int nfree)
{
	int numnds=NumberNodes();
	int i,j,nst=2*numnds;
    int indg;
	int nameEl=ElementName();
	double Fxy[(MaxElNd-1)*MxFree+1];
	double dx,dy,len,Dn,Dt;
	double pi=3.141592653589793,dsx,dsy,xpxi,ypxi;
    MaterialBase *matl=theMaterials[material-1];
	
	// Get stiffness matrix (and also load nodal coordinates (ce[]) and material props (pr.C[][]))
	Stiffness(np);
	
    // Load nodal displacements into re[]
    int ind=0;
    for(j=1;j<=numnds;j++)
    {	indg=nfree*(nodes[j-1]-1);
        for(i=1;i<=nfree;i++)
            re[++ind]=rm[indg+i];
    }

	// forces in cartensian frame
	for(i=1;i<=nst;i++)
	{	Fxy[i]=0.;
		for(j=1;j<=nst;j++)
		{	if(np!=AXI_SYM)
				Fxy[i]+=se[i][j]*re[j];
			else
				Fxy[i]+=2.*pi*se[i][j]*re[j];
		}
	}
	
	// transfer force to se[][] and get strain energy of interphase
    strainEnergy=0.;
	for(i=1;i<=nst;i++)
	{	strainEnergy+=0.5*re[i]*Fxy[i];
		se[i][7]=Fxy[i];
	}
	for(i=1;i<=numnds;i++)
	{	se[i][2]=0.;
		se[i][4]=0.;
	}
		
	// get normal and shear stresses from interface law
	Dn=matl->pr.C[1][1];
	Dt=matl->pr.C[1][2];
	if(nameEl==LINEAR_INTERFACE)
	{	dx=ce[2].x-ce[1].x;
		dy=ce[2].y-ce[1].y;
		len=sqrt(dx*dx + dy*dy);
		
		// nodes 1 and 4 and then 2 and 3
		InterfaceTraction(1,4,dx,dy,len,Dn,Dt);
		InterfaceTraction(2,3,dx,dy,len,Dn,Dt);
	}
	
	else
	{	dx=(ce[3].x-ce[1].x)/2.;
		dy=(ce[3].y-ce[1].y)/2.;
		dsx=ce[1].x+ce[3].x-2.*ce[2].x;
		dsy=ce[1].y+ce[3].y-2.*ce[2].y;
		
		// nodes 1 and 6
		xpxi=dx-dsx;
		ypxi=dy-dsy;
		len=sqrt(xpxi*xpxi + ypxi*ypxi);
		InterfaceTraction(1,6,xpxi,ypxi,len,Dn,Dt);
		
		// nodes 2 and 5
		xpxi=dx;
		ypxi=dy;
		len=sqrt(xpxi*xpxi + ypxi*ypxi);
		InterfaceTraction(2,5,xpxi,ypxi,len,Dn,Dt);
		
		// nodes 3 and 4
		xpxi=dx+dsx;
		ypxi=dy+dsy;
		len=sqrt(xpxi*xpxi + ypxi*ypxi);
		InterfaceTraction(3,4,xpxi,ypxi,len,Dn,Dt);
	}
}
Esempio n. 9
0
bool SES_DrawWire::startPositioning(Schematic& schematic, const Point& pos,
                                    SI_NetPoint* fixedPoint) noexcept {
  try {
    // start a new undo command
    Q_ASSERT(mSubState == SubState_Idle);
    mUndoStack.beginCmdGroup(tr("Draw Wire"));
    mSubState = SubState_PositioningNetPoint;

    // determine the fixed anchor (create one if it doesn't exist already)
    NetSignal*                      netsignal  = nullptr;
    SI_NetSegment*                  netsegment = nullptr;
    tl::optional<CircuitIdentifier> forcedNetName;
    if (fixedPoint) {
      mFixedStartAnchor = fixedPoint;
      netsegment        = &fixedPoint->getNetSegment();
    } else if (SI_NetPoint* netpoint = findNetPoint(schematic, pos)) {
      mFixedStartAnchor = netpoint;
      netsegment        = &netpoint->getNetSegment();
    } else if (SI_SymbolPin* pin = findSymbolPin(schematic, pos)) {
      mFixedStartAnchor = pin;
      netsegment        = pin->getNetSegmentOfLines();
      netsignal         = pin->getCompSigInstNetSignal();
      if (pin->getComponentSignalInstance()) {
        QString name =
            pin->getComponentSignalInstance()->getForcedNetSignalName();
        try {
          if (!name.isEmpty())
            forcedNetName = CircuitIdentifier(name);  // can throw
        } catch (const Exception& e) {
          QMessageBox::warning(
              &mEditor, tr("Invalid net name"),
              QString(tr("Could not apply the forced net name because '%1' is "
                         "not a valid net name."))
                  .arg(name));
        }
      }
    } else if (SI_NetLine* netline = findNetLine(schematic, pos)) {
      // split netline
      netsegment = &netline->getNetSegment();
      QScopedPointer<CmdSchematicNetSegmentAddElements> cmdAdd(
          new CmdSchematicNetSegmentAddElements(*netsegment));
      mFixedStartAnchor = cmdAdd->addNetPoint(pos);
      cmdAdd->addNetLine(*mFixedStartAnchor, netline->getStartPoint());
      cmdAdd->addNetLine(*mFixedStartAnchor, netline->getEndPoint());
      mUndoStack.appendToCmdGroup(cmdAdd.take());  // can throw
      QScopedPointer<CmdSchematicNetSegmentRemoveElements> cmdRemove(
          new CmdSchematicNetSegmentRemoveElements(*netsegment));
      cmdRemove->removeNetLine(*netline);
      mUndoStack.appendToCmdGroup(cmdRemove.take());  // can throw
    }

    // find netsignal if name is given
    if (forcedNetName) {
      netsignal = mCircuit.getNetSignalByName(**forcedNetName);
    }

    // create new netsignal if none found
    if ((!netsegment) && (!netsignal)) {
      // get or add netclass with the name "default"
      NetClass* netclass = mCircuit.getNetClassByName(ElementName("default"));
      if (!netclass) {
        CmdNetClassAdd* cmd =
            new CmdNetClassAdd(mCircuit, ElementName("default"));
        mUndoStack.appendToCmdGroup(cmd);  // can throw
        netclass = cmd->getNetClass();
        Q_ASSERT(netclass);
      }
      // add new netsignal
      CmdNetSignalAdd* cmd =
          new CmdNetSignalAdd(mCircuit, *netclass, forcedNetName);
      mUndoStack.appendToCmdGroup(cmd);  // can throw
      netsignal = cmd->getNetSignal();
      Q_ASSERT(netsignal);
    }

    // create new netsegment if none found
    if (!netsegment) {
      // connect pin if needed
      if (SI_SymbolPin* pin = dynamic_cast<SI_SymbolPin*>(mFixedStartAnchor)) {
        Q_ASSERT(pin->getComponentSignalInstance());
        mUndoStack.appendToCmdGroup(new CmdCompSigInstSetNetSignal(
            *pin->getComponentSignalInstance(), netsignal));
      }
      // add net segment
      Q_ASSERT(netsignal);
      CmdSchematicNetSegmentAdd* cmd =
          new CmdSchematicNetSegmentAdd(schematic, *netsignal);
      mUndoStack.appendToCmdGroup(cmd);  // can throw
      netsegment = cmd->getNetSegment();
    }

    // add netpoint if none found
    Q_ASSERT(netsegment);
    CmdSchematicNetSegmentAddElements* cmd =
        new CmdSchematicNetSegmentAddElements(*netsegment);
    if (!mFixedStartAnchor) {
      mFixedStartAnchor = cmd->addNetPoint(pos);
    }
    Q_ASSERT(mFixedStartAnchor);

    // add more netpoints & netlines
    SI_NetPoint* p2 = cmd->addNetPoint(pos);
    Q_ASSERT(p2);  // second netpoint
    SI_NetLine* l1 = cmd->addNetLine(*mFixedStartAnchor, *p2);
    Q_ASSERT(l1);  // first netline
    SI_NetPoint* p3 = cmd->addNetPoint(pos);
    Q_ASSERT(p3);  // third netpoint
    SI_NetLine* l2 = cmd->addNetLine(*p2, *p3);
    Q_ASSERT(l2);                      // second netline
    mUndoStack.appendToCmdGroup(cmd);  // can throw

    // update members
    mPositioningNetPoint1 = p2;
    mPositioningNetLine1  = l1;
    mPositioningNetPoint2 = p3;
    mPositioningNetLine2  = l2;

    // properly place the new netpoints/netlines according the current wire mode
    updateNetpointPositions(pos);

    // highlight all elements of the current netsignal
    mCircuit.setHighlightedNetSignal(&netsegment->getNetSignal());

    return true;
  } catch (const Exception& e) {
    QMessageBox::critical(&mEditor, tr("Error"), e.getMsg());
    if (mSubState != SubState_Idle) {
      abortPositioning(false);
    }
    return false;
  }
}
Esempio n. 10
0
bool testDocumentToXML() {
    
        Node* p_text = new TextNode(string("Comme l'écriture d'un compilateur est une tâche fort complexe, le programmateur a tout intérêt à travailler."));
        Node* titre_text = new TextNode(string("Réalisation d'un compilateur"));
        Node* resume_text = new TextNode(string("Ceci est extrait du livre \"Réaliser un compilateur : les outils Lex et Yacc\" de Nino Silverio."));
        
        nodeList p_children = nodeList();
        nodeList titre_children = nodeList();
        nodeList resume_children = nodeList();
        nodeList section_children = nodeList();
        nodeList chapitre_children = nodeList();
        nodeList rapport_children = nodeList();
        
        ElementName titre = ElementName(string(""), string("titre"));
        ElementName p = ElementName(string("p"), string("p"));
        ElementName section = ElementName(string("section"), string("section"));
        ElementName chapitre = ElementName(string("chapitre"), string("resume"));
        ElementName resume = ElementName(string("resume"), string("chapitre"));
        ElementName rapport = ElementName(string("rapport"), string("rapport"));
        
         
        p_children.push_back(p_text);
	Node* p_elem = Element::createElement(&p, NULL, &p_children);
        
        titre_children.push_back(titre_text);
        Node* titre_elem = Element::createElement(&titre, NULL, &titre_children);
        
        section_children.push_back(titre_elem);
        section_children.push_back(p_elem);
        Node* section_elem = Element::createElement(&section, NULL, &section_children);
        
        chapitre_children.push_back(section_elem);
        Node* chapitre_elem = Element::createElement(&chapitre, NULL, &chapitre_children);
        
        resume_children.push_back(resume_text);
        Node* resume_elem = Element::createElement(&resume, NULL, &resume_children);
        
        rapport_children.push_back(resume_elem);
        rapport_children.push_back(chapitre_elem);
        Node* rapport_elem = Element::createElement(&rapport, NULL, &rapport_children);
        
        
        string line;
        string text = "";
        ifstream xmlfile;
        const char * filename = "../../tests/testfile1.xml";
        xmlfile.open(filename, ios::in);
        if(xmlfile.is_open()) { 
                while (getline (xmlfile,line)){
                        //getline (xmlfile,myline,'\t');
                    text+=line;
                }
        }
        else {
            fail("testDocumentToXML", "Failed to open xml file in ifstream");
        }     
                
       //having problems with encoding, i will write outputs to a file
       ofstream outfile;
       outfile.open("../../tests/output.txt", ios::trunc);
       if (outfile.is_open()){ 
           outfile<<rapport_elem->toXML();
       }
       else {
           fail("testDocumentToXML", "Failed to write output file");
       }
       
//	
//	if (result != expected) {
//		fail("simpleToXMLWithAttributes (to_xml)", "toXML did not answer expected result." << std::endl
//		 << "Expected : " << std::endl << expected << std::endl
//		 << "Got: " << std::endl << result << std::endl)
//	}
//        	
//	delete b;
//	delete a;
       xmlfile.close();
       outfile.close();
	return true;
}
Esempio n. 11
0
File: CGUI.cpp Progetto: 2asoft/0ad
void CGUI::Xeromyces_ReadImage(XMBElement Element, CXeromyces* pFile, CGUISprite& parent)
{
	SGUIImage* Image = new SGUIImage;

	Image->m_TextureSize = CClientArea(CRect(0, 0, 0, 0), CRect(0, 0, 100, 100));
	Image->m_Size = CClientArea(CRect(0, 0, 0, 0), CRect(0, 0, 100, 100));

	// TODO Gee: Setup defaults here (or maybe they are in the SGUIImage ctor)

	for (XMBAttribute attr : Element.GetAttributes())
	{
		CStr attr_name(pFile->GetAttributeString(attr.Name));
		CStrW attr_value(attr.Value.FromUTF8());

		if (attr_name == "texture")
		{
			Image->m_TextureName = VfsPath("art/textures/ui") / attr_value;
		}
		else if (attr_name == "size")
		{
			CClientArea ca;
			if (!GUI<CClientArea>::ParseString(attr_value, ca))
				LOGERROR("GUI: Error parsing '%s' (\"%s\")", attr_name, utf8_from_wstring(attr_value));
			else
				Image->m_Size = ca;
		}
		else if (attr_name == "texture_size")
		{
			CClientArea ca;
			if (!GUI<CClientArea>::ParseString(attr_value, ca))
				LOGERROR("GUI: Error parsing '%s' (\"%s\")", attr_name, utf8_from_wstring(attr_value));
			else
				Image->m_TextureSize = ca;
		}
		else if (attr_name == "real_texture_placement")
		{
			CRect rect;
			if (!GUI<CRect>::ParseString(attr_value, rect))
				LOGERROR("GUI: Error parsing '%s' (\"%s\")", attr_name, utf8_from_wstring(attr_value));
			else
				Image->m_TexturePlacementInFile = rect;
		}
		else if (attr_name == "cell_size")
		{
			CSize size;
			if (!GUI<CSize>::ParseString(attr_value, size))
				LOGERROR("GUI: Error parsing '%s' (\"%s\")", attr_name, utf8_from_wstring(attr_value));
			else
				Image->m_CellSize = size;
		}
		else if (attr_name == "fixed_h_aspect_ratio")
		{
			float val;
			if (!GUI<float>::ParseString(attr_value, val))
				LOGERROR("GUI: Error parsing '%s' (\"%s\")", attr_name, utf8_from_wstring(attr_value));
			else
				Image->m_FixedHAspectRatio = val;
		}
		else if (attr_name == "round_coordinates")
		{
			bool b;
			if (!GUI<bool>::ParseString(attr_value, b))
				LOGERROR("GUI: Error parsing '%s' (\"%s\")", attr_name, utf8_from_wstring(attr_value));
			else
				Image->m_RoundCoordinates = b;
		}
		else if (attr_name == "wrap_mode")
		{
			if (attr_value == L"repeat")
				Image->m_WrapMode = GL_REPEAT;
			else if (attr_value == L"mirrored_repeat")
				Image->m_WrapMode = GL_MIRRORED_REPEAT;
			else if (attr_value == L"clamp_to_edge")
				Image->m_WrapMode = GL_CLAMP_TO_EDGE;
			else
				LOGERROR("GUI: Error parsing '%s' (\"%s\")", attr_name, utf8_from_wstring(attr_value));
		}
		else if (attr_name == "z_level")
		{
			float z_level;
			if (!GUI<float>::ParseString(attr_value, z_level))
				LOGERROR("GUI: Error parsing '%s' (\"%s\")", attr_name, utf8_from_wstring(attr_value));
			else
				Image->m_DeltaZ = z_level/100.f;
		}
		else if (attr_name == "backcolor")
		{
			CColor color;
			if (!GUI<CColor>::ParseString(attr_value, color))
				LOGERROR("GUI: Error parsing '%s' (\"%s\")", attr_name, utf8_from_wstring(attr_value));
			else
				Image->m_BackColor = color;
		}
		else if (attr_name == "bordercolor")
		{
			CColor color;
			if (!GUI<CColor>::ParseString(attr_value, color))
				LOGERROR("GUI: Error parsing '%s' (\"%s\")", attr_name, utf8_from_wstring(attr_value));
			else
				Image->m_BorderColor = color;
		}
		else if (attr_name == "border")
		{
			bool b;
			if (!GUI<bool>::ParseString(attr_value, b))
				LOGERROR("GUI: Error parsing '%s' (\"%s\")", attr_name, utf8_from_wstring(attr_value));
			else
				Image->m_Border = b;
		}
		else
			debug_warn(L"Invalid data - DTD shouldn't allow this");
	}

	// Look for effects
	for (XMBElement child : Element.GetChildNodes())
	{
		CStr ElementName(pFile->GetElementString(child.GetNodeName()));
		if (ElementName == "effect")
		{
			if (Image->m_Effects)
				LOGERROR("GUI <image> must not have more than one <effect>");
			else
			{
				Image->m_Effects = new SGUIImageEffects;
				Xeromyces_ReadEffects(child, pFile, *Image->m_Effects);
			}
		}
		else
			debug_warn(L"Invalid data - DTD shouldn't allow this");
	}

	parent.AddImage(Image);
}