Exemple #1
0
void Slider::_notification(int p_what) {


	switch(p_what) {

		case NOTIFICATION_MOUSE_ENTER: {

			mouse_inside=true;
			update();
		} break;
		case NOTIFICATION_MOUSE_EXIT: {

			mouse_inside=false;
			update();
		} break;
		case NOTIFICATION_DRAW: {
			RID ci = get_canvas_item();
			Size2i size = get_size();
			Ref<StyleBox> style = get_stylebox("slider");
			Ref<StyleBox> focus = get_stylebox("focus");
			Ref<Texture> grabber = get_icon(mouse_inside||has_focus()?"grabber_hilite":"grabber");
			Ref<Texture> tick = get_icon("tick");

			if (orientation==VERTICAL) {

				style->draw(ci,Rect2i(Point2i(),Size2i(style->get_minimum_size().width+style->get_center_size().width,size.height)));
				//if (mouse_inside||has_focus())
				//	focus->draw(ci,Rect2i(Point2i(),Size2i(style->get_minimum_size().width+style->get_center_size().width,size.height)));
				float areasize = size.height - grabber->get_size().height;
				if (ticks>1) {
					int tickarea = size.height - tick->get_height();
					for(int i=0;i<ticks;i++) {
					        if( ! ticks_on_borders && (i == 0 || i + 1 == ticks) ) continue;
						int ofs = i*tickarea/(ticks-1);
						tick->draw(ci,Point2(0,ofs));
					}

				}
				grabber->draw(ci,Point2i(size.width/2-grabber->get_size().width/2,size.height - get_unit_value()*areasize - grabber->get_size().height));
			} else {
				style->draw(ci,Rect2i(Point2i(),Size2i(size.width,style->get_minimum_size().height+style->get_center_size().height)));
				//if (mouse_inside||has_focus())
				//	focus->draw(ci,Rect2i(Point2i(),Size2i(size.width,style->get_minimum_size().height+style->get_center_size().height)));

				float areasize = size.width - grabber->get_size().width;
				if (ticks>1) {
					int tickarea = size.width - tick->get_width();
					for(int i=0;i<ticks;i++) {
					        if( (! ticks_on_borders) && ( (i == 0) || ((i + 1) == ticks)) ) continue;
						int ofs = i*tickarea/(ticks-1);
						tick->draw(ci,Point2(ofs,0));
					}

				}
				grabber->draw(ci,Point2i(get_unit_value()*areasize,size.height/2-grabber->get_size().height/2));
			}

		} break;
	}
}
void PngImageExt::FindNonOpaqueRect(Rect2i & rect)
{
	rect = Rect2i(0, 0, GetWidth(), GetHeight());
	for (uint32 y = 0; y < GetHeight(); ++y)
		if (IsHorzLineOpaque(y))
		{
			rect.y++;
			rect.dy--;
		}else break;
	
	for (uint32 x = 0; x < GetWidth(); ++x)
		if (IsVertLineOpaque(x))
		{
			rect.x++;
			rect.dx--;
		}else break;
		
	if ((rect.dx == 0) && (rect.dy == 0))
	{
		rect.x = rect.y = 0; 
		rect.dx = rect.dy = 1;
		return;
	}
	
	for (int32 y = GetHeight() - 1; y >= 0; --y)
		if (IsHorzLineOpaque(y))rect.dy--;
		else break;
	
	for (int32 x = GetWidth() - 1; x >= 0; --x)
		if (IsVertLineOpaque(x))rect.dx--;
		else break;
}
Exemple #3
0
Vector<Vector<Vector2> > BitMap::clip_opaque_to_polygons(const Rect2 &p_rect, float p_epsilon) const {

	Rect2i r = Rect2i(0, 0, width, height).clip(p_rect);
	print_verbose("BitMap: Rect: " + r);

	Point2i from;
	Ref<BitMap> fill;
	fill.instance();
	fill->create(get_size());

	Vector<Vector<Vector2> > polygons;
	for (int i = r.position.y; i < r.position.y + r.size.height; i++) {
		for (int j = r.position.x; j < r.position.x + r.size.width; j++) {
			if (!fill->get_bit(Point2(j, i)) && get_bit(Point2(j, i))) {

				Vector<Vector2> polygon = _march_square(r, Point2i(j, i));
				print_verbose("BitMap: Pre reduce: " + itos(polygon.size()));
				polygon = reduce(polygon, r, p_epsilon);
				print_verbose("BitMap: Post reduce: " + itos(polygon.size()));
				polygons.push_back(polygon);
				fill_bits(this, fill, Point2i(j, i), r);
			}
		}
	}

	return polygons;
}
Exemple #4
0
void BitMap::set_bit_rect(const Rect2& p_rect,bool p_value) {

	Rect2i current = Rect2i(0,0,width,height).clip(p_rect);
	uint8_t *data = bitmask.ptr();

	for(int i=current.pos.x;i<current.pos.x+current.size.x;i++) {

		for(int j=current.pos.y;j<current.pos.y+current.size.y;j++) {


			int ofs = width * j + i;
			int bbyte = ofs/8;
			int bbit = ofs % 8;

			uint8_t b = data[bbyte];

			if (p_value)
				b|=(1<<bbit);
			else
				b&=!(1<<bbit);

			data[bbyte]=b;

		}
	}

}
void PngImageExt::FindNonOpaqueRect(Rect2i & rect)
{
	rect = Rect2i(0, 0, width, height);
	for (int y = 0; y < height; ++y)
		if (IsHorzLineOpaque(y))
		{
			rect.y++;
			rect.dy--;
		}else break;
	
	for (int x = 0; x < width; ++x)
		if (IsVertLineOpaque(x))
		{
			rect.x++;
			rect.dx--;
		}else break;
		
	if ((rect.dx == 0) && (rect.dy == 0))
	{
		rect.x = rect.y = 0; 
		rect.dx = rect.dy = 1;
		return;
	}
	
	for (int y = height - 1; y >= 0; --y)
		if (IsHorzLineOpaque(y))rect.dy--;
		else break;
	
	for (int x = width - 1; x >= 0; --x)
		if (IsVertLineOpaque(x))rect.dx--;
		else break;
}
Exemple #6
0
Rect2i Layout::getImageRect(std::size_t index) const
{
	const std::pair<std::size_t, LineInfo> line = findLine(index);
	const int x = (index - line.first) % columns_ * cellStepX_;
	const int y = (index - line.first) / columns_ * cellStepY_ + line.second.cellTop;

	return Rect2i(x, y, x + imageWidth_, y + line.second.imageHeight);
}
RectPacker::PackNode * RectPacker::PackNode::Insert(const Size2i & imageSize)
{
	if (!isLeaf)
	{
		RectPacker::PackNode *newNode = child[0]->Insert(imageSize);
		if (newNode)return newNode;

		return child[1]->Insert(imageSize);
	}
	else
	{
		if (isImageSet)return 0;


		if ((imageSize.dx > rect.dx) || (imageSize.dy > rect.dy))
		{
			return 0;
		}
		if ((imageSize.dx == rect.dx) && (imageSize.dy == rect.dy))
		{
			isImageSet = true;
			return this;
		}

		isLeaf = false;

		child[0] = new RectPacker::PackNode;
		child[1] = new RectPacker::PackNode;

		int32 dw = rect.dx - imageSize.dx;
		int32 dh = rect.dy - imageSize.dy;

		if (dw > dh)
		{
			child[0]->rect = Rect2i(	rect.x, rect.y, imageSize.dx, rect.dy);
			child[1]->rect = Rect2i(	rect.x + imageSize.dx, rect.y, rect.dx - imageSize.dx, rect.dy);
		}
		else
		{
			child[0]->rect = Rect2i(	rect.x, rect.y, rect.dx, imageSize.dy);
			child[1]->rect = Rect2i(	rect.x, rect.y + imageSize.dy, rect.dx, rect.dy - imageSize.dy);
		}
		return child[0]->Insert(imageSize);
	}
}
Exemple #8
0
void ItemList::add_item(const String& p_item,const Ref<Texture>& p_texture,bool p_selectable) {

	Item item;
	item.icon=p_texture;
	item.icon_region=Rect2i();
	item.text=p_item;
	item.selectable=p_selectable;
	item.selected=false;
	item.disabled=false;
	item.custom_bg=Color(0,0,0,0);
	items.push_back(item);

	update();
	shape_changed=true;

}
Exemple #9
0
void BitMap::grow_mask(int p_pixels, const Rect2 &p_rect) {

	Rect2i r = Rect2i(0, 0, width, height).clip(p_rect);

	Ref<BitMap> copy;
	copy.instance();
	copy->create(get_size());
	copy->bitmask = bitmask;

	for (int i = r.position.y; i < r.position.y + r.size.height; i++) {
		for (int j = r.position.x; j < r.position.x + r.size.width; j++) {
			if (copy->get_bit(Point2(j, i)))
				continue;

			bool found = false;

			for (int y = i - p_pixels; y <= i + p_pixels; y++) {
				for (int x = j - p_pixels; x <= j + p_pixels; x++) {

					if (x < p_rect.position.x || x >= p_rect.position.x + p_rect.size.x)
						continue;
					if (y < p_rect.position.y || y >= p_rect.position.y + p_rect.size.y)
						continue;

					float d = Point2(j, i).distance_to(Point2(x, y)) - CMP_EPSILON;
					if (d > p_pixels)
						continue;

					if (copy->get_bit(Point2(x, y))) {
						found = true;
						break;
					}
				}
				if (found)
					break;
			}

			if (found) {
				set_bit(Point2(j, i), true);
			}
		}
	}
}
Exemple #10
0
void Slider::_notification(int p_what) {

	switch (p_what) {

		case NOTIFICATION_MOUSE_ENTER: {

			mouse_inside = true;
			update();
		} break;
		case NOTIFICATION_MOUSE_EXIT: {

			mouse_inside = false;
			update();
		} break;
		case NOTIFICATION_VISIBILITY_CHANGED: // fallthrough
		case NOTIFICATION_EXIT_TREE: {

			mouse_inside = false;
			grab.active = false;
		} break;
		case NOTIFICATION_DRAW: {
			RID ci = get_canvas_item();
			Size2i size = get_size();
			Ref<StyleBox> style = get_stylebox("slider");
			Ref<StyleBox> focus = get_stylebox("focus");
			Ref<StyleBox> grabber_area = get_stylebox("grabber_area");
			Ref<Texture> grabber = get_icon(editable ? ((mouse_inside || has_focus()) ? "grabber_highlight" : "grabber") : "grabber_disabled");
			Ref<Texture> tick = get_icon("tick");

			if (orientation == VERTICAL) {

				int widget_width = style->get_minimum_size().width + style->get_center_size().width;
				float areasize = size.height - grabber->get_size().height;
				style->draw(ci, Rect2i(Point2i(size.width / 2 - widget_width / 2, 0), Size2i(widget_width, size.height)));
				grabber_area->draw(ci, Rect2i(Point2i((size.width - widget_width) / 2, size.height - areasize * get_as_ratio() - grabber->get_size().height / 2), Size2i(widget_width, areasize * get_as_ratio() + grabber->get_size().width / 2)));
				/*
				if (mouse_inside||has_focus())
					focus->draw(ci,Rect2i(Point2i(),Size2i(style->get_minimum_size().width+style->get_center_size().width,size.height)));
				*/
				if (ticks > 1) {
					int tickarea = size.height - tick->get_height();
					for (int i = 0; i < ticks; i++) {
						if (!ticks_on_borders && (i == 0 || i + 1 == ticks)) continue;
						int ofs = i * tickarea / (ticks - 1);
						tick->draw(ci, Point2i((size.width - widget_width) / 2, ofs));
					}
				}
				grabber->draw(ci, Point2i(size.width / 2 - grabber->get_size().width / 2, size.height - get_as_ratio() * areasize - grabber->get_size().height));
			} else {

				int widget_height = style->get_minimum_size().height + style->get_center_size().height;
				float areasize = size.width - grabber->get_size().width;

				style->draw(ci, Rect2i(Point2i(0, (size.height - widget_height) / 2), Size2i(size.width, widget_height)));
				grabber_area->draw(ci, Rect2i(Point2i(0, (size.height - widget_height) / 2), Size2i(areasize * get_as_ratio() + grabber->get_size().width / 2, widget_height)));
				/*
				if (mouse_inside||has_focus())
					focus->draw(ci,Rect2i(Point2i(),Size2i(size.width,style->get_minimum_size().height+style->get_center_size().height)));
				*/

				if (ticks > 1) {
					int tickarea = size.width - tick->get_width();
					for (int i = 0; i < ticks; i++) {
						if ((!ticks_on_borders) && ((i == 0) || ((i + 1) == ticks))) continue;
						int ofs = i * tickarea / (ticks - 1);
						tick->draw(ci, Point2i(ofs, (size.height - widget_height) / 2));
					}
				}
				grabber->draw(ci, Point2i(get_as_ratio() * areasize, size.height / 2 - grabber->get_size().height / 2));
			}

		} break;
	}
}
Exemple #11
0
Vector<Vector2> BitMap::_march_square(const Rect2i &rect, const Point2i &start) const {

	int stepx = 0;
	int stepy = 0;
	int prevx = 0;
	int prevy = 0;
	int startx = start.x;
	int starty = start.y;
	int curx = startx;
	int cury = starty;
	unsigned int count = 0;
	Set<Point2i> case9s;
	Set<Point2i> case6s;
	Vector<Vector2> _points;
	do {
		int sv = 0;
		{ //square value

			/*
			checking the 2x2 pixel grid, assigning these values to each pixel, if not transparent
			+---+---+
			| 1 | 2 |
			+---+---+
			| 4 | 8 | <- current pixel (curx,cury)
			+---+---+
			*/
			//NOTE: due to the way we pick points from texture, rect needs to be smaller, otherwise it goes outside 1 pixel
			Rect2i fixed_rect = Rect2i(rect.position, rect.size - Size2i(2, 2));
			Point2i tl = Point2i(curx - 1, cury - 1);
			sv += (fixed_rect.has_point(tl) && get_bit(tl)) ? 1 : 0;
			Point2i tr = Point2i(curx, cury - 1);
			sv += (fixed_rect.has_point(tr) && get_bit(tr)) ? 2 : 0;
			Point2i bl = Point2i(curx - 1, cury);
			sv += (fixed_rect.has_point(bl) && get_bit(bl)) ? 4 : 0;
			Point2i br = Point2i(curx, cury);
			sv += (fixed_rect.has_point(br) && get_bit(br)) ? 8 : 0;
			ERR_FAIL_COND_V(sv == 0 || sv == 15, Vector<Vector2>());
		}

		switch (sv) {

			case 1:
			case 5:
			case 13:
				/* going UP with these cases:
				1          5           13
				+---+---+  +---+---+  +---+---+
				| 1 |   |  | 1 |   |  | 1 |   |
				+---+---+  +---+---+  +---+---+
				|   |   |  | 4 |   |  | 4 | 8 |
				+---+---+  +---+---+  +---+---+
				*/
				stepx = 0;
				stepy = -1;
				break;

			case 8:
			case 10:
			case 11:
				/* going DOWN with these cases:
				8          10         11
				+---+---+  +---+---+  +---+---+
				|   |   |  |   | 2 |  | 1 | 2 |
				+---+---+  +---+---+  +---+---+
				|   | 8 |  |   | 8 |  |   | 8 |
				+---+---+  +---+---+  +---+---+
				*/
				stepx = 0;
				stepy = 1;
				break;

			case 4:
			case 12:
			case 14:
				/* going LEFT with these cases:
				4          12         14
				+---+---+  +---+---+  +---+---+
				|   |   |  |   |   |  |   | 2 |
				+---+---+  +---+---+  +---+---+
				| 4 |   |  | 4 | 8 |  | 4 | 8 |
				+---+---+  +---+---+  +---+---+
				*/
				stepx = -1;
				stepy = 0;
				break;

			case 2:
			case 3:
			case 7:
				/* going RIGHT with these cases:
				2          3          7
				+---+---+  +---+---+  +---+---+
				|   | 2 |  | 1 | 2 |  | 1 | 2 |
				+---+---+  +---+---+  +---+---+
				|   |   |  |   |   |  | 4 |   |
				+---+---+  +---+---+  +---+---+
				*/
				stepx = 1;
				stepy = 0;
				break;
			case 9:
				/*
				+---+---+
				| 1 |   |
				+---+---+
				|   | 8 |
				+---+---+
				this should normally go UP, but if we already been here, we go down
				*/
				if (case9s.has(Point2i(curx, cury))) {
					//found, so we go down, and delete from case9s;
					stepx = 0;
					stepy = 1;
					case9s.erase(Point2i(curx, cury));
				} else {
					//not found, we go up, and add to case9s;
					stepx = 0;
					stepy = -1;
					case9s.insert(Point2i(curx, cury));
				}
				break;
			case 6:
				/*
				6
				+---+---+
				|   | 2 |
				+---+---+
				| 4 |   |
				+---+---+
				this normally go RIGHT, but if its coming from UP, it should go LEFT
				*/
				if (case6s.has(Point2i(curx, cury))) {
					//found, so we go down, and delete from case6s;
					stepx = -1;
					stepy = 0;
					case6s.erase(Point2i(curx, cury));
				} else {
					//not found, we go up, and add to case6s;
					stepx = 1;
					stepy = 0;
					case6s.insert(Point2i(curx, cury));
				}
				break;
			default:
				ERR_PRINT("this shouldn't happen.");
		}
		//little optimization
		// if previous direction is same as current direction,
		// then we should modify the last vec to current
		curx += stepx;
		cury += stepy;
		if (stepx == prevx && stepy == prevy) {
			_points.write[_points.size() - 1].x = (float)(curx - rect.position.x);
			_points.write[_points.size() - 1].y = (float)(cury + rect.position.y);
		} else {
			_points.push_back(Vector2((float)(curx - rect.position.x), (float)(cury + rect.position.y)));
		}

		count++;
		prevx = stepx;
		prevy = stepy;

		ERR_FAIL_COND_V(count > width * height, _points);
	} while (curx != startx || cury != starty);
	return _points;
}
Exemple #12
0
void TexturePacker::PackToMultipleTextures(const char * excludeFolder, const char* outputPath, std::list<DefinitionFile*> & defList)
{
    if (defList.size() != 1)
        if (CommandLineParser::Instance()->GetVerbose())printf("* ERROR: failed to pack to multiple textures\n");

    for (int i = 0; i < (int)sortVector.size(); ++i)
    {
        DefinitionFile * defFile = sortVector[i].defFile;
        int frame = sortVector[i].frameIndex;
        if (CommandLineParser::Instance()->GetVerbose())printf("[MultiPack] prepack: %s frame: %d w:%d h:%d\n", defFile->filename.c_str(), frame, defFile->frameRects[frame].dx, defFile->frameRects[frame].dy);
    }

    std::vector<ImagePacker*> & packers = usedPackers;

    /*
    // OLD PACKING ALGORITHM
    ImagePacker * currentPacker = new ImagePacker(Rect2i::Make(0, 0, 1024, 1024));
    packers.push_back(currentPacker);

    // Packing of sorted by size images
    for (int i = 0; i < sortVector.size(); ++i)
    {
    	DefinitionFile * defFile = sortVector[i].defFile;
    	int frame = sortVector[i].frameIndex;
    	printf("[MultiPack] pack: %s frame: %d w:%d h:%d\n", defFile->filename.c_str(), frame, defFile->frameRects[frame].dx, defFile->frameRects[frame].dy);

    	bool packed = false;
    	for (int packerIndex = 0; packerIndex < packers.size(); ++packerIndex)
    	{
    		if (packers[packerIndex]->AddImage(Size2i::Make(defFile->frameRects[frame].dx, defFile->frameRects[frame].dy), &defFile->frameRects[frame]))
    		{
    			packed = true;
    			printf("[MultiPack] added to packer: %d\n", packerIndex);
    			break;
    		}
    	}

    	if (!packed)
    	{
    		currentPacker = new ImagePacker(Rect2i::Make(0, 0, 1024, 1024));
    		packers.push_back(currentPacker);

    		if (!currentPacker->AddImage(Size2i::Make(defFile->frameRects[frame].dx, defFile->frameRects[frame].dy), &defFile->frameRects[frame]))
    		{
    			printf("*** FATAL ERROR: image is too big: imageSize: %d, %d\n", defFile->frameRects[frame].dx, defFile->frameRects[frame].dy);
    			return;
    		}else
    		{
    			printf("[MultiPack] added to packer: %d\n", packers.size() - 1);
    		}
    	}

    } */


    /* // ALGO #2
    std::vector<SizeSortItem> sortVectorWork = sortVector;

    while(sortVectorWork.size() > 0)
    {
    	// try to pack for each resolution
    	int maxPackedObjects = 0;
    	//int bestResolution = 1025 * 1025;

    	printf("* Packing tries started: ");

    	ImagePacker * bestPackerForThisStep = 0;
    	std::vector<SizeSortItem> newWorkVector;

    	for (int yResolution = 8; yResolution <= 1024; yResolution *= 2)
    		for (int xResolution = 8; xResolution <= 1024; xResolution *= 2)
    		{
    			Rect2i textureRect = Rect2i::Make(0, 0, xResolution, yResolution);
    			ImagePacker * packer = new ImagePacker(textureRect);

    			std::vector<SizeSortItem> tempSortVector = sortVectorWork;
    			int n = TryToPackFromSortVector(packer, tempSortVector);

    			if (n > maxPackedObjects)
    			{
    				maxPackedObjects = n;
    				SafeDelete(bestPackerForThisStep);
    				bestPackerForThisStep = packer;
    				newWorkVector = tempSortVector;
    			}
    		}

    	sortVectorWork = newWorkVector;
    	packers.push_back(bestPackerForThisStep);
    } */

    std::vector<SizeSortItem> sortVectorWork = sortVector;

    while(sortVectorWork.size() > 0)
    {
        // try to pack for each resolution
        float maxValue = 0.0f;
        //int bestResolution = 1025 * 1025;

        if (CommandLineParser::Instance()->GetVerbose())printf("* Packing tries started: ");

        ImagePacker * bestPackerForThisStep = 0;
        std::vector<SizeSortItem> newWorkVector;

        for (int yResolution = 8; yResolution <= maxTextureSize; yResolution *= 2)
            for (int xResolution = 8; xResolution <= maxTextureSize; xResolution *= 2)
            {
                if (CommandLineParser::Instance()->IsFlagSet("--pvr") && (xResolution != yResolution))continue;

                if ((onlySquareTextures) && (xResolution != yResolution))continue;

                Rect2i textureRect = Rect2i(0, 0, xResolution, yResolution);
                ImagePacker * packer = new ImagePacker(textureRect);

                std::vector<SizeSortItem> tempSortVector = sortVectorWork;
                float n = TryToPackFromSortVectorWeight(packer, tempSortVector);

                if (n > maxValue)
                {
                    maxValue = n;
                    SafeDelete(bestPackerForThisStep);
                    bestPackerForThisStep = packer;
                    newWorkVector = tempSortVector;
                }
            }

        sortVectorWork = newWorkVector;
        packers.push_back(bestPackerForThisStep);
    }

    if (CommandLineParser::Instance()->GetVerbose())printf("* Writing %d final textures \n", (int)packers.size());

    std::vector<PngImageExt*> finalImages;

    for (int imageIndex = 0; imageIndex < (int)packers.size(); ++imageIndex)
    {
        PngImageExt * image = new PngImageExt();
        ImagePacker * packer = packers[imageIndex];
        image->Create(packer->GetRect().dx, packer->GetRect().dy);
        finalImages.push_back(image);
    }

    for (std::list<DefinitionFile*>::iterator defi = defList.begin(); defi != defList.end(); ++defi)
    {
        DefinitionFile * defFile = *defi;

        for (int frame = 0; frame < defFile->frameCount; ++frame)
        {
            Rect2i * destRect;
            ImagePacker * foundPacker = 0;
            int packerIndex = 0;
            char name[256];

            for (packerIndex = 0; packerIndex < (int)packers.size(); ++packerIndex)
            {
                destRect = packers[packerIndex]->SearchRectForPtr(&defFile->frameRects[frame]);

                if (destRect)
                {
                    foundPacker = packers[packerIndex];
                    std::string withoutExt = defFile->filename.substr(0, defFile->filename.length() - 4);
                    snprintf(name, 256, "%s%d.png", withoutExt.c_str(), frame);
                    break;
                }
            }

            if (foundPacker)
            {
                if (CommandLineParser::Instance()->GetVerbose())printf("[MultiPack] pack to texture: %d\n", packerIndex);
                PngImageExt image;
                image.Read(name);
                finalImages[packerIndex]->DrawImage(destRect->x, destRect->y, &image);
                if (CommandLineParser::Instance()->IsFlagSet("--debug"))
                {
                    finalImages[packerIndex]->DrawRect(*destRect, 0xFF0000FF);
                }
            }
        }
    }

    for (int image = 0; image < (int)packers.size(); ++image)
    {
        char temp[256];
        sprintf(temp, "texture%d.png", image);
        std::string textureName = std::string(outputPath) + std::string(temp);
        finalImages[image]->Write(textureName.c_str());
    }

    for (std::list<DefinitionFile*>::iterator defi = defList.begin(); defi != defList.end(); ++defi)
    {
        DefinitionFile * defFile = *defi;

        std::string textureName = std::string(outputPath) + std::string("texture");
        if (!WriteMultipleDefinition(excludeFolder, outputPath, "texture", defFile))
        {
            printf("* ERROR: failed to write definition\n");
        }
    }
}
Exemple #13
0
void TexturePacker::PackToTextures(const char * excludeFolder, const char* outputPath, std::list<DefinitionFile*> & defsList)
{
    lastPackedPacker = 0;
    for (std::list<DefinitionFile*>::iterator dfi = defsList.begin(); dfi != defsList.end(); ++dfi)
    {
        DefinitionFile * defFile = *dfi;
        for (int frame = 0; frame < defFile->frameCount; ++frame)
        {
            SizeSortItem sortItem;
            sortItem.imageSize = defFile->frameRects[frame].dx * defFile->frameRects[frame].dy;
            sortItem.defFile = defFile;
            sortItem.frameIndex = frame;
            sortVector.push_back(sortItem);
        }
    }

//	for (int i = 0; i < sortVector.size(); ++i)
//	{
//		DefinitionFile * defFile = sortVector[i].defFile;
//		int frame = sortVector[i].frameIndex;
//		printf("[SinglePack] before sort: %s frame: %d w:%d h:%d\n", defFile->filename.c_str(), frame, defFile->frameRects[frame].dx, defFile->frameRects[frame].dy);
//	}

    std::sort(sortVector.begin(), sortVector.end(), sortFn);

//	for (int i = 0; i < sortVector.size(); ++i)
//	{
//		DefinitionFile * defFile = sortVector[i].defFile;
//		int frame = sortVector[i].frameIndex;
//		printf("[SinglePack] after sort: %s frame: %d w:%d h:%d\n", defFile->filename.c_str(), frame, defFile->frameRects[frame].dx, defFile->frameRects[frame].dy);
//	}

    // try to pack for each resolution
    int bestResolution = (maxTextureSize + 1) * (maxTextureSize + 1);
    int bestXResolution, bestYResolution;

    if (CommandLineParser::Instance()->GetVerbose())
        printf("* Packing tries started: ");

    bool isPvr = false;
    if (CommandLineParser::Instance()->IsFlagSet("--pvr"))
        isPvr = true;

    for (int yResolution = 8; yResolution <= maxTextureSize; yResolution *= 2)
        for (int xResolution = 8; xResolution <= maxTextureSize; xResolution *= 2)
        {
            if ((isPvr) && (xResolution != yResolution))continue;

            if ((onlySquareTextures) && (xResolution != yResolution))continue;

            Rect2i textureRect = Rect2i(0, 0, xResolution, yResolution);

            if (xResolution * yResolution < bestResolution)
                if (TryToPack(textureRect, defsList))
                {
                    bestResolution = xResolution * yResolution;
                    bestXResolution = xResolution;
                    bestYResolution = yResolution;
                }
        }
    if (CommandLineParser::Instance()->GetVerbose())
        printf("\n");
    if (bestResolution != (maxTextureSize + 1) * (maxTextureSize + 1))
    {
        std::string textureName = std::string(outputPath) + std::string("texture");
        if (CommandLineParser::Instance()->GetVerbose())
            printf("* Writing final texture (%d x %d): %s\n", bestXResolution, bestYResolution , textureName.c_str());

        PngImageExt finalImage;
        finalImage.Create(bestXResolution, bestYResolution);

        // Writing
        for (std::list<DefinitionFile*>::iterator dfi = defsList.begin(); dfi != defsList.end(); ++dfi)
        {
            DefinitionFile * defFile = *dfi;
            for (int frame = 0; frame < defFile->frameCount; ++frame)
            {
                Rect2i *destRect = lastPackedPacker->SearchRectForPtr(&defFile->frameRects[frame]);
                if (!destRect)printf("*** ERROR Can't find rect for frame\n");

                char name[256];
                std::string withoutExt = defFile->filename.substr(0, defFile->filename.length() - 4);
                snprintf(name, 256, "%s%d.png", withoutExt.c_str(), frame);

                PngImageExt image;
                image.Read(name);
                finalImage.DrawImage(destRect->x, destRect->y, &image);

                if (CommandLineParser::Instance()->IsFlagSet("--debug"))
                {
                    finalImage.DrawRect(*destRect, 0xFF0000FF);
                }
            }

            if (!WriteDefinition(excludeFolder, outputPath, "texture", defFile))
            {
                printf("* ERROR: failed to write definition\n");
            }
        }
        char textureExtension[5] = "png";
        if (CommandLineParser::Instance()->IsFlagSet("--pvr"))strcpy(textureExtension, "pvr");

        textureName += std::string(".") + textureExtension;
        finalImage.Write(textureName.c_str());
    } else
    {
        //
        PackToMultipleTextures(excludeFolder, outputPath, defsList);
    }
}
Exemple #14
0
void TexturePacker::PackToTexturesSeparate(const char * excludeFolder, const char* outputPath, std::list<DefinitionFile*> & defsList)
{
    lastPackedPacker = 0;
    int textureIndex = 0;
    for (std::list<DefinitionFile*>::iterator dfi = defsList.begin(); dfi != defsList.end(); ++dfi)
    {
        sortVector.clear();

        DefinitionFile * defFile = *dfi;
        for (int frame = 0; frame < defFile->frameCount; ++frame)
        {
            SizeSortItem sortItem;
            sortItem.imageSize = defFile->frameRects[frame].dx * defFile->frameRects[frame].dy;
            sortItem.defFile = defFile;
            sortItem.frameIndex = frame;
            sortVector.push_back(sortItem);
        }
        std::sort(sortVector.begin(), sortVector.end(), sortFn);


        // try to pack for each resolution
        int bestResolution = (maxTextureSize + 1) * (maxTextureSize + 1);
        int bestXResolution, bestYResolution;

        if (CommandLineParser::Instance()->GetVerbose())
            printf("* Packing tries started: ");

        for (int yResolution = 8; yResolution <= maxTextureSize; yResolution *= 2)
            for (int xResolution = 8; xResolution <= maxTextureSize; xResolution *= 2)
            {
                Rect2i textureRect = Rect2i(0, 0, xResolution, yResolution);

                if (xResolution * yResolution < bestResolution)
                    if (TryToPack(textureRect, defsList))
                    {
                        bestResolution = xResolution * yResolution;
                        bestXResolution = xResolution;
                        bestYResolution = yResolution;
                    }
            }
        if (CommandLineParser::Instance()->GetVerbose())
            printf("\n");
        if (bestResolution != (maxTextureSize + 1) * (maxTextureSize + 1))
        {
            char textureNameWithIndex[50];
            sprintf(textureNameWithIndex, "texture%d", textureIndex++);
            std::string textureName = std::string(outputPath) + std::string(textureNameWithIndex);
            if (CommandLineParser::Instance()->GetVerbose())
                printf("* Writing final texture (%d x %d): %s\n", bestXResolution, bestYResolution , textureName.c_str());

            PngImageExt finalImage;
            finalImage.Create(bestXResolution, bestYResolution);

            // Writing
            for (int frame = 0; frame < defFile->frameCount; ++frame)
            {
                Rect2i *destRect = lastPackedPacker->SearchRectForPtr(&defFile->frameRects[frame]);
                if (!destRect)printf("*** ERROR Can't find rect for frame\n");

                char name[256];
                std::string withoutExt = defFile->filename.substr(0, defFile->filename.length() - 4);
                snprintf(name, 256, "%s%d.png", withoutExt.c_str(), frame);

                PngImageExt image;
                image.Read(name);
                finalImage.DrawImage(destRect->x, destRect->y, &image);
            }

            if (!WriteDefinition(excludeFolder, outputPath, textureNameWithIndex, defFile))
            {
                printf("* ERROR: failed to write definition\n");
            }
            char textureExtension[5] = "png";
            if (CommandLineParser::Instance()->IsFlagSet("--pvr"))strcpy(textureExtension, "pvr");
            textureName += std::string(".") + textureExtension;

            finalImage.Write(textureName.c_str());
        }
    }
}
DefinitionFile * ResourcePackerScreen::ProcessPSD(const String & processDirectoryPath, const String & psdPathname, const String & psdName)
{
	int32 maxTextureSize = 1024;
	if (CommandLineParser::Instance()->IsFlagSet("--tsize2048"))
	{
		maxTextureSize = 2048;
	}
	
	// TODO: Check CRC32
	std::vector<Magick::Image> layers;
	
	String psdNameWithoutExtension = FileSystem::ReplaceExtension(psdName, "");
	
	try 
	{
		Magick::readImages(&layers, psdPathname);
		
		if (layers.size() == 0)
		{
			Logger::Error("Number of layers is too low: %s", psdPathname.c_str());
			return 0;
		}
		
		if (layers.size() == 1)
		{
			layers.push_back(layers[0]);
		}
		
		//Logger::Debug("psd file: %s wext: %s", psdPathname.c_str(), psdNameWithoutExtension.c_str());
		
		int width = (int)layers[0].columns();
		int height = (int)layers[0].rows();
		
		for(int k = 1; k < (int)layers.size(); ++k)
		{
			Magick::Image & currentLayer = layers[k];
			
			
			/* 
			MagickCore::ResetImagePropertyIterator(currentLayer.image());
			const char * property = MagickCore::GetNextImageProperty(currentLayer.image());
			if (property != (const char *) NULL)
			{
				printf("  Properties:\n");
				while (property != (const char *) NULL)
				{
					printf("    %c",*property);
					if (strlen(property) > 1)
						printf("%s: ",property+1);
					if (strlen(property) > 80)
						printf("\n");

					const char * value = MagickCore::GetImageProperty(currentLayer.image(), property);
					if (value != (const char *) NULL)
						printf("%s\n",value);
					property = MagickCore::GetNextImageProperty(currentLayer.image());
				}
			} */
			
			
			
			currentLayer.crop(Magick::Geometry(width,height, 0, 0));
			currentLayer.magick("PNG");
			String outputFile = processDirectoryPath + String("/") + psdNameWithoutExtension;
			outputFile += String(Format("%d.png", k - 1));
			currentLayer.write(outputFile);
		}
		
		
		DefinitionFile * defFile = new DefinitionFile;
		defFile->filename = processDirectoryPath + String("/") + psdNameWithoutExtension + String(".txt");
		// Logger::Debug("filename: %s", defFile->filename.c_str());
		defFile->spriteWidth = width;
		defFile->spriteHeight = height;
		defFile->frameCount = (int)layers.size() -1;
		defFile->frameRects = new Rect2i[defFile->frameCount];
		
		for(int k = 1; k < (int)layers.size(); ++k)
		{
			Magick::Image & currentLayer = layers[k];
			Magick::Geometry bbox = currentLayer.page();
			int xOff = (int)bbox.xOff();
			if (bbox.xNegative())
				xOff = -xOff;
			int yOff = (int)bbox.yOff();
			if (bbox.yNegative())
				yOff = -yOff;
			
			defFile->frameRects[k - 1] = Rect2i(xOff, yOff, (int32)bbox.width(), (int32)bbox.height());
			
			//printf("Percent: %d Aspect: %d Greater: %d Less: %d\n", (int)bbox.percent(), (int)bbox.aspect(), (int)bbox.greater(), (int)bbox.less());
			
			if ((defFile->frameRects[k - 1].dx >= maxTextureSize) || (defFile->frameRects[k - 1].dy >= maxTextureSize))
			{
				
				printf("* WARNING * - frame of %s layer %d is bigger than maxTextureSize(%d) layer exportSize (%d x %d) FORCE REDUCE TO (%d x %d). Bewarned!!! Results not guaranteed!!!\n", psdName.c_str(), k - 1, maxTextureSize
					   , defFile->frameRects[k - 1].dx, defFile->frameRects[k - 1].dy, width, height);
				defFile->frameRects[k - 1].dx = width;
				defFile->frameRects[k - 1].dy = height;
			}
				
			
			
			if (CommandLineParser::Instance()->IsFlagSet("--add0pixel"))
			{
				
			}else if (CommandLineParser::Instance()->IsFlagSet("--add1pixel"))
			{
				defFile->frameRects[k - 1].dx++;
				defFile->frameRects[k - 1].dy++;
			}
			else if (CommandLineParser::Instance()->IsFlagSet("--add2pixel"))
			{
				defFile->frameRects[k - 1].dx+=2;
				defFile->frameRects[k - 1].dy+=2;
			}
			else if (CommandLineParser::Instance()->IsFlagSet("--add4pixel"))
			{
				defFile->frameRects[k - 1].dx+=4;
				defFile->frameRects[k - 1].dy+=4;
			}
			else if(CommandLineParser::Instance()->IsFlagSet("--add2sidepixel"))
			{
				defFile->frameRects[k - 1].dx+=2;
				defFile->frameRects[k - 1].dy+=2;
			}
			else
			{
				defFile->frameRects[k - 1].dx++;
				defFile->frameRects[k - 1].dy++;	
			}
		}
		
		return defFile;
	}
	catch( Magick::Exception &error_ )
    {
		std::cout << "Caught exception: " << error_.what() << " file: "<< psdPathname << std::endl;
		return 0;
    }
	return 0;
}
bool DefinitionFile::LoadPNGDef(const std::string & _filename, const std::string & pathToProcess)
{
	if (CommandLineParser::Instance()->GetVerbose())printf("* Load PNG Definition: %s\n", _filename.c_str()); 
	
	FILE * fp = fopen(_filename.c_str(), "rt");
	fscanf(fp, "%d", &frameCount);

	String path;
	String name;
	CommandLineParser::SplitFilePath(_filename, path, name);
	String nameWithoutExt = name.substr(0, name.length() - 7);
	String corespondingPngImage = path + String("/") + nameWithoutExt + String(".png");

	filename = pathToProcess + String("/") + nameWithoutExt + String(".txt");
	
	PngImageExt image;
	image.Read(corespondingPngImage.c_str());
	spriteWidth = image.GetWidth() / frameCount;
	spriteHeight = image.GetHeight();
	
//	String dirWrite = path + String("/$process/"); 
//	mkdir(dirWrite.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
	if (CommandLineParser::Instance()->GetVerbose())printf("* frameCount: %d spriteWidth: %d spriteHeight: %d\n", frameCount, spriteWidth, spriteHeight); 


	frameRects = new Rect2i[frameCount];
	for (int k = 0; k < frameCount; ++k)
	{
		PngImageExt frameX;
		frameX.Create(spriteWidth, spriteHeight);
		frameX.DrawImage(0, 0, &image, Rect2i(k * spriteWidth, 0, spriteWidth, spriteHeight));
		
		
		Rect2i reducedRect;
		frameX.FindNonOpaqueRect(reducedRect);
		if (CommandLineParser::Instance()->GetVerbose())printf("%s - reduced_rect(%d %d %d %d)\n", nameWithoutExt.c_str(), reducedRect.x, reducedRect.y, reducedRect.dx, reducedRect.dy);
		
		/*if (k == 1)
		{
			for (int y = 0; y < spriteWidth; ++y)
			{
				for (int x = 0; x < spriteWidth; ++x)
				{
					printf("%02x ", frameX.GetPixel(x, y)[3]);
				}
				printf("\n");
			}
		}*/
		
		PngImageExt frameX2;
		frameX2.Create(reducedRect.dx, reducedRect.dy);
		frameX2.DrawImage(0, 0, &frameX, reducedRect);
		
		char number[10];
		sprintf(number, "%d", k);
		String fileWrite = pathToProcess + String("/") + nameWithoutExt + String(number) + String(".png"); 
		frameX2.Write(fileWrite.c_str());		
	
		frameRects[k].x = reducedRect.x;
		frameRects[k].y = reducedRect.y;
		frameRects[k].dx = reducedRect.dx;
		frameRects[k].dy = reducedRect.dy;
	
	
		if (CommandLineParser::Instance()->IsFlagSet("--add0pixel"))
		{
			
		}else if (CommandLineParser::Instance()->IsFlagSet("--add1pixel"))
		{
			frameRects[k].dx++;
			frameRects[k].dy++;
		}
		else if (CommandLineParser::Instance()->IsFlagSet("--add2pixel"))
		{
			frameRects[k].dx+=2;
			frameRects[k].dy+=2;
		}
		else if (CommandLineParser::Instance()->IsFlagSet("--add4pixel"))
		{
			frameRects[k].dx+=4;
			frameRects[k].dy+=4;
		}else 
		{
			frameRects[k].dx++;
			frameRects[k].dy++;	
		}
	}
	

	fclose(fp);
	return true;
}