1 /*
2 * OpenClonk, http://www.openclonk.org
3 *
4 * Copyright (c) 1998-2000, Matthes Bender
5 * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/
6 * Copyright (c) 2009-2016, The OpenClonk Team and contributors
7 *
8 * Distributed under the terms of the ISC license; see accompanying file
9 * "COPYING" for details.
10 *
11 * "Clonk" is a registered trademark of Matthes Bender, used with permission.
12 * See accompanying file "TRADEMARK" for details.
13 *
14 * To redistribute this file separately, substitute the full license texts
15 * for the above references.
16 */
17
18 /* A facet that can hold its own surface and also target coordinates */
19
20 #include "C4Include.h"
21 #include "graphics/C4FacetEx.h"
22 #include "graphics/C4Draw.h"
23
24 #include "lib/C4Rect.h"
25 #include "c4group/C4Group.h"
26
Set(C4Surface * nsfc,float nx,float ny,float nwdt,float nhgt,float ntx,float nty,float Zoom)27 void C4TargetFacet::Set(C4Surface * nsfc, float nx, float ny, float nwdt, float nhgt, float ntx, float nty, float Zoom)
28 {
29 Set(nsfc, nx, ny, nwdt, nhgt, ntx, nty, Zoom, ntx, nty);
30 }
31
Set(C4Surface * nsfc,float nx,float ny,float nwdt,float nhgt,float ntx,float nty,float Zoom,float prx,float pry)32 void C4TargetFacet::Set(C4Surface * nsfc, float nx, float ny, float nwdt, float nhgt, float ntx, float nty, float Zoom, float prx, float pry)
33 {
34 C4Facet::Set(nsfc, nx, ny, nwdt, nhgt);
35 TargetX = ntx; TargetY = nty; this->Zoom = Zoom;
36 ParRefX = prx; ParRefY = pry;
37 }
38
Set(C4Surface * nsfc,const C4Rect & r,float ntx,float nty,float Zoom)39 void C4TargetFacet::Set(C4Surface * nsfc, const C4Rect & r, float ntx, float nty, float Zoom)
40 {
41 Set(nsfc, r.x, r.y, r.Wdt, r.Hgt, ntx, nty, Zoom);
42 }
43
SetRect(C4TargetRect & rSrc)44 void C4TargetFacet::SetRect(C4TargetRect &rSrc)
45 {
46 X=rSrc.x; Y=rSrc.y; Wdt=rSrc.Wdt; Hgt=rSrc.Hgt;
47 TargetX=rSrc.tx; TargetY=rSrc.ty;
48 ParRefX=rSrc.tx; TargetY=rSrc.ty;
49 }
50
51 // ------------------------
52 // C4FacetSurface
53
Create(int iWdt,int iHgt,int iWdt2,int iHgt2)54 bool C4FacetSurface::Create(int iWdt, int iHgt, int iWdt2, int iHgt2)
55 {
56 Clear();
57 // Create surface
58 Face.Default();
59 if (!Face.Create(iWdt,iHgt)) return false;
60 // Set facet
61 if (iWdt2==C4FCT_Full) iWdt2=Face.Wdt; if (iWdt2==C4FCT_Height) iWdt2=Face.Hgt; if (iWdt2==C4FCT_Width) iWdt2=Face.Wdt;
62 if (iHgt2==C4FCT_Full) iHgt2=Face.Hgt; if (iHgt2==C4FCT_Height) iHgt2=Face.Hgt; if (iHgt2==C4FCT_Width) iHgt2=Face.Wdt;
63 Set(&Face,0,0,iWdt2,iHgt2);
64 return true;
65 }
66
CreateClrByOwner(C4Surface * pBySurface)67 bool C4FacetSurface::CreateClrByOwner(C4Surface *pBySurface)
68 {
69 Clear();
70 // create surface
71 if (!Face.CreateColorByOwner(pBySurface)) return false;
72 // set facet
73 Set(&Face,0,0,Face.Wdt,Face.Hgt);
74 // success
75 return true;
76 }
77
Load(C4Group & hGroup,const char * szName,int iWdt,int iHgt,bool fNoErrIfNotFound,int iFlags)78 bool C4FacetSurface::Load(C4Group &hGroup, const char *szName, int iWdt, int iHgt, bool fNoErrIfNotFound, int iFlags)
79 {
80 Clear();
81 // Entry name
82 char szFilename[_MAX_FNAME+1];
83 SCopy(szName,szFilename,_MAX_FNAME);
84 char *szExt = GetExtension(szFilename);
85 if (!*szExt)
86 {
87 // no extension: Default to extension that is found as file in group
88 const char * const extensions[] = { "png", "bmp", "jpeg", "jpg", nullptr };
89 int i = 0; const char *szExt;
90 while ((szExt = extensions[i++]))
91 {
92 EnforceExtension(szFilename, szExt);
93 if (hGroup.FindEntry(szFilename)) break;
94 }
95 }
96 // Load surface
97 if (!Face.Load(hGroup,szFilename,false,fNoErrIfNotFound, iFlags)) return false;
98 // Set facet
99 if (iWdt==C4FCT_Full) iWdt=Face.Wdt; if (iWdt==C4FCT_Height) iWdt=Face.Hgt; if (iWdt==C4FCT_Width) iWdt=Face.Wdt;
100 if (iHgt==C4FCT_Full) iHgt=Face.Hgt; if (iHgt==C4FCT_Height) iHgt=Face.Hgt; if (iHgt==C4FCT_Width) iHgt=Face.Wdt;
101 Set(&Face,0,0,iWdt,iHgt);
102 return true;
103 }
104
CopyFromSfcMaxSize(C4Surface & srcSfc,int32_t iMaxSize,uint32_t dwColor)105 bool C4FacetSurface::CopyFromSfcMaxSize(C4Surface &srcSfc, int32_t iMaxSize, uint32_t dwColor)
106 {
107 // safety
108 if (!srcSfc.Wdt || !srcSfc.Hgt) return false;
109 Clear();
110 // no scale?
111 bool fNeedsScale = !(srcSfc.Wdt <= iMaxSize && srcSfc.Hgt <= iMaxSize);
112 if (!fNeedsScale && !dwColor)
113 {
114 // no change necessary; just copy then
115 Face.Copy(srcSfc);
116 }
117 else
118 {
119 // must scale down or colorize. Just blit.
120 C4Facet fctSource;
121 fctSource.Set(&srcSfc, 0,0,srcSfc.Wdt,srcSfc.Hgt);
122 int32_t iTargetWdt, iTargetHgt;
123 if (fNeedsScale)
124 {
125 if (fctSource.Wdt > fctSource.Hgt)
126 {
127 iTargetWdt = iMaxSize;
128 iTargetHgt = fctSource.Hgt * iTargetWdt / fctSource.Wdt;
129 }
130 else
131 {
132 iTargetHgt = iMaxSize;
133 iTargetWdt = fctSource.Wdt * iTargetHgt / fctSource.Hgt;
134 }
135 }
136 else
137 {
138 iTargetWdt = fctSource.Wdt;
139 iTargetHgt = fctSource.Hgt;
140 }
141 if (dwColor) srcSfc.SetClr(dwColor);
142 Create(iTargetWdt, iTargetHgt);
143 pDraw->Blit(&srcSfc, 0.0f,0.0f,float(fctSource.Wdt),float(fctSource.Hgt),
144 &Face, 0,0,iTargetWdt,iTargetHgt);
145 }
146 Set(&Face, 0,0, Face.Wdt, Face.Hgt);
147 return true;
148 }
149
Grayscale(int32_t iOffset)150 void C4FacetSurface::Grayscale(int32_t iOffset)
151 {
152 if (!pDraw || !Surface || !Wdt || !Hgt) return;
153 pDraw->Grayscale(Surface, iOffset);
154 }
155
EnsureOwnSurface()156 bool C4FacetSurface::EnsureOwnSurface()
157 {
158 // is it a link?
159 if (Surface != &Face)
160 {
161 // then recreate in same size
162 C4Facet fctOld = *this;
163 if (!Create(fctOld.Wdt, fctOld.Hgt)) return false;
164 fctOld.Draw(*this);
165 }
166 return true;
167 }
168
169