Exemple #1
0
void adjustNode(struct btreeNode *myNode, int pos) {
      if (!pos) {
              if (myNode->link[1]->count > MIN) {
                      doLeftShift(myNode, 1);
              } else {
                      mergeNodes(myNode, 1);
              }
      } else {
              if (myNode->count != pos) {
                      if(myNode->link[pos - 1]->count > MIN) {
                              doRightShift(myNode, pos);
                      } else {
                              if (myNode->link[pos + 1]->count > MIN) {
                                      doLeftShift(myNode, pos + 1);
                              } else {
                                      mergeNodes(myNode, pos);
                              }
                      }
              } else {
                      if (myNode->link[pos - 1]->count > MIN)
                              doRightShift(myNode, pos);
                      else
                              mergeNodes(myNode, pos);
              }
      }
}
Exemple #2
0
void visit(char *key, struct node *p)
{
    if (1 == p->is_real)
    {
        if (0 == p->child_num)
        {
            int i;
            for (i = 0; i < p->parent->child_num; i++)
            {
                if (!strcmp(p->parent->child[i]->key, p->key))
                {
                    int j;
                    for  (j = i; j < p->parent->child_num - 1; j++)
                        strcpy(p->parent->child[j], p->parent->child[j + 1]);
                    FREE(p->parent->child[p->parent->child_num - 1]);
                    p->parent->child[p->parent->child_num - 1] = NULL;
                    p->parent->child_num--;
                }
            }
            if (1 == p->parent->child_num && 0 == p->parent->is_real && 0 == p->is_root)
                mergeNodes(p->parent, p->parent->child[0]);
        }
        else if (1 == p->child_num)
            mergeNodes(p, p->child[0]);
        else
            p->is_real = 0;
    }
    return;
}
void CreateAutodiffSubgraphs(Block * block, size_t threshold) {
  // This implementation is not optimal, but it is simple.
  // It just scans through the list in order looking for runs of
  // differentiable ops, and then grouping them together when
  // it hits the first non-differentiable op.
  // It cannot handle things like:
  // a = f(x, y)
  // b = black_box(a)
  // c = g(a)
  // where you could group {f, g} together if the nodes were in a different
  // topological order

  // a better strategy would be to try to treat this like a fusion problem
  // and group maximal groups

  std::vector<Node*> groupable;
  for(Node * node : block->nodes()) { // Note: nodes() iterator stays valid since it is
                            // always pointing _after_ the nodes that mergeNodes
                            // mutates.
    if(isDifferentiable(node)) {
      groupable.push_back(node);
    } else {
      if(groupable.size() >= threshold) {
        mergeNodes(block, kGraphExecutor, groupable);
      }
      groupable.clear();
      for (Block * sub_block : node->blocks()) {
        CreateAutodiffSubgraphs(sub_block, threshold);
      }
    }
  }
  if(groupable.size() >= threshold) {
    mergeNodes(block, kGraphExecutor, groupable);
  }
}
Exemple #4
0
void mergeNodes(pugi::xml_node toNode, pugi::xml_node& fromNode)
{
  // Base case = both nodes are text nodes
  pugi::xml_text fromNodeText = fromNode.text();
  pugi::xml_text toNodeText = toNode.text();
  if (fromNodeText && toNodeText) {
    SBLog::info() << "Overwriting template value of \"" << toNode.name() << "\" from \"" << toNodeText.get() << "\" to \"" << fromNodeText.get() << "\"." << std::endl;
    toNodeText.set(fromNodeText.get());
    return;
  }

  // Calculate number of children in toNode
  unsigned maxDistance = std::distance(toNode.begin(), toNode.end());

  // Merge children
  for (pugi::xml_node fromNodeChild = fromNode.first_child(); fromNodeChild; fromNodeChild = fromNodeChild.next_sibling()) {
    // Find appropriate merge point
    pugi::xml_node toNodeChild = findSimilarNode(fromNodeChild, toNode, maxDistance);
    if (toNodeChild) {
      mergeNodes(toNodeChild, fromNodeChild);
    } else {
      toNode.append_copy(fromNodeChild);
    }
  }

  // Erase fromNode
  removeNode(fromNode);
}
Exemple #5
0
void DependencyDigraph::cleanUpGraph(std::vector<Variable*>& vars) {

    //    for (std::shared_ptr<variableNode> vn : variable_nodes) {
    for (Variable* iv : vars) {


        //        
        if (iv->isDef()) {
            std::shared_ptr<variableNode> vn = variable_nodes.at(iv->getID());
            //            if (iv)
            //            vn->update;

            mergeNodes(vn, invariant_nodes.at(iv->getOneway()->getID()));

            //            vn.~__shared_ptr();

        }
    }
    //    
    //    unsigned timestampCounter = 0;
    //    for (IntegerVariable* iv : vars) {
    //        if (!iv->isFixed() && !iv->isDef()) {
    //            variableNode vn = variable_nodes.at(iv->getID());
    //        }
    //    }

}
css_RuleList optimize(css_RuleList list, char* filename) {
	// merge nodes with same selector
	list = mergeNodes(list);
	list = removeDoubleDeclarations(list);
	list = mergeDoubleDeclarations(list);
	
	return list;
}
Exemple #7
0
void VCProject::writeProjectItems(pugi::xml_node& node) const
{
  pugi::xml_node tempNode = node.parent().append_child("Temp");
  for (auto item : m_items) {
    item->writeDescription(tempNode);
  }
  mergeNodes(node, tempNode);
}
/* Insert a node somewhere in the linked list
 *
 * node    The node to insert
 *
 * @discussion If the node matches one already in the list, then "node" is
 * freed.
 */
void insertNode(InDel *node, int k) {
    int direction;

    //Deal with the first node
    if(lastTargetNode == firstTargetNode && firstTargetNode->next == NULL) {
        insertAfter(node, firstTargetNode);
        lastTargetNode = node;
        return;
    }

    direction = TargetNodeCmp(node, lastTargetNode, k);

    //Always come from the left
    while(direction>=0 && lastTargetNode->next != NULL) {
        lastTargetNode = lastTargetNode->next;
        direction = TargetNodeCmp(node, lastTargetNode, k);
    }
    if(direction > 0) {
        insertAfter(node, lastTargetNode);
        lastTargetNode = node;
        return;
    } else if(direction == 0) {
        mergeNodes(node, k);
        destroyNode(node);
        return;
    }

    assert(direction < 0);
    while(lastTargetNode->prev != NULL && direction < 0) {
        lastTargetNode = lastTargetNode->prev;
        direction = TargetNodeCmp(node, lastTargetNode, k);
    }
    if(direction != 0) {
        insertAfter(node, lastTargetNode);
        lastTargetNode = node;
        return;
    } else if(direction == 0) {
        mergeNodes(node, k);
        destroyNode(node);
        return;
    }
    assert(1==0);
}
Exemple #9
0
void VCProject::writeBuildExtensionTargets(pugi::xml_node& node) const
{
  pugi::xml_node tempNode = node.parent().append_child("Temp");
  for (auto ext : m_buildExtensions) {
    if (sb_fextension(ext) == "targets") {
      pugi::xml_node propsFile = tempNode.append_child("Import");
      propsFile.append_attribute("Project") = ext.c_str();
    }
  }
  mergeNodes(node, tempNode);
}
Exemple #10
0
void VCProject::writeSharedProjects(pugi::xml_node& node) const
{
  std::string projectPath = getPath();
  std::string projectDir = sb_dirname(projectPath);

  pugi::xml_node tempNode = node.parent().append_child("Temp");
  for (auto sproj : m_sharedProjects) {
    std::string sprojRelativePath = getRelativePath(projectDir, sproj->getPath());
    pugi::xml_node importProj = tempNode.append_child("Import");
    importProj.append_attribute("Project") = sprojRelativePath.c_str();
    importProj.append_attribute("Label") = "Shared";
  }
  mergeNodes(node, tempNode);
}
Exemple #11
0
void VCProject::writeFilterItemDescriptions(pugi::xml_node& node) const
{
  pugi::xml_node tempNode = node.parent().append_child("Temp");
  for (auto item : m_items) {
    std::string itemName = item->getItemName();
    std::string includePath = item->getIncludePath();
    std::string filterPath = item->getFilterPath();

    pugi::xml_node fItem = tempNode.append_child(itemName.c_str());
    fItem.append_attribute("Include") = includePath.c_str();
    if (!filterPath.empty() && filterPath != ".") {
      appendNodeWithText(fItem, "Filter", winPath(filterPath));
    }
  }
  mergeNodes(node, tempNode);
}
Exemple #12
0
	bool SettingsManager::loadSettingsFile(const std::string& _fileName)
	{
		pugi::xml_document doc;
		pugi::xml_parse_result result = doc.load_file(_fileName.c_str());

		if (result)
		{
			if (std::string(doc.first_child().name()) == std::string(mDocument->document_element().name()))
				mergeNodes(mDocument->document_element(), doc.first_child());
		}
		else
		{
			// логировать если это ошибка формата xml
		}

		return result;
	}
void VCProjectConfiguration::writeProperties(pugi::xml_node& proto) const
{
  // Insert nodes after the bookmark
  pugi::xml_node parent = proto.parent();
  pugi::xml_node prevSibling = proto;

  for (auto platform : m_platforms) {
    std::string configCond = getVSConfigurationPlatformCond(m_name, platform.first);
    pugi::xml_node configPropsGroup = parent.insert_copy_before(proto, prevSibling);
    configPropsGroup.append_attribute("Condition") = configCond.c_str();

    pugi::xml_node tempNode = proto.parent().append_child("Temp");
    writePropertiesMap(platform.second->getProperties(), tempNode);
    mergeNodes(configPropsGroup, tempNode);

    prevSibling = configPropsGroup;
  }
}
Exemple #14
0
	void SettingsManager::mergeNodes(pugi::xml_node _nodeTarget, pugi::xml_node _nodeSource)
	{
		bool listElement = MyGUI::utility::endWith(_nodeTarget.name(), ".List");

		// затираем текст у цели потому что любое значение текста источника является конечным
		pugi::xml_node targetTextNode = _nodeTarget.first_child();
		if (!targetTextNode.empty() && targetTextNode.type() == pugi::node_pcdata)
			targetTextNode.set_value("");

		pugi::xml_node sourceTextNode = _nodeSource.first_child();
		if (!sourceTextNode.empty() && sourceTextNode.type() == pugi::node_pcdata)
		{
			targetTextNode = _nodeTarget.first_child();
			if (targetTextNode.empty())
				targetTextNode = _nodeTarget.append_child(pugi::node_pcdata);
			targetTextNode.set_value(sourceTextNode.value());
		}

		for (pugi::xml_node::iterator child = _nodeSource.begin(); child != _nodeSource.end(); child ++)
		{
			if ((*child).type() != pugi::node_element)
				continue;

			pugi::xml_node targetChildNode;

			if (listElement)
			{
				targetChildNode = _nodeTarget.append_child((*child).name());
			}
			else
			{
				targetChildNode = _nodeTarget.child((*child).name());
				if (targetChildNode.empty())
					targetChildNode = _nodeTarget.append_child((*child).name());
			}

			mergeAttributes(targetChildNode, (*child));
			mergeNodes(targetChildNode, (*child));
		}
	}
Exemple #15
0
void VCProject::writeFilterDescriptions(pugi::xml_node& node) const
{
  StringSet filters;
  for (auto item : m_items) {
    recordFilterPath(item->getFilterPath(), filters);
  }

  pugi::xml_node tempNode = node.parent().append_child("Temp");
  for (auto filter : filters) {
    // Generate a unique id
    std::string id = sole::uuid4().str();

    // Fix up the filter path to be Windows-style
    std::string winFilterPath = winPath(filter);

    // Create a filter description node
    pugi::xml_node filterDesc = tempNode.append_child("Filter");
    filterDesc.append_attribute("Include") = winFilterPath.c_str();
    appendNodeWithText(filterDesc, "UniqueIdentifier", formatVSGUID(id));
  }
  mergeNodes(node, tempNode);
}
Exemple #16
0
int chckAtlasPack(chckAtlas *atlas, const int forcePowerOfTwo, const int onePixelBorder, unsigned int *outWidth, unsigned int *outHeight)
{
   assert(atlas);

   if (onePixelBorder) {
      unsigned int i;
      for (i = 0; i != atlas->textureCount; ++i) {
         struct texture *t = &atlas->textures[i];
         t->rect.w += 2;
         t->rect.h += 2;
      }
      atlas->longestEdge += 2;
   }

   if (forcePowerOfTwo)
      atlas->longestEdge = nextPow2(atlas->longestEdge);

   unsigned int width = atlas->longestEdge;
   unsigned int count = (unsigned int)((float)atlas->totalArea/(atlas->longestEdge * atlas->longestEdge) + 0.5f);
   unsigned int height = (count + 2) * atlas->longestEdge;

   if (forcePowerOfTwo)
      height = nextPow2(height);

   if (width > height && height != width * 0.5f) {
      height = width * 0.5f;
      width *= 0.5f;
      checkDimensions(atlas, &width, &height);
   } else if (height > width && width != height * 0.5f) {
      width = height * 0.5f;
      height *= 0.5f;
      checkDimensions(atlas, &width, &height);
   }

   atlas->debugCount = 0;
   atlasNodeNew(atlas, 0, 0, width, height);

   unsigned int i;
   for (i = 0; i != atlas->textureCount; ++i) {
      unsigned int i2;
      unsigned int longestEdge = 0, mostArea = 0, index = 0;
      for(i2 = 0; i2 != atlas->textureCount; ++i2) {
         struct texture *t = &atlas->textures[i2];
         if (t->placed)
            continue;

         if (t->longestEdge > longestEdge) {
            mostArea = t->area;
            longestEdge = t->longestEdge;
            index = i2;
         } else if (t->longestEdge == longestEdge && t->area > mostArea) {
            mostArea = t->area;
            index = i2;
         }
      }

      unsigned int edgeCount = 0;
      unsigned int leastY = UINT_MAX;
      unsigned int leastX = UINT_MAX;
      struct texture *t = &atlas->textures[index];
      struct node *previousBestFit = NULL;
      struct node *bestFit = NULL;
      struct node *previous = NULL;
      struct node *search = atlas->freeList;

      while (search) {
         unsigned int ec;
         if (nodeFits(search, t->rect.w, t->rect.h, &ec)) {
            if (ec == 2) {
               previousBestFit = previous;
               bestFit = search;
               edgeCount = ec;
               break;
            } else if (search->rect.y < leastY) {
               leastY = search->rect.y;
               leastX = search->rect.x;
               previousBestFit = previous;
               bestFit = search;
               edgeCount = ec;
            } else if (search->rect.y == leastY && search->rect.x < leastX) {
               leastX = search->rect.x;
               previousBestFit = previous;
               bestFit = search;
               edgeCount = ec;
            }
         }
         previous = search;
         search = search->next;
      }

      /* should always find a fit */
      assert(bestFit);

      switch (edgeCount) {
         case 0:
            if (t->longestEdge <= bestFit->rect.w) {
               int flipped = 0;
               unsigned int width = t->rect.w;
               unsigned int height = t->rect.h;

               if (width > height) {
                  width = t->rect.h;
                  height = t->rect.w;
                  flipped  = 1;
               }

               texturePlace(t, bestFit->rect.x, bestFit->rect.y, flipped);
               atlasNodeNew(atlas, bestFit->rect.x, bestFit->rect.y + height, bestFit->rect.w, bestFit->rect.h - height);

               bestFit->rect.x += width;
               bestFit->rect.w -= width;
               bestFit->rect.h = height;
            } else {
               assert(t->longestEdge <= bestFit->rect.h);
               int flipped  = 0;
               unsigned int width = t->rect.w;
               unsigned int height = t->rect.h;

               if (width > height) {
                  width = t->rect.h;
                  height = t->rect.w;
                  flipped  = 1;
               }

               texturePlace(t, bestFit->rect.x, bestFit->rect.y, flipped);
               atlasNodeNew(atlas, bestFit->rect.x + width, bestFit->rect.y, bestFit->rect.w - width, bestFit->rect.h);

               bestFit->rect.y += height;
               bestFit->rect.h -= height;
               bestFit->rect.w = width;
            }
            break;
         case 1:
            if (t->rect.w == bestFit->rect.w) {
               texturePlace(t, bestFit->rect.x, bestFit->rect.y, 0);
               bestFit->rect.y += t->rect.h;
               bestFit->rect.h -= t->rect.h;
            } else if (t->rect.h == bestFit->rect.h) {
               texturePlace(t, bestFit->rect.x, bestFit->rect.y, 0);
               bestFit->rect.x += t->rect.w;
               bestFit->rect.w -= t->rect.w;
            } else if (t->rect.w == bestFit->rect.h) {
               texturePlace(t, bestFit->rect.x, bestFit->rect.y, 1);
               bestFit->rect.x += t->rect.h;
               bestFit->rect.w -= t->rect.h;
            } else if (t->rect.h == bestFit->rect.w) {
               texturePlace(t, bestFit->rect.x, bestFit->rect.y, 1);
               bestFit->rect.y += t->rect.w;
               bestFit->rect.h -= t->rect.w;
            }
            break;
         case 2:
            {
               int flipped = (t->rect.w != bestFit->rect.w || t->rect.h != bestFit->rect.h);
               texturePlace(t, bestFit->rect.x, bestFit->rect.y, flipped);

               if (previousBestFit) {
                  previousBestFit->next = bestFit->next;
               } else {
                  atlas->freeList = bestFit->next;
               }

               if (bestFit)
                  free(bestFit);
            }
            break;
      }

      /* merge as much as we can */
      while (mergeNodes(atlas));
   }

   width = 0, height = 0;
   for(i = 0; i < atlas->textureCount; ++i) {
      struct texture *t = &atlas->textures[i];
      if (onePixelBorder) {
         t->rect.w -= 2;
         t->rect.h -= 2;
         t->rect.x += 1;
         t->rect.y += 1;
      }

      unsigned int x = (t->flipped ? t->rect.x + t->rect.h : t->rect.x + t->rect.w);
      unsigned int y = (t->flipped ? t->rect.y + t->rect.w : t->rect.y + t->rect.h);
      width = (x > width ? x : width);
      height = (y > height ? y : height);
   }

   if (forcePowerOfTwo) {
      width = nextPow2(width);
      height = nextPow2(height);
   }

   if (outWidth) *outWidth = width;
   if (outHeight) *outHeight = height;
   return (width * height) - atlas->totalArea;
}
Exemple #17
0
void buildGraph(ChainsContainer & chains)
{
#if 0
	//find the max_size of chains
	int max_size=0;
	for (int i=0;i<chains.size();i++)
	{
		int curr_size=chains.at(i)->m_chain.size();
		if (curr_size>max_size)
			max_size=curr_size;
	}
	//fill info with begin()
	QVector<QVector<TmpChainInfo> > info;
	QVector<TmpChainInfo> traversal_leader_pos;
	QVector<int> chains_left;
	QVector<TmpChainInfo> temp;
	for (int i=0;i<chains.size();i++)
	{
		TmpChainInfo t;
		t.curr_itr=chains.at(i)->m_chain.begin();
		temp.push_back(t);
		chains_left.push_back(i);
	}
	traversal_leader_pos=temp;
	info.push_back(temp);
	//since temp has all at first position push to entry of 0, the rest must be moved one pos then pushed to all rest
	for (int j=0;j<chains.size();j++)
		++temp[j].curr_itr;
	for (int i=1;i<chains.size();i++)
		info.push_back(temp);

	while (chains_left.count()>1)
	{
		for (int i=0;i<chains_left.count();i++)
		{
			int c1=chains_left[i];
			ChainNarratorNodeIterator & it=traversal_leader_pos[c1].curr_itr;
			for (int j=0;j<chains_left.count();j++)
			{
				int c2=chains_left[j];
				if (c1!=c2)
				{
					if (!info[c1][c2].finished())
						info[c1][c2].checkStepEqualChains(it);
				}
			}
			++it;
			if (traversal_leader_pos[c1].finished())
				chains_left.remove(c1);
		}
	}


	/*
	for (int c1=0;c1<chains.count();c1++)
	{
		ChainNarratorNodeIterator it1(chains.at(c1)->m_chain.begin());
		for (int c2=0;c2<chains.count();c2++)
		{
			ChainNarratorNodeIterator it2(chains.at(c2)->m_chain.begin());//if it is not the first check, then already checked
			if (c1!=0)
				++it2;
			for (int j=(c1==0?0:1);j<radius && j<chains.at(c2)->m_chain.size();j++)
			{
				assert(it2.getIndex()==j);
				if (equal(it1.getNarrator(),it2.getNarrator())>=threshold)
				{
					new GraphNarratorNode(it1,it2); //dont delete
					break;
				}
				++it2;
			}
		}
	}
	for (int n=1;n<max_size;n++)
	{
		for (int c1=0;c1<chains.count();c1++)
		{
			ChainNarratorNodeIterator it1(chains.at(c1)->m_chain.begin()+n);
			for (int c2=n;c2<chains.count();c2++)
			{
				ChainNarratorNodeIterator it2(chains.at(c2)->m_chain.begin());//if it is not the first check, then already checked
				if (c1!=0)
					++it2;
				for (int j=(c1==0?0:1);j<radius;j++)
				{
					assert(it2.getIndex()==j);
					if (equal(it1.getNarrator(),it2.getNarrator())>=threshold)
					{
						new GraphNarratorNode(it1,it2); //dont delete
						break;
					}
					++it2;
				}
			}
		}
	}*/
#else
	int needle=0, offset=-1;
	for (int i=0;i<chains.size();i++)
	{
		Chain & c1= *chains.at(i);
		for (int k=i+1;k<chains.size();k++)
		{
			Chain & c2= *chains.at(k);
			needle=0;
			offset=-1;
			int j=0;
			ChainNarratorNodeIterator n1(c1.m_chain.begin());
			bool last_1=false;
			while(true)
			{
				int u=min(offset+1,needle-radius);
				u=u>0?u:0;
				bool match=false;
				ChainNarratorNodeIterator  & n3=n1.getCorrespondingNarratorNode().getChainNodeItrInChain(k);
				if (!n3.isNull())
				{
					k++;
					n1=ChainNarratorNodeIterator(c1.m_chain.begin())+k;
					u=n3.getIndex()+1;
					needle=u;
					offset=u-1;
				}
				ChainNarratorNodeIterator n2=c2.m_chain.begin();
				n2=n2+u;
				bool last_2=false;
				while(true)
				{
					if (equal(n1.getNarrator(),n2.getNarrator())>=threshold)
					{
						mergeNodes(n1,n2);
						offset=u;
						needle=++u; //TODO: check if correct
						match=true;
						break;
					}
					++n2;
					u++;
					if (last_2)
						break;
					if (n2.isLast())
						last_2=true;
				}
				if (!match)
					needle++;
				j++;
				++n1;
				if (last_1)
					break;
				if (n1.isLast())
					last_1=true;
			}
		}
	}
#endif
}
Exemple #18
0
void VCProject::writeUserMacros(pugi::xml_node& node) const
{
  pugi::xml_node tempNode = node.parent().append_child("Temp");
  writePropertiesMap(m_userMacros, tempNode);
  mergeNodes(node, tempNode);
}
  virtual int packTextures(int &width,int &height,bool forcePowerOfTwo,bool onePixelBorder)  // pack the textures, the return code is the amount of wasted/unused area.
  {
    width = 0;
    height = 0;

    if ( onePixelBorder )
    {
      for (int i=0; i<mTextureCount; i++)
      {
        Texture &t = mTextures[i];
        t.mWidth+=2;
        t.mHeight+=2;
      }
      mLongestEdge+=2;
    }

    if ( forcePowerOfTwo )
    {
      mLongestEdge = nextPow2(mLongestEdge);
    }

    width  = mLongestEdge;              // The width is no more than the longest edge of any rectangle passed in
    int count = mTotalArea / (mLongestEdge*mLongestEdge);
    height = (count+2)*mLongestEdge;            // We guess that the height is no more than twice the longest edge.  On exit, this will get shrunk down to the actual tallest height.

    mDebugCount = 0;
    newFree(0,0,width,height);

    // We must place each texture
    for (int i=0; i<mTextureCount; i++)
    {

      int index = 0;
      int longestEdge = 0;
      int mostArea = 0;

      // We first search for the texture with the longest edge, placing it first.
      // And the most area...
      for (int j=0; j<mTextureCount; j++)
      {

        Texture &t = mTextures[j];

        if ( !t.isPlaced() ) // if this texture has not already been placed.
        {
          if ( t.mLongestEdge > longestEdge )
          {
            mostArea = t.mArea;
            longestEdge = t.mLongestEdge;
            index = j;
          }
          else if ( t.mLongestEdge == longestEdge ) // if the same length, keep the one with the most area.
          {
            if ( t.mArea > mostArea )
            {
              mostArea = t.mArea;
              index = j;
            }
          }
        }
      }

      // For the texture with the longest edge we place it according to this criteria.
      //   (1) If it is a perfect match, we always accept it as it causes the least amount of fragmentation.
      //   (2) A match of one edge with the minimum area left over after the split.
      //   (3) No edges match, so look for the node which leaves the least amount of area left over after the split.
      Texture &t = mTextures[index];

      int leastY = 0x7FFFFFFF;
      int leastX = 0x7FFFFFFF;

      Node *previousBestFit = 0;
      Node *bestFit = 0;
      Node *previous = 0;
      Node *search = mFreeList;
      int edgeCount = 0;

      // Walk the singly linked list of free nodes
      // see if it will fit into any currently free space
      while ( search )
      {
        int ec;
        if ( search->fits(t.mWidth,t.mHeight,ec) ) // see if the texture will fit into this slot, and if so how many edges does it share.
        {
          if ( ec == 2 )
          {
            previousBestFit = previous;     // record the pointer previous to this one (used to patch the linked list)
            bestFit = search; // record the best fit.
            edgeCount = ec;
            break;
          }
          if ( search->mY < leastY )
          {
            leastY = search->mY;
            leastX = search->mX;
            previousBestFit = previous;
            bestFit = search;
            edgeCount = ec;
          }
          else if ( search->mY == leastY && search->mX < leastX )
          {
            leastX = search->mX;
            previousBestFit = previous;
            bestFit = search;
            edgeCount = ec;
          }
        }
        previous = search;
        search = search->mNext;
      }

      assert( bestFit ); // we should always find a fit location!

      if ( bestFit )
      {
        validate();

        switch ( edgeCount )
        {
          case 0:
            if ( t.mLongestEdge <= bestFit->mWidth )
            {
              bool flipped = false;

              int wid = t.mWidth;
              int hit = t.mHeight;

              if ( hit > wid )
              {
                wid = t.mHeight;
                hit = t.mWidth;
                flipped = true;
              }

              t.place(bestFit->mX,bestFit->mY,flipped); // place it.

              newFree(bestFit->mX,bestFit->mY+hit,bestFit->mWidth,bestFit->mHeight-hit);

              bestFit->mX+=wid;
              bestFit->mWidth-=wid;
              bestFit->mHeight = hit;
              validate();
            }
            else
            {

              assert( t.mLongestEdge <= bestFit->mHeight );

              bool flipped = false;

              int wid = t.mWidth;
              int hit = t.mHeight;

              if ( hit < wid )
              {
                wid = t.mHeight;
                hit = t.mWidth;
                flipped = true;
              }

              t.place(bestFit->mX,bestFit->mY,flipped); // place it.

              newFree(bestFit->mX,bestFit->mY+hit,bestFit->mWidth,bestFit->mHeight-hit);

              bestFit->mX+=wid;
              bestFit->mWidth-=wid;
              bestFit->mHeight = hit;
              validate();
            }
            break;
          case 1:
            {
              if ( t.mWidth == bestFit->mWidth )
              {
                t.place(bestFit->mX,bestFit->mY,false);
                bestFit->mY+=t.mHeight;
                bestFit->mHeight-=t.mHeight;
                validate();
              }
              else if ( t.mHeight == bestFit->mHeight )
              {
                t.place(bestFit->mX,bestFit->mY,false);
                bestFit->mX+=t.mWidth;
                bestFit->mWidth-=t.mWidth;
                validate();
              }
              else if ( t.mWidth == bestFit->mHeight )
              {
                t.place(bestFit->mX,bestFit->mY,true);
                bestFit->mX+=t.mHeight;
                bestFit->mWidth-=t.mHeight;
                validate();
              }
              else if ( t.mHeight == bestFit->mWidth )
              {
                t.place(bestFit->mX,bestFit->mY,true);
                bestFit->mY+=t.mWidth;
                bestFit->mHeight-=t.mWidth;
                validate();
              }
            }
            break;
          case 2:
            {
              bool flipped = t.mWidth != bestFit->mWidth || t.mHeight != bestFit->mHeight;
              t.place(bestFit->mX,bestFit->mY,flipped);
              if ( previousBestFit )
              {
                previousBestFit->mNext = bestFit->mNext;
              }
              else
              {
                mFreeList = bestFit->mNext;
              }
              delete bestFit;
              validate();
            }
            break;
        }
        while ( mergeNodes() ); // keep merging nodes as much as we can...
      }
    }

    height = 0;
    for (int i=0; i<mTextureCount; i++)
    {
      Texture &t = mTextures[i];
      if ( onePixelBorder )
      {
        t.mWidth-=2;
        t.mHeight-=2;
        t.mX++;
        t.mY++;
      }

      int y;
      if (t.mFlipped)
      {
        y = t.mY + t.mWidth;
      }
      else
      {
        y = t.mY + t.mHeight;
      }

      if ( y > height )
        height = y;
    }

    if ( forcePowerOfTwo )
    {
      height = nextPow2(height);
    }

    return (width*height)-mTotalArea;
  }
Exemple #20
0
void radix_insert(char *key, struct node *p)
{
    int numberOfMatchingCharacters = getNumberOfMatchingCharacters(key, p);
    if (p->is_root || numberOfMatchingCharacters == 0 || (numberOfMatchingCharacters < strlen(key) && numberOfMatchingCharacters >= strlen(p->key)))
    {
        int flag = 0;
        char *newText = (char*)malloc(sizeof(char)*(strlen(key) - numberOfMatchingCharacters + 1));
        strcpy(newText, key + numberOfMatchingCharacters);
        int i;
        for (i = 0; i < p->child_num; i++)
        {
            if (p->child[i] == NULL && p->is_root)
            {
                struct node *tmp = (struct node*)malloc(sizeof(struct node));
                strcpy(tmp->key, newText);
                tmp->child_num = 0;
                tmp->is_real = 1;
                tmp->parent = p;
                tmp->child = (struct node**)malloc(sizeof(struct node));

                p->child_num++;
                p->child = realloc(p->child, sizeof(struct node));
                p->child[p->child_num - 1] = tmp;

            }
            if (p->child[i]->key[0] == newText[0])
            {
                flag = 1;
                radix_insert(newText, p->child[i]);
            }
        }

        if (0 == flag)
        {
            struct node *rn = (struct node*)malloc(sizeof(struct node));

            strcpy(rn->key, newText);
            rn->child_num = 0;
            rn->parent = p;
            rn->is_real = 1;
            rn->child = (struct node**)malloc(sizeof(struct node));

            p->child_num++;
            p->child = realloc(p->child, sizeof(struct node));

            p->child[p->child_num - 1] = rn;
        }
        FREE(newText);
        newText = NULL;
    }

    else if (numberOfMatchingCharacters == strlen(key) && numberOfMatchingCharacters == strlen(p->key))
    {
        if (1 == p->is_real)
            fprintf(stdout,"Duplicate key!\n");
        p->is_real = 1;
    }
    else if (numberOfMatchingCharacters > 0 && numberOfMatchingCharacters < strlen(p->key))
    {

        struct node *n1 = (struct node*)malloc(sizeof(struct node));
        char *newKey1 = (char*)malloc(sizeof(char)*(strlen(p->key) - numberOfMatchingCharacters + 1));
        strcpy(newKey1, p->key + numberOfMatchingCharacters);
        strcpy(n1->key, newKey1);
        FREE(newKey1);
        newKey1 = NULL;

        n1->value_head = p->value_head;
        n1->value_num = p->value_num;
        p->value_num = 0;
        p->value_head = NULL;

        n1->is_real = p->is_real;
        n1->child_num = p->child_num;
        int i;

        n1->child = (struct node**)malloc(sizeof(struct node) * n1->child_num);

        for (i = 0; i < n1->child_num; i++)
        {
            n1->child[i] = p->child[i];
            p->child[i]->parent = n1;
        }
        n1->parent = p;
        if (1 == n1->child_num && 0 == n1->is_real)
            mergeNodes(n1, n1->child[0]);
        char *newKey2 = (char*)malloc(sizeof(char)* (numberOfMatchingCharacters + 1));
        strncpy(newKey2, key, numberOfMatchingCharacters);
        newKey2[numberOfMatchingCharacters] = '\0';

        strcpy(p->key, newKey2);
        FREE(newKey2);
        newKey2 = NULL;
        p->is_real = 0;
        p->child[p->child_num] = (struct node*)malloc(sizeof(struct node));
        p->child[0] = n1;
        p->child_num = 1;

        if(numberOfMatchingCharacters < strlen(key))
        {
            struct node *n2 = (struct node*)malloc(sizeof(struct node));
            char *newKey3 = (char*)malloc(sizeof(char)*(strlen(key) - numberOfMatchingCharacters + 1));
            strcpy(newKey3, key + numberOfMatchingCharacters);

            strcpy(n2->key,newKey3);
            n2->is_real = 1;
            n2->parent = p;
            n2->child_num = 0;
            n2->child = (struct node**)malloc(sizeof(struct node));
            p->child_num++;
            p->child = realloc(p->child, sizeof(struct node));
            p->child[1] = n2;

        }
        else
        {
            p->is_real = 1;
        }

    }
    else
    {
        struct node *n = (struct node*)malloc(sizeof(struct node));

        char *newKey4 = (char*)malloc(sizeof(char)*(strlen(p->key) - numberOfMatchingCharacters + 1));
        strcpy(newKey4, p->key + numberOfMatchingCharacters);

        strcpy(n->key, newKey4);

        n->value_head = p->value_head;
        n->value_num = p->value_num;
        p->value_num = 0;
        p->value_head = NULL;

        FREE(newKey4);
        newKey4 = NULL;
        n->parent = p;
        n->child_num = p->child_num;
        int i;
        for (i = 0; i < p->child_num; i++)
        {
            if (!n->child[i])
                n->child[i] = (struct node*)malloc(sizeof(struct node));
            n->child[i] = p->child[i];
        }
        n->is_real = p->is_real;

        strcpy(p->key, key);
        p->is_real = 1;
        p->child_num++;
        p->child = realloc(p->child, sizeof(struct node));

        p->child[p->child_num] = n;
    }
}