blob: bd71d50b06eac11fddc7f64958f3d0ac45b9590b [file] [log] [blame]
Matt Mowere04eee72016-12-31 00:38:57 -06001/*
2 Copyright 2017 TeamWin
3 This file is part of TWRP/TeamWin Recovery Project.
4
5 TWRP is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
9
10 TWRP is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with TWRP. If not, see <http://www.gnu.org/licenses/>.
17*/
18
Dees_Troy51a0e822012-09-05 15:24:24 -040019// resource.cpp - Source to manage GUI resources
20
21#include <stdarg.h>
22#include <stdio.h>
23#include <stdlib.h>
24#include <string.h>
Dees_Troy51a0e822012-09-05 15:24:24 -040025#include <unistd.h>
Dees_Troy51a0e822012-09-05 15:24:24 -040026
27#include <string>
28#include <sstream>
29#include <iostream>
30#include <iomanip>
Ethan Yonker3fdcda42016-11-30 12:29:37 -060031#include <fcntl.h>
Dees_Troy51a0e822012-09-05 15:24:24 -040032
thatb2e8f672015-03-05 20:25:39 +010033#include "../minzip/Zip.h"
Dees_Troy51a0e822012-09-05 15:24:24 -040034extern "C" {
Dees_Troy2673cec2013-04-02 20:22:16 +000035#include "../twcommon.h"
Ethan Yonker63e414f2015-02-06 15:44:39 -060036#include "gui.h"
Dees_Troy51a0e822012-09-05 15:24:24 -040037}
Ethan Yonkerfbb43532015-12-28 21:54:50 +010038#include "../minuitwrp/minui.h"
Dees_Troy51a0e822012-09-05 15:24:24 -040039
40#include "rapidxml.hpp"
41#include "objects.hpp"
42
43#define TMP_RESOURCE_NAME "/tmp/extract.bin"
44
Ethan Yonkerd0514ba2015-10-22 14:17:47 -050045Resource::Resource(xml_node<>* node, ZipArchive* pZip __unused)
Dees_Troy51a0e822012-09-05 15:24:24 -040046{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +020047 if (node && node->first_attribute("name"))
48 mName = node->first_attribute("name")->value();
Dees_Troy51a0e822012-09-05 15:24:24 -040049}
50
Vojtech Bocekfafb0c52013-07-25 22:53:02 +020051int Resource::ExtractResource(ZipArchive* pZip, std::string folderName, std::string fileName, std::string fileExtn, std::string destFile)
Dees_Troy51a0e822012-09-05 15:24:24 -040052{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +020053 if (!pZip)
54 return -1;
Dees_Troy51a0e822012-09-05 15:24:24 -040055
Vojtech Bocekfafb0c52013-07-25 22:53:02 +020056 std::string src = folderName + "/" + fileName + fileExtn;
Dees_Troy51a0e822012-09-05 15:24:24 -040057
58 const ZipEntry* binary = mzFindZipEntry(pZip, src.c_str());
Vojtech Bocekfafb0c52013-07-25 22:53:02 +020059 if (binary == NULL) {
60 return -1;
Dees_Troy51a0e822012-09-05 15:24:24 -040061 }
62
Vojtech Bocekfafb0c52013-07-25 22:53:02 +020063 unlink(destFile.c_str());
64 int fd = creat(destFile.c_str(), 0666);
65 if (fd < 0)
66 return -1;
Dees_Troy51a0e822012-09-05 15:24:24 -040067
Vojtech Bocekfafb0c52013-07-25 22:53:02 +020068 int ret = 0;
69 if (!mzExtractZipEntryToFile(pZip, binary, fd))
70 ret = -1;
Dees_Troy51a0e822012-09-05 15:24:24 -040071
Vojtech Bocekfafb0c52013-07-25 22:53:02 +020072 close(fd);
73 return ret;
Dees_Troy51a0e822012-09-05 15:24:24 -040074}
75
thatb240f4a2016-03-14 01:21:38 +010076void Resource::LoadImage(ZipArchive* pZip, std::string file, gr_surface* surface)
Ethan Yonker63e414f2015-02-06 15:44:39 -060077{
thatb240f4a2016-03-14 01:21:38 +010078 int rc = 0;
Ethan Yonker63e414f2015-02-06 15:44:39 -060079 if (ExtractResource(pZip, "images", file, ".png", TMP_RESOURCE_NAME) == 0)
80 {
thatb240f4a2016-03-14 01:21:38 +010081 rc = res_create_surface(TMP_RESOURCE_NAME, surface);
Ethan Yonker63e414f2015-02-06 15:44:39 -060082 unlink(TMP_RESOURCE_NAME);
83 }
84 else if (ExtractResource(pZip, "images", file, "", TMP_RESOURCE_NAME) == 0)
85 {
86 // JPG includes the .jpg extension in the filename so extension should be blank
thatb240f4a2016-03-14 01:21:38 +010087 rc = res_create_surface(TMP_RESOURCE_NAME, surface);
Ethan Yonker63e414f2015-02-06 15:44:39 -060088 unlink(TMP_RESOURCE_NAME);
89 }
90 else if (!pZip)
91 {
92 // File name in xml may have included .png so try without adding .png
thatb240f4a2016-03-14 01:21:38 +010093 rc = res_create_surface(file.c_str(), surface);
Ethan Yonker63e414f2015-02-06 15:44:39 -060094 }
thatb240f4a2016-03-14 01:21:38 +010095 if (rc != 0)
96 LOGINFO("Failed to load image from %s%s, error %d\n", file.c_str(), pZip ? " (zip)" : "", rc);
Ethan Yonker63e414f2015-02-06 15:44:39 -060097}
98
99void Resource::CheckAndScaleImage(gr_surface source, gr_surface* destination, int retain_aspect)
100{
101 if (!source) {
102 *destination = NULL;
103 return;
104 }
105 if (get_scale_w() != 0 && get_scale_h() != 0) {
106 float scale_w = get_scale_w(), scale_h = get_scale_h();
107 if (retain_aspect) {
108 if (scale_w < scale_h)
109 scale_h = scale_w;
110 else
111 scale_w = scale_h;
112 }
113 if (res_scale_surface(source, destination, scale_w, scale_h)) {
114 LOGINFO("Error scaling image, using regular size.\n");
115 *destination = source;
116 }
117 } else {
118 *destination = source;
119 }
120}
121
Dees_Troy51a0e822012-09-05 15:24:24 -0400122FontResource::FontResource(xml_node<>* node, ZipArchive* pZip)
123 : Resource(node, pZip)
124{
Ethan Yonker74db1572015-10-28 12:44:49 -0500125 origFontSize = 0;
126 origFont = NULL;
127 LoadFont(node, pZip);
128}
129
130void FontResource::LoadFont(xml_node<>* node, ZipArchive* pZip)
131{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200132 std::string file;
Vojtech Bocek76ee9032014-09-07 15:01:56 +0200133 xml_attribute<>* attr;
Dees_Troy51a0e822012-09-05 15:24:24 -0400134
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200135 mFont = NULL;
136 if (!node)
137 return;
Dees_Troy51a0e822012-09-05 15:24:24 -0400138
Vojtech Bocek76ee9032014-09-07 15:01:56 +0200139 attr = node->first_attribute("filename");
140 if (!attr)
141 return;
Dees_Troy51a0e822012-09-05 15:24:24 -0400142
Vojtech Bocek76ee9032014-09-07 15:01:56 +0200143 file = attr->value();
144
Matt Mowera8a89d12016-12-30 18:10:37 -0600145 if (file.size() >= 4 && file.compare(file.size()-4, 4, ".ttf") == 0)
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200146 {
Ethan Yonker74db1572015-10-28 12:44:49 -0500147 int font_size = 0;
Vojtech Bocek76ee9032014-09-07 15:01:56 +0200148
Ethan Yonker74db1572015-10-28 12:44:49 -0500149 if (origFontSize != 0) {
150 attr = node->first_attribute("scale");
151 if (attr == NULL)
152 return;
153 font_size = origFontSize * atoi(attr->value()) / 100;
154 } else {
155 attr = node->first_attribute("size");
156 if (attr == NULL)
157 return;
158 font_size = scale_theme_min(atoi(attr->value()));
159 origFontSize = font_size;
160 }
Vojtech Bocek76ee9032014-09-07 15:01:56 +0200161
Vojtech Bocek76ee9032014-09-07 15:01:56 +0200162 int dpi = 300;
163
164 attr = node->first_attribute("dpi");
Matt Mowera8a89d12016-12-30 18:10:37 -0600165 if (attr)
Vojtech Bocek76ee9032014-09-07 15:01:56 +0200166 dpi = atoi(attr->value());
167
thatb240f4a2016-03-14 01:21:38 +0100168 // we can't use TMP_RESOURCE_NAME here because the ttf subsystem is caching the name and scaling needs to reload the font
169 std::string tmpname = "/tmp/" + file;
170 if (ExtractResource(pZip, "fonts", file, "", tmpname) == 0)
Vojtech Bocek76ee9032014-09-07 15:01:56 +0200171 {
thatb240f4a2016-03-14 01:21:38 +0100172 mFont = gr_ttf_loadFont(tmpname.c_str(), font_size, dpi);
Vojtech Bocek76ee9032014-09-07 15:01:56 +0200173 }
174 else
175 {
Dees Troy3454ade2015-01-20 19:21:04 +0000176 file = std::string(TWRES "fonts/") + file;
Ethan Yonker74db1572015-10-28 12:44:49 -0500177 mFont = gr_ttf_loadFont(file.c_str(), font_size, dpi);
Vojtech Bocek76ee9032014-09-07 15:01:56 +0200178 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200179 }
180 else
181 {
Ethan Yonker88037f42015-10-04 22:09:08 -0500182 LOGERR("Non-TTF fonts are no longer supported.\n");
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200183 }
Dees_Troy51a0e822012-09-05 15:24:24 -0400184}
185
Ethan Yonker74db1572015-10-28 12:44:49 -0500186void FontResource::DeleteFont() {
Matt Mowera8a89d12016-12-30 18:10:37 -0600187 if (mFont)
Ethan Yonker74db1572015-10-28 12:44:49 -0500188 gr_ttf_freeFont(mFont);
189 mFont = NULL;
Matt Mowera8a89d12016-12-30 18:10:37 -0600190 if (origFont)
Ethan Yonker74db1572015-10-28 12:44:49 -0500191 gr_ttf_freeFont(origFont);
192 origFont = NULL;
193}
194
195void FontResource::Override(xml_node<>* node, ZipArchive* pZip) {
196 if (!origFont) {
197 origFont = mFont;
198 } else if (mFont) {
199 gr_ttf_freeFont(mFont);
200 mFont = NULL;
201 }
202 LoadFont(node, pZip);
203}
204
Dees_Troy51a0e822012-09-05 15:24:24 -0400205FontResource::~FontResource()
206{
Ethan Yonker74db1572015-10-28 12:44:49 -0500207 DeleteFont();
Dees_Troy51a0e822012-09-05 15:24:24 -0400208}
209
that5267a212015-05-06 23:45:57 +0200210ImageResource::ImageResource(xml_node<>* node, ZipArchive* pZip)
Dees_Troy51a0e822012-09-05 15:24:24 -0400211 : Resource(node, pZip)
212{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200213 std::string file;
Ethan Yonker63e414f2015-02-06 15:44:39 -0600214 gr_surface temp_surface = NULL;
Dees_Troy51a0e822012-09-05 15:24:24 -0400215
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200216 mSurface = NULL;
Ethan Yonker619a7212014-12-03 16:47:37 -0600217 if (!node) {
218 LOGERR("ImageResource node is NULL\n");
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200219 return;
Ethan Yonker619a7212014-12-03 16:47:37 -0600220 }
Dees_Troy51a0e822012-09-05 15:24:24 -0400221
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200222 if (node->first_attribute("filename"))
223 file = node->first_attribute("filename")->value();
Ethan Yonker63e414f2015-02-06 15:44:39 -0600224 else {
225 LOGERR("No filename specified for image resource.\n");
226 return;
227 }
Dees_Troy51a0e822012-09-05 15:24:24 -0400228
that5267a212015-05-06 23:45:57 +0200229 bool retain_aspect = (node->first_attribute("retainaspect") != NULL);
230 // the value does not matter, if retainaspect is present, we assume that we want to retain it
Ethan Yonker63e414f2015-02-06 15:44:39 -0600231 LoadImage(pZip, file, &temp_surface);
232 CheckAndScaleImage(temp_surface, &mSurface, retain_aspect);
Dees_Troy51a0e822012-09-05 15:24:24 -0400233}
234
235ImageResource::~ImageResource()
236{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200237 if (mSurface)
238 res_free_surface(mSurface);
Dees_Troy51a0e822012-09-05 15:24:24 -0400239}
240
that5267a212015-05-06 23:45:57 +0200241AnimationResource::AnimationResource(xml_node<>* node, ZipArchive* pZip)
Dees_Troy51a0e822012-09-05 15:24:24 -0400242 : Resource(node, pZip)
243{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200244 std::string file;
245 int fileNum = 1;
Dees_Troy51a0e822012-09-05 15:24:24 -0400246
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200247 if (!node)
248 return;
Dees_Troy51a0e822012-09-05 15:24:24 -0400249
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200250 if (node->first_attribute("filename"))
251 file = node->first_attribute("filename")->value();
Ethan Yonker63e414f2015-02-06 15:44:39 -0600252 else {
253 LOGERR("No filename specified for image resource.\n");
254 return;
255 }
Dees_Troy51a0e822012-09-05 15:24:24 -0400256
that5267a212015-05-06 23:45:57 +0200257 bool retain_aspect = (node->first_attribute("retainaspect") != NULL);
258 // the value does not matter, if retainaspect is present, we assume that we want to retain it
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200259 for (;;)
260 {
261 std::ostringstream fileName;
262 fileName << file << std::setfill ('0') << std::setw (3) << fileNum;
Dees_Troy51a0e822012-09-05 15:24:24 -0400263
Ethan Yonker63e414f2015-02-06 15:44:39 -0600264 gr_surface surface, temp_surface = NULL;
265 LoadImage(pZip, fileName.str(), &temp_surface);
266 CheckAndScaleImage(temp_surface, &surface, retain_aspect);
267 if (surface) {
268 mSurfaces.push_back(surface);
269 fileNum++;
270 } else
271 break; // Done loading animation images
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200272 }
Dees_Troy51a0e822012-09-05 15:24:24 -0400273}
274
275AnimationResource::~AnimationResource()
276{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200277 std::vector<gr_surface>::iterator it;
Dees_Troy51a0e822012-09-05 15:24:24 -0400278
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200279 for (it = mSurfaces.begin(); it != mSurfaces.end(); ++it)
280 res_free_surface(*it);
281
282 mSurfaces.clear();
Dees_Troy51a0e822012-09-05 15:24:24 -0400283}
284
that74ac6062015-03-04 22:39:34 +0100285FontResource* ResourceManager::FindFont(const std::string& name) const
Dees_Troy51a0e822012-09-05 15:24:24 -0400286{
that74ac6062015-03-04 22:39:34 +0100287 for (std::vector<FontResource*>::const_iterator it = mFonts.begin(); it != mFonts.end(); ++it)
288 if (name == (*it)->GetName())
289 return *it;
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200290 return NULL;
Dees_Troy51a0e822012-09-05 15:24:24 -0400291}
292
that74ac6062015-03-04 22:39:34 +0100293ImageResource* ResourceManager::FindImage(const std::string& name) const
Dees_Troy51a0e822012-09-05 15:24:24 -0400294{
that74ac6062015-03-04 22:39:34 +0100295 for (std::vector<ImageResource*>::const_iterator it = mImages.begin(); it != mImages.end(); ++it)
296 if (name == (*it)->GetName())
297 return *it;
298 return NULL;
299}
300
301AnimationResource* ResourceManager::FindAnimation(const std::string& name) const
302{
303 for (std::vector<AnimationResource*>::const_iterator it = mAnimations.begin(); it != mAnimations.end(); ++it)
304 if (name == (*it)->GetName())
305 return *it;
306 return NULL;
307}
308
thatb2e8f672015-03-05 20:25:39 +0100309std::string ResourceManager::FindString(const std::string& name) const
310{
Ethan Yonker74db1572015-10-28 12:44:49 -0500311 if (this != NULL) {
312 std::map<std::string, string_resource_struct>::const_iterator it = mStrings.find(name);
313 if (it != mStrings.end())
314 return it->second.value;
315 LOGERR("String resource '%s' not found. No default value.\n", name.c_str());
316 PageManager::AddStringResource("NO DEFAULT", name, "[" + name + ("]"));
317 } else {
318 LOGINFO("String resources not loaded when looking for '%s'. No default value.\n", name.c_str());
319 }
thatb2e8f672015-03-05 20:25:39 +0100320 return "[" + name + ("]");
321}
322
Ethan Yonker74db1572015-10-28 12:44:49 -0500323std::string ResourceManager::FindString(const std::string& name, const std::string& default_string) const
324{
325 if (this != NULL) {
326 std::map<std::string, string_resource_struct>::const_iterator it = mStrings.find(name);
327 if (it != mStrings.end())
328 return it->second.value;
329 LOGERR("String resource '%s' not found. Using default value.\n", name.c_str());
330 PageManager::AddStringResource("DEFAULT", name, default_string);
331 } else {
332 LOGINFO("String resources not loaded when looking for '%s'. Using default value.\n", name.c_str());
333 }
334 return default_string;
335}
336
337void ResourceManager::DumpStrings() const
338{
339 if (this == NULL) {
340 gui_print("No string resources\n");
341 return;
342 }
343 std::map<std::string, string_resource_struct>::const_iterator it;
344 gui_print("Dumping all strings:\n");
345 for (it = mStrings.begin(); it != mStrings.end(); it++)
346 gui_print("source: %s: '%s' = '%s'\n", it->second.source.c_str(), it->first.c_str(), it->second.value.c_str());
347 gui_print("Done dumping strings\n");
348}
349
that74ac6062015-03-04 22:39:34 +0100350ResourceManager::ResourceManager()
351{
Ethan Yonker780cd392014-07-21 15:24:39 -0500352}
353
Ethan Yonker74db1572015-10-28 12:44:49 -0500354void ResourceManager::AddStringResource(std::string resource_source, std::string resource_name, std::string value)
355{
356 string_resource_struct res;
357 res.source = resource_source;
358 res.value = value;
359 mStrings[resource_name] = res;
360}
361
362void ResourceManager::LoadResources(xml_node<>* resList, ZipArchive* pZip, std::string resource_source)
Ethan Yonker780cd392014-07-21 15:24:39 -0500363{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200364 if (!resList)
365 return;
that0f425062015-03-04 23:05:00 +0100366
367 for (xml_node<>* child = resList->first_node(); child; child = child->next_sibling())
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200368 {
that0f425062015-03-04 23:05:00 +0100369 std::string type = child->name();
370 if (type == "resource") {
371 // legacy format : <resource type="...">
372 xml_attribute<>* attr = child->first_attribute("type");
373 type = attr ? attr->value() : "*unspecified*";
374 }
Dees_Troy51a0e822012-09-05 15:24:24 -0400375
that74ac6062015-03-04 22:39:34 +0100376 bool error = false;
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200377 if (type == "font")
378 {
that74ac6062015-03-04 22:39:34 +0100379 FontResource* res = new FontResource(child, pZip);
380 if (res->GetResource())
381 mFonts.push_back(res);
382 else {
383 error = true;
384 delete res;
385 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200386 }
Ethan Yonker74db1572015-10-28 12:44:49 -0500387 else if (type == "fontoverride")
388 {
389 if (mFonts.size() != 0 && child && child->first_attribute("name")) {
390 string FontName = child->first_attribute("name")->value();
391 size_t font_count = mFonts.size(), i;
392 bool found = false;
393
394 for (i = 0; i < font_count; i++) {
395 if (mFonts[i]->GetName() == FontName) {
396 mFonts[i]->Override(child, pZip);
397 found = true;
398 break;
399 }
400 }
401 if (!found) {
402 LOGERR("Unable to locate font '%s' for override.\n", FontName.c_str());
403 }
404 } else if (mFonts.size() != 0)
405 LOGERR("Unable to locate font name for type fontoverride.\n");
406 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200407 else if (type == "image")
408 {
that5267a212015-05-06 23:45:57 +0200409 ImageResource* res = new ImageResource(child, pZip);
that74ac6062015-03-04 22:39:34 +0100410 if (res->GetResource())
411 mImages.push_back(res);
412 else {
413 error = true;
414 delete res;
415 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200416 }
417 else if (type == "animation")
418 {
that5267a212015-05-06 23:45:57 +0200419 AnimationResource* res = new AnimationResource(child, pZip);
that74ac6062015-03-04 22:39:34 +0100420 if (res->GetResourceCount())
421 mAnimations.push_back(res);
422 else {
423 error = true;
424 delete res;
425 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200426 }
thatb2e8f672015-03-05 20:25:39 +0100427 else if (type == "string")
428 {
Ethan Yonker74db1572015-10-28 12:44:49 -0500429 if (xml_attribute<>* attr = child->first_attribute("name")) {
430 string_resource_struct res;
431 res.source = resource_source;
432 res.value = child->value();
433 mStrings[attr->value()] = res;
434 } else
thatb2e8f672015-03-05 20:25:39 +0100435 error = true;
436 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200437 else
438 {
439 LOGERR("Resource type (%s) not supported.\n", type.c_str());
that74ac6062015-03-04 22:39:34 +0100440 error = true;
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200441 }
thatf6ed8fc2015-02-14 20:23:16 +0100442
that74ac6062015-03-04 22:39:34 +0100443 if (error)
thatf74ac872015-01-18 12:00:02 +0100444 {
445 std::string res_name;
446 if (child->first_attribute("name"))
447 res_name = child->first_attribute("name")->value();
448 if (res_name.empty() && child->first_attribute("filename"))
449 res_name = child->first_attribute("filename")->value();
450
451 if (!res_name.empty()) {
452 LOGERR("Resource (%s)-(%s) failed to load\n", type.c_str(), res_name.c_str());
453 } else
454 LOGERR("Resource type (%s) failed to load\n", type.c_str());
thatf74ac872015-01-18 12:00:02 +0100455 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200456 }
Dees_Troy51a0e822012-09-05 15:24:24 -0400457}
458
459ResourceManager::~ResourceManager()
460{
that74ac6062015-03-04 22:39:34 +0100461 for (std::vector<FontResource*>::iterator it = mFonts.begin(); it != mFonts.end(); ++it)
462 delete *it;
Dees_Troy51a0e822012-09-05 15:24:24 -0400463
that74ac6062015-03-04 22:39:34 +0100464 for (std::vector<ImageResource*>::iterator it = mImages.begin(); it != mImages.end(); ++it)
465 delete *it;
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200466
that74ac6062015-03-04 22:39:34 +0100467 for (std::vector<AnimationResource*>::iterator it = mAnimations.begin(); it != mAnimations.end(); ++it)
468 delete *it;
Dees_Troy51a0e822012-09-05 15:24:24 -0400469}