forked from Mirrors/openclonk
181 lines
4.7 KiB
C++
181 lines
4.7 KiB
C++
/*
|
|
* OpenClonk, http://www.openclonk.org
|
|
*
|
|
* Copyright (c) 1998-2000, Matthes Bender
|
|
* Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/
|
|
* Copyright (c) 2009-2016, The OpenClonk Team and contributors
|
|
*
|
|
* Distributed under the terms of the ISC license; see accompanying file
|
|
* "COPYING" for details.
|
|
*
|
|
* "Clonk" is a registered trademark of Matthes Bender, used with permission.
|
|
* See accompanying file "TRADEMARK" for details.
|
|
*
|
|
* To redistribute this file separately, substitute the full license texts
|
|
* for the above references.
|
|
*/
|
|
|
|
/* A facet that can hold its own surface and also target coordinates */
|
|
|
|
#include "C4Include.h"
|
|
#include "graphics/C4FacetEx.h"
|
|
#include "graphics/C4Draw.h"
|
|
|
|
#include "lib/C4Rect.h"
|
|
#include "c4group/C4Group.h"
|
|
|
|
void C4TargetFacet::Set(C4Surface * nsfc, float nx, float ny, float nwdt, float nhgt, float ntx, float nty, float Zoom)
|
|
{
|
|
Set(nsfc, nx, ny, nwdt, nhgt, ntx, nty, Zoom, ntx, nty);
|
|
}
|
|
|
|
void C4TargetFacet::Set(C4Surface * nsfc, float nx, float ny, float nwdt, float nhgt, float ntx, float nty, float Zoom, float prx, float pry)
|
|
{
|
|
C4Facet::Set(nsfc, nx, ny, nwdt, nhgt);
|
|
TargetX = ntx; TargetY = nty; this->Zoom = Zoom;
|
|
ParRefX = prx; ParRefY = pry;
|
|
}
|
|
|
|
void C4TargetFacet::Set(C4Surface * nsfc, const C4Rect & r, float ntx, float nty, float Zoom)
|
|
{
|
|
Set(nsfc, r.x, r.y, r.Wdt, r.Hgt, ntx, nty, Zoom);
|
|
}
|
|
|
|
void C4TargetFacet::SetRect(C4TargetRect &rSrc)
|
|
{
|
|
X=rSrc.x; Y=rSrc.y; Wdt=rSrc.Wdt; Hgt=rSrc.Hgt;
|
|
TargetX=rSrc.tx; TargetY=rSrc.ty;
|
|
ParRefX=rSrc.tx; TargetY=rSrc.ty;
|
|
}
|
|
|
|
// ------------------------
|
|
// C4FacetSurface
|
|
|
|
bool C4FacetSurface::Create(int iWdt, int iHgt, int iWdt2, int iHgt2)
|
|
{
|
|
Clear();
|
|
// Create surface
|
|
Face.Default();
|
|
if (!Face.Create(iWdt,iHgt)) return false;
|
|
// Set facet
|
|
if (iWdt2 == C4FCT_Full || iWdt2 == C4FCT_Width)
|
|
iWdt2 = Face.Wdt;
|
|
else if (iWdt2 == C4FCT_Height)
|
|
iWdt2 = Face.Hgt;
|
|
if (iHgt2 == C4FCT_Full || iHgt2 == C4FCT_Height)
|
|
iHgt2 = Face.Hgt;
|
|
else if (iHgt2 == C4FCT_Width)
|
|
iHgt2 = Face.Wdt;
|
|
Set(&Face,0,0,iWdt2,iHgt2);
|
|
return true;
|
|
}
|
|
|
|
bool C4FacetSurface::CreateClrByOwner(C4Surface *pBySurface)
|
|
{
|
|
Clear();
|
|
// create surface
|
|
if (!Face.CreateColorByOwner(pBySurface)) return false;
|
|
// set facet
|
|
Set(&Face,0,0,Face.Wdt,Face.Hgt);
|
|
// success
|
|
return true;
|
|
}
|
|
|
|
bool C4FacetSurface::Load(C4Group &hGroup, const char *szName, int iWdt, int iHgt, bool fNoErrIfNotFound, int iFlags)
|
|
{
|
|
Clear();
|
|
// Entry name
|
|
char szFilename[_MAX_FNAME+1];
|
|
SCopy(szName,szFilename,_MAX_FNAME);
|
|
char *szExt = GetExtension(szFilename);
|
|
if (!*szExt)
|
|
{
|
|
// no extension: Default to extension that is found as file in group
|
|
const char * const extensions[] = { "png", "bmp", "jpeg", "jpg", nullptr };
|
|
int i = 0; const char *szExt;
|
|
while ((szExt = extensions[i++]))
|
|
{
|
|
EnforceExtension(szFilename, szExt);
|
|
if (hGroup.FindEntry(szFilename)) break;
|
|
}
|
|
}
|
|
// Load surface
|
|
if (!Face.Load(hGroup,szFilename,false,fNoErrIfNotFound, iFlags)) return false;
|
|
// Set facet
|
|
if (iWdt == C4FCT_Full || iWdt == C4FCT_Width)
|
|
iWdt = Face.Wdt;
|
|
else if (iWdt == C4FCT_Height)
|
|
iWdt = Face.Hgt;
|
|
if (iHgt == C4FCT_Full || iHgt == C4FCT_Height)
|
|
iHgt = Face.Hgt;
|
|
else if (iHgt == C4FCT_Width)
|
|
iHgt = Face.Wdt;
|
|
Set(&Face,0,0,iWdt,iHgt);
|
|
return true;
|
|
}
|
|
|
|
bool C4FacetSurface::CopyFromSfcMaxSize(C4Surface &srcSfc, int32_t iMaxSize, uint32_t dwColor)
|
|
{
|
|
// safety
|
|
if (!srcSfc.Wdt || !srcSfc.Hgt) return false;
|
|
Clear();
|
|
// no scale?
|
|
bool fNeedsScale = !(srcSfc.Wdt <= iMaxSize && srcSfc.Hgt <= iMaxSize);
|
|
if (!fNeedsScale && !dwColor)
|
|
{
|
|
// no change necessary; just copy then
|
|
Face.Copy(srcSfc);
|
|
}
|
|
else
|
|
{
|
|
// must scale down or colorize. Just blit.
|
|
C4Facet fctSource;
|
|
fctSource.Set(&srcSfc, 0,0,srcSfc.Wdt,srcSfc.Hgt);
|
|
int32_t iTargetWdt, iTargetHgt;
|
|
if (fNeedsScale)
|
|
{
|
|
if (fctSource.Wdt > fctSource.Hgt)
|
|
{
|
|
iTargetWdt = iMaxSize;
|
|
iTargetHgt = fctSource.Hgt * iTargetWdt / fctSource.Wdt;
|
|
}
|
|
else
|
|
{
|
|
iTargetHgt = iMaxSize;
|
|
iTargetWdt = fctSource.Wdt * iTargetHgt / fctSource.Hgt;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
iTargetWdt = fctSource.Wdt;
|
|
iTargetHgt = fctSource.Hgt;
|
|
}
|
|
if (dwColor) srcSfc.SetClr(dwColor);
|
|
Create(iTargetWdt, iTargetHgt);
|
|
pDraw->Blit(&srcSfc, 0.0f,0.0f,float(fctSource.Wdt),float(fctSource.Hgt),
|
|
&Face, 0,0,iTargetWdt,iTargetHgt);
|
|
}
|
|
Set(&Face, 0,0, Face.Wdt, Face.Hgt);
|
|
return true;
|
|
}
|
|
|
|
void C4FacetSurface::Grayscale(int32_t iOffset)
|
|
{
|
|
if (!pDraw || !Surface || !Wdt || !Hgt) return;
|
|
pDraw->Grayscale(Surface, iOffset);
|
|
}
|
|
|
|
bool C4FacetSurface::EnsureOwnSurface()
|
|
{
|
|
// is it a link?
|
|
if (Surface != &Face)
|
|
{
|
|
// then recreate in same size
|
|
C4Facet fctOld = *this;
|
|
if (!Create(fctOld.Wdt, fctOld.Hgt)) return false;
|
|
fctOld.Draw(*this);
|
|
}
|
|
return true;
|
|
}
|
|
|