Files
minecraft-pe-0.6.1/src/client/gui/components/NinePatch.cpp
2026-03-02 22:04:18 +03:00

142 lines
4.5 KiB
C++
Executable File

#include "NinePatch.h"
NinePatchDescription::NinePatchDescription( float x, float y, float x1, float x2, float x3, float y1, float y2, float y3, float w, float e, float n, float s ) : u0(x), u1(x + x1), u2(x + x2), u3(x + x3),
v0(y), v1(y + y1), v2(y + y2), v3(y + y3),
w(w), e(e), n(n), s(s),
imgW(-1),
imgH(-1) {
}
NinePatchDescription& NinePatchDescription::transformUVForImage( const TextureData& d ) {
return transformUVForImageSize(d.w, d.h);
}
NinePatchDescription& NinePatchDescription::transformUVForImageSize( int w, int h ) {
if (imgW < 0)
imgW = imgH = 1;
const float us = (float) imgW / w; // @todo: prepare for normal blit? (e.g. mult by 256)
const float vs = (float) imgH / h;
u0 *= us; u1 *= us; u2 *= us; u3 *= us;
v0 *= vs; v1 *= vs; v2 *= vs; v3 *= vs;
imgW = w;
imgH = h;
return *this;
}
NinePatchDescription NinePatchDescription::createSymmetrical( int texWidth, int texHeight, const IntRectangle& src, int xCutAt, int yCutAt ) {
NinePatchDescription patch((float)src.x, (float)src.y,// width and height of src
(float)xCutAt, (float)(src.w-xCutAt), (float)src.w, // u tex coordinates
(float)yCutAt, (float)(src.h-yCutAt), (float)src.h, // v tex coordinates
(float)xCutAt, (float)xCutAt, (float)yCutAt, (float)yCutAt); // border width and heights
if (texWidth > 0) patch.transformUVForImageSize(texWidth, texHeight);
return patch;
}
NinePatchLayer::NinePatchLayer(const NinePatchDescription& desc, const std::string& imageName, Textures* textures, float w, float h)
: desc(desc),
imageName(imageName),
textures(textures),
w(-1), h(-1),
excluded(0)
{
setSize(w, h);
}
void NinePatchLayer::setSize( float w, float h ) {
if (w == this->w && h == this->h)
return;
this->w = w;
this->h = h;
for (int i = 0; i < 9; ++i)
buildQuad(i);
}
void NinePatchLayer::draw( Tesselator& t, float x, float y ) {
textures->loadAndBindTexture(imageName);
t.begin();
t.addOffset(x, y, 0);
for (int i = 0, b = 1; i < 9; ++i, b += b)
if ((b & excluded) == 0)
d(t, quads[i]);
t.addOffset(-x, -y, 0);
t.draw();
}
NinePatchLayer* NinePatchLayer::exclude( int excludeId ) {
return setExcluded(excluded | (1 << excludeId));
}
NinePatchLayer* NinePatchLayer::setExcluded( int exludeBits ) {
excluded = exludeBits;
return this;
}
void NinePatchLayer::buildQuad( int qid ) {
//@attn; fix
CachedQuad& q = quads[qid];
const int yid = qid / 3;
const int xid = qid - 3 * yid;
q.u0 = (&desc.u0)[xid];
q.u1 = (&desc.u0)[xid + 1];
q.v0 = (&desc.v0)[yid];
q.v1 = (&desc.v0)[yid + 1];
q.z = 0;
getPatchInfo(xid, yid, q.x0, q.x1, q.y0, q.y1);
/* q.x0 = w * (q.u0 - desc.u0);
q.y0 = h * (q.v0 - desc.v0);
q.x1 = w * (q.u1 - desc.u0);
q.y1 = h * (q.v1 - desc.v0);
*/
}
void NinePatchLayer::getPatchInfo( int xc, int yc, float& x0, float& x1, float& y0, float& y1 ) {
if (xc == 0) { x0 = 0; x1 = desc.w; }
else if (xc == 1) { x0 = desc.w; x1 = w - desc.e; }
else if (xc == 2) { x0 = w-desc.e; x1 = w; }
if (yc == 0) { y0 = 0; y1 = desc.n; }
else if (yc == 1) { y0 = desc.n; y1 = h - desc.s; }
else if (yc == 2) { y0 = h-desc.s; y1 = h; }
}
void NinePatchLayer::d( Tesselator& t, const CachedQuad& q ) {
/*
t.vertexUV(x , y + h, blitOffset, (float)(sx ), (float)(sy + sh));
t.vertexUV(x + w, y + h, blitOffset, (float)(sx + sw), (float)(sy + sh));
t.vertexUV(x + w, y , blitOffset, (float)(sx + sw), (float)(sy ));
t.vertexUV(x , y , blitOffset, (float)(sx ), (float)(sy ));
*/
t.vertexUV(q.x0, q.y1, q.z, q.u0, q.v1);
t.vertexUV(q.x1, q.y1, q.z, q.u1, q.v1);
t.vertexUV(q.x1, q.y0, q.z, q.u1, q.v0);
t.vertexUV(q.x0, q.y0, q.z, q.u0, q.v0);
}
NinePatchFactory::NinePatchFactory( Textures* textures, const std::string& imageName ) : textures(textures),
imageName(imageName),
width(1),
height(1) {
TextureId id = textures->loadTexture(imageName);
if (id != Textures::InvalidId) {
const TextureData* data = textures->getTemporaryTextureData(id);
if (data) { // This should never be false
width = data->w;
height = data->h;
}
} else {
LOGE("Error @ NinePatchFactory::ctor - Couldn't find texture: %s\n", imageName.c_str());
}
}
NinePatchLayer* NinePatchFactory::createSymmetrical( const IntRectangle& src, int xCutAt, int yCutAt, float w /*= 32.0f*/, float h /*= 32.0f*/ ) {
return new NinePatchLayer(
NinePatchDescription::createSymmetrical(width, height, src, xCutAt, yCutAt),
imageName, textures, w, h);
}