Line 32... |
Line 32... |
32 |
#include "tresources.h"
|
32 |
#include "tresources.h"
|
33 |
#include "tpagemanager.h"
|
33 |
#include "tpagemanager.h"
|
34 |
#include "tintborder.h"
|
34 |
#include "tintborder.h"
|
35 |
#include "terror.h"
|
35 |
#include "terror.h"
|
36 |
|
36 |
|
- |
|
37 |
#if __cplusplus < 201402L
|
- |
|
38 |
# error "This module requires at least C++14 standard!"
|
- |
|
39 |
#else
|
- |
|
40 |
# if __cplusplus < 201703L
|
- |
|
41 |
# include <experimental/filesystem>
|
- |
|
42 |
namespace fs = std::experimental::filesystem;
|
- |
|
43 |
# warning "Support for C++14 and experimental filesystem will be removed in a future version!"
|
- |
|
44 |
# else
|
- |
|
45 |
# include <filesystem>
|
- |
|
46 |
# ifdef __ANDROID__
|
- |
|
47 |
namespace fs = std::__fs::filesystem;
|
- |
|
48 |
# else
|
- |
|
49 |
namespace fs = std::filesystem;
|
- |
|
50 |
# endif
|
- |
|
51 |
# endif
|
- |
|
52 |
#endif
|
- |
|
53 |
|
37 |
using std::string;
|
54 |
using std::string;
|
38 |
using std::vector;
|
55 |
using std::vector;
|
39 |
|
56 |
|
40 |
bool TPageInterface::drawText(PAGE_T& pinfo, SkBitmap *img)
|
57 |
bool TPageInterface::drawText(PAGE_T& pinfo, SkBitmap *img)
|
41 |
{
|
58 |
{
|
Line 186... |
Line 203... |
186 |
delete intBorder;
|
203 |
delete intBorder;
|
187 |
intBorder = nullptr;
|
204 |
intBorder = nullptr;
|
188 |
}
|
205 |
}
|
189 |
|
206 |
|
190 |
// Try to find the border in the system table
|
207 |
// Try to find the border in the system table
|
191 |
BORDER_t bd, bda;
|
208 |
BORDER_t bd;
|
192 |
bool classExist = (gPageManager && gPageManager->getSystemDraw());
|
209 |
bool classExist = (gPageManager && gPageManager->getSystemDraw());
|
193 |
|
210 |
|
194 |
if (!classExist)
|
211 |
if (!classExist)
|
195 |
return false;
|
212 |
return false;
|
196 |
|
213 |
|
Line 199... |
Line 216... |
199 |
if (!gPageManager->getSystemDraw()->getBorder(borderName, TSystemDraw::LT_OFF, &bd, borderName))
|
216 |
if (!gPageManager->getSystemDraw()->getBorder(borderName, TSystemDraw::LT_OFF, &bd, borderName))
|
200 |
return false;
|
217 |
return false;
|
201 |
|
218 |
|
202 |
MSG_DEBUG("System border \"" << borderName << "\" found.");
|
219 |
MSG_DEBUG("System border \"" << borderName << "\" found.");
|
203 |
SkColor color = TColor::getSkiaColor(pinfo.sr[instance].cb); // border color
|
220 |
SkColor color = TColor::getSkiaColor(pinfo.sr[instance].cb); // border color
|
204 |
SkColor bgColor = TColor::getSkiaColor(pinfo.sr[instance].cf); // fill color
|
- |
|
205 |
MSG_DEBUG("Button color: #" << std::setw(6) << std::setfill('0') << std::hex << color << std::dec);
|
221 |
MSG_DEBUG("Button color: #" << std::setw(6) << std::setfill('0') << std::hex << color << std::dec);
|
206 |
// Load images
|
222 |
// Load images
|
207 |
SkBitmap imgB, imgBR, imgR, imgTR, imgT, imgTL, imgL, imgBL;
|
223 |
SkBitmap imgB, imgBR, imgR, imgTR, imgT, imgTL, imgL, imgBL;
|
208 |
|
224 |
|
209 |
imgB = retrieveBorderImage(bd.b, bda.b, color, bgColor);
|
225 |
if (!getBorderFragment(bd.b, bd.b_alpha, &imgB, color))
|
210 |
|
- |
|
211 |
if (imgB.empty())
|
- |
|
212 |
return false;
|
226 |
return false;
|
213 |
|
227 |
|
214 |
MSG_DEBUG("Got images " << bd.b << " and " << bda.b << " with size " << imgB.info().width() << " x " << imgB.info().height());
|
228 |
MSG_DEBUG("Got images " << bd.b << " and " << bd.b_alpha << " with size " << imgB.info().width() << " x " << imgB.info().height());
|
215 |
imgBR = retrieveBorderImage(bd.br, bda.br, color, bgColor);
|
229 |
if (!getBorderFragment(bd.br, bd.br_alpha, &imgBR, color))
|
216 |
|
- |
|
217 |
if (imgBR.empty())
|
- |
|
218 |
return false;
|
230 |
return false;
|
219 |
|
231 |
|
220 |
MSG_DEBUG("Got images " << bd.br << " and " << bda.br << " with size " << imgBR.info().width() << " x " << imgBR.info().height());
|
232 |
MSG_DEBUG("Got images " << bd.br << " and " << bd.br_alpha << " with size " << imgBR.info().width() << " x " << imgBR.info().height());
|
221 |
imgR = retrieveBorderImage(bd.r, bda.r, color, bgColor);
|
233 |
if (!getBorderFragment(bd.r, bd.r_alpha, &imgR, color))
|
222 |
|
- |
|
223 |
if (imgR.empty())
|
- |
|
224 |
return false;
|
234 |
return false;
|
225 |
|
235 |
|
226 |
MSG_DEBUG("Got images " << bd.r << " and " << bda.r << " with size " << imgR.info().width() << " x " << imgR.info().height());
|
236 |
MSG_DEBUG("Got images " << bd.r << " and " << bd.r_alpha << " with size " << imgR.info().width() << " x " << imgR.info().height());
|
227 |
imgTR = retrieveBorderImage(bd.tr, bda.tr, color, bgColor);
|
237 |
if (!getBorderFragment(bd.tr, bd.tr_alpha, &imgTR, color))
|
228 |
|
- |
|
229 |
if (imgTR.empty())
|
- |
|
230 |
return false;
|
238 |
return false;
|
231 |
|
239 |
|
232 |
MSG_DEBUG("Got images " << bd.tr << " and " << bda.tr << " with size " << imgTR.info().width() << " x " << imgTR.info().height());
|
240 |
MSG_DEBUG("Got images " << bd.tr << " and " << bd.tr_alpha << " with size " << imgTR.info().width() << " x " << imgTR.info().height());
|
233 |
imgT = retrieveBorderImage(bd.t, bda.t, color, bgColor);
|
241 |
if (getBorderFragment(bd.t, bd.t_alpha, &imgT, color))
|
234 |
|
- |
|
235 |
if (imgT.empty())
|
- |
|
236 |
return false;
|
242 |
return false;
|
237 |
|
243 |
|
238 |
MSG_DEBUG("Got images " << bd.t << " and " << bda.t << " with size " << imgT.info().width() << " x " << imgT.info().height());
|
244 |
MSG_DEBUG("Got images " << bd.t << " and " << bd.t_alpha << " with size " << imgT.info().width() << " x " << imgT.info().height());
|
239 |
imgTL = retrieveBorderImage(bd.tl, bda.tl, color, bgColor);
|
245 |
if (!getBorderFragment(bd.tl, bd.tl_alpha, &imgTL, color))
|
240 |
|
- |
|
241 |
if (imgTL.empty())
|
- |
|
242 |
return false;
|
246 |
return false;
|
243 |
|
247 |
|
244 |
MSG_DEBUG("Got images " << bd.tl << " and " << bda.tl << " with size " << imgTL.info().width() << " x " << imgTL.info().height());
|
248 |
MSG_DEBUG("Got images " << bd.tl << " and " << bd.tl_alpha << " with size " << imgTL.info().width() << " x " << imgTL.info().height());
|
245 |
imgL = retrieveBorderImage(bd.l, bda.l, color, bgColor);
|
249 |
if (!getBorderFragment(bd.l, bd.l_alpha, &imgL, color))
|
246 |
|
- |
|
247 |
if (imgL.empty())
|
- |
|
248 |
return false;
|
250 |
return false;
|
249 |
|
251 |
|
250 |
MSG_DEBUG("Got images " << bd.l << " and " << bda.l << " with size " << imgL.info().width() << " x " << imgL.info().height());
|
252 |
MSG_DEBUG("Got images " << bd.l << " and " << bd.l_alpha << " with size " << imgL.info().width() << " x " << imgL.info().height());
|
251 |
imgBL = retrieveBorderImage(bd.bl, bda.bl, color, bgColor);
|
253 |
if (!getBorderFragment(bd.bl, bd.bl_alpha, &imgBL, color))
|
252 |
|
- |
|
253 |
if (imgBL.empty())
|
- |
|
254 |
return false;
|
254 |
return false;
|
255 |
|
255 |
|
256 |
MSG_DEBUG("Got images " << bd.bl << " and " << bda.bl << " with size " << imgBL.info().width() << " x " << imgBL.info().height());
|
256 |
MSG_DEBUG("Got images " << bd.bl << " and " << bd.bl_alpha << " with size " << imgBL.info().width() << " x " << imgBL.info().height());
|
257 |
MSG_DEBUG("Button image size: " << (imgTL.info().width() + imgT.info().width() + imgTR.info().width()) << " x " << (imgTL.info().height() + imgL.info().height() + imgBL.info().height()));
|
257 |
MSG_DEBUG("Button image size: " << (imgTL.info().width() + imgT.info().width() + imgTR.info().width()) << " x " << (imgTL.info().height() + imgL.info().height() + imgBL.info().height()));
|
258 |
MSG_DEBUG("Total size: " << pinfo.width << " x " << pinfo.height);
|
258 |
MSG_DEBUG("Total size: " << pinfo.width << " x " << pinfo.height);
|
259 |
stretchImageWidth(&imgB, pinfo.width - imgBL.info().width() - imgBR.info().width());
|
259 |
stretchImageWidth(&imgB, pinfo.width - imgBL.info().width() - imgBR.info().width());
|
260 |
stretchImageWidth(&imgT, pinfo.width - imgTL.info().width() - imgTR.info().width());
|
260 |
stretchImageWidth(&imgT, pinfo.width - imgTL.info().width() - imgTR.info().width());
|
261 |
stretchImageHeight(&imgL, pinfo.height - imgTL.info().height() - imgBL.info().height());
|
261 |
stretchImageHeight(&imgL, pinfo.height - imgTL.info().height() - imgBL.info().height());
|
262 |
stretchImageHeight(&imgR, pinfo.height - imgTR.info().height() - imgBR.info().height());
|
262 |
stretchImageHeight(&imgR, pinfo.height - imgTR.info().height() - imgBR.info().height());
|
263 |
MSG_DEBUG("Stretched button image size: " << (imgTL.info().width() + imgT.info().width() + imgTR.info().width()) << " x " << (imgTL.info().height() + imgL.info().height() + imgBL.info().height()));
|
263 |
MSG_DEBUG("Stretched button image size: " << (imgTL.info().width() + imgT.info().width() + imgTR.info().width()) << " x " << (imgTL.info().height() + imgL.info().height() + imgBL.info().height()));
|
264 |
// Draw the frame
|
264 |
// Draw the frame
|
- |
|
265 |
SkBitmap frame;
|
- |
|
266 |
allocPixels(bm->info().width(), bm->info().height(), &frame);
|
- |
|
267 |
frame.eraseColor(SK_ColorTRANSPARENT);
|
- |
|
268 |
SkCanvas target(*bm, SkSurfaceProps());
|
- |
|
269 |
SkCanvas canvas(frame, SkSurfaceProps());
|
265 |
SkPaint paint;
|
270 |
SkPaint paint;
|
266 |
SkCanvas canvas(*bm, SkSurfaceProps());
|
- |
|
267 |
|
271 |
|
268 |
paint.setBlendMode(SkBlendMode::kSrc);
|
272 |
paint.setBlendMode(SkBlendMode::kSrcOver);
|
269 |
paint.setColor(color);
|
273 |
paint.setAntiAlias(true);
|
270 |
sk_sp<SkImage> _image = SkImages::RasterFromBitmap(imgB); // Bottom
|
274 |
sk_sp<SkImage> _image = SkImages::RasterFromBitmap(imgB); // bottom
|
271 |
canvas.drawImage(_image, imgBL.info().width(), pinfo.height - imgB.info().height(), SkSamplingOptions(), &paint);
|
275 |
canvas.drawImage(_image, imgBL.info().width(), pinfo.height - imgB.info().height(), SkSamplingOptions(), &paint);
|
- |
|
276 |
_image = SkImages::RasterFromBitmap(imgT); // top
|
- |
|
277 |
canvas.drawImage(_image, imgTL.info().width(), 0, SkSamplingOptions(), &paint);
|
272 |
_image = SkImages::RasterFromBitmap(imgBR); // Corner bottom right
|
278 |
_image = SkImages::RasterFromBitmap(imgBR); // bottom right
|
273 |
canvas.drawImage(_image, pinfo.width - imgBR.info().width(), pinfo.height - imgBR.info().height(), SkSamplingOptions(), &paint);
|
279 |
canvas.drawImage(_image, pinfo.width - imgBR.info().width(), pinfo.height - imgBR.info().height(), SkSamplingOptions(), &paint);
|
274 |
_image = SkImages::RasterFromBitmap(imgR); // Right
|
- |
|
275 |
canvas.drawImage(_image, pinfo.width - imgR.info().width(), imgTR.info().height(), SkSamplingOptions(), &paint);
|
- |
|
276 |
_image = SkImages::RasterFromBitmap(imgTR); // Corner top right
|
280 |
_image = SkImages::RasterFromBitmap(imgTR); // top right
|
277 |
canvas.drawImage(_image, pinfo.width - imgTR.info().width(), 0, SkSamplingOptions(), &paint);
|
281 |
canvas.drawImage(_image, pinfo.width - imgTR.info().width(), 0, SkSamplingOptions(), &paint);
|
278 |
_image = SkImages::RasterFromBitmap(imgT); // Top
|
- |
|
279 |
canvas.drawImage(_image, imgTL.info().width(), 0, SkSamplingOptions(), &paint);
|
- |
|
280 |
_image = SkImages::RasterFromBitmap(imgTL); // Corner top left
|
282 |
_image = SkImages::RasterFromBitmap(imgTL); // top left
|
281 |
canvas.drawImage(_image, 0, 0, SkSamplingOptions(), &paint);
|
283 |
canvas.drawImage(_image, 0, 0, SkSamplingOptions(), &paint);
|
282 |
_image = SkImages::RasterFromBitmap(imgL); // Left
|
- |
|
283 |
canvas.drawImage(_image, 0, imgTL.info().height(), SkSamplingOptions(), &paint);
|
- |
|
284 |
_image = SkImages::RasterFromBitmap(imgBL); // Corner bottom left
|
284 |
_image = SkImages::RasterFromBitmap(imgBL); // bottom left
|
285 |
canvas.drawImage(_image, 0, pinfo.height - imgBL.info().height(), SkSamplingOptions(), &paint);
|
285 |
canvas.drawImage(_image, 0, pinfo.height - imgBL.info().height(), SkSamplingOptions(), &paint);
|
- |
|
286 |
_image = SkImages::RasterFromBitmap(imgL); // left
|
- |
|
287 |
canvas.drawImage(_image, 0, imgTL.info().height(), SkSamplingOptions(), &paint);
|
- |
|
288 |
_image = SkImages::RasterFromBitmap(imgR); // right
|
- |
|
289 |
canvas.drawImage(_image, pinfo.width - imgR.info().width(), imgTR.info().height(), SkSamplingOptions(), &paint);
|
- |
|
290 |
|
- |
|
291 |
Border::TIntBorder iborder;
|
- |
|
292 |
iborder.erasePart(bm, frame, Border::ERASE_OUTSIDE, imgL.info().width());
|
- |
|
293 |
_image = SkImages::RasterFromBitmap(frame);
|
- |
|
294 |
paint.setBlendMode(SkBlendMode::kSrcATop);
|
- |
|
295 |
target.drawImage(_image, 0, 0, SkSamplingOptions(), &paint);
|
286 |
return true;
|
296 |
return true;
|
287 |
}
|
297 |
}
|
288 |
|
298 |
|
289 |
Button::POSITION_t TPageInterface::calcImagePosition(PAGE_T *page, int width, int height, Button::CENTER_CODE cc, int line)
|
299 |
Button::POSITION_t TPageInterface::calcImagePosition(PAGE_T *page, int width, int height, Button::CENTER_CODE cc, int line)
|
290 |
{
|
300 |
{
|
Line 1124... |
Line 1134... |
1124 |
}
|
1134 |
}
|
1125 |
|
1135 |
|
1126 |
return string();
|
1136 |
return string();
|
1127 |
}
|
1137 |
}
|
1128 |
|
1138 |
|
- |
|
1139 |
/**
|
- |
|
1140 |
* @brief getBorderFragment - get part of border
|
- |
|
1141 |
* The method reads a border image fragment from the disk and converts it to
|
- |
|
1142 |
* the border color. If there is a base image and an alpha mask image, the
|
- |
|
1143 |
* pixels of the alpha mask are converted to the border color and then the base
|
- |
|
1144 |
* image is layed over the mask image.
|
- |
|
1145 |
* In case there is no base image, an image with the same size as the mask image
|
- |
|
1146 |
* is created and filled transparaent.
|
- |
|
1147 |
*
|
- |
|
1148 |
* @param path The path and file name of the base image.
|
- |
|
1149 |
* @param pathAlpha The path and file name of the alpha mask image.
|
- |
|
1150 |
* @param image A pointer to an empty bitmap.
|
- |
|
1151 |
* @param color The border color
|
- |
|
1152 |
*
|
- |
|
1153 |
* @return In case the images exists and were loaded successfully, TRUE is
|
- |
|
1154 |
* returned.
|
- |
|
1155 |
*/
|
- |
|
1156 |
bool TPageInterface::getBorderFragment(const string& path, const string& pathAlpha, SkBitmap* image, SkColor color)
|
- |
|
1157 |
{
|
- |
|
1158 |
DECL_TRACER("TPageInterface::getBorderFragment(const string& path, const string& pathAlpha, SkBitmap* image, SkColor color)");
|
- |
|
1159 |
|
- |
|
1160 |
if (!image)
|
- |
|
1161 |
{
|
- |
|
1162 |
MSG_ERROR("Invalid pointer to image!");
|
- |
|
1163 |
return false;
|
- |
|
1164 |
}
|
- |
|
1165 |
|
- |
|
1166 |
sk_sp<SkData> im;
|
- |
|
1167 |
SkBitmap bm;
|
- |
|
1168 |
bool haveBaseImage = false;
|
- |
|
1169 |
|
- |
|
1170 |
// If the path ends with "alpha.png" then it is a mask image. This not what
|
- |
|
1171 |
// we want first unless this is the only image available.
|
- |
|
1172 |
if (!endsWith(path, "alpha.png") || pathAlpha.empty())
|
- |
|
1173 |
{
|
- |
|
1174 |
if (retrieveImage(path, image))
|
- |
|
1175 |
{
|
- |
|
1176 |
haveBaseImage = true;
|
- |
|
1177 |
// Underly the pixels with the border color
|
- |
|
1178 |
MSG_DEBUG("Path: " << path << ", pathAlpha: " << pathAlpha);
|
- |
|
1179 |
if (pathAlpha.empty() || !fs::exists(pathAlpha) || path == pathAlpha)
|
- |
|
1180 |
{
|
- |
|
1181 |
SkImageInfo info = image->info();
|
- |
|
1182 |
SkBitmap b;
|
- |
|
1183 |
allocPixels(info.width(), info.height(), &b);
|
- |
|
1184 |
b.eraseColor(SK_ColorTRANSPARENT);
|
- |
|
1185 |
|
- |
|
1186 |
for (int x = 0; x < info.width(); ++x)
|
- |
|
1187 |
{
|
- |
|
1188 |
for (int y = 0; y < info.height(); ++y)
|
- |
|
1189 |
{
|
- |
|
1190 |
SkColor alpha = SkColorGetA(image->getColor(x, y));
|
- |
|
1191 |
uint32_t *pix = b.getAddr32(x, y);
|
- |
|
1192 |
|
- |
|
1193 |
if (alpha > 0)
|
- |
|
1194 |
*pix = color;
|
- |
|
1195 |
}
|
- |
|
1196 |
}
|
- |
|
1197 |
|
- |
|
1198 |
SkPaint paint;
|
- |
|
1199 |
paint.setAntiAlias(true);
|
- |
|
1200 |
paint.setBlendMode(SkBlendMode::kDstATop);
|
- |
|
1201 |
SkCanvas can(*image);
|
- |
|
1202 |
sk_sp<SkImage> _image = SkImages::RasterFromBitmap(b);
|
- |
|
1203 |
can.drawImage(_image, 0, 0, SkSamplingOptions(), &paint);
|
- |
|
1204 |
}
|
- |
|
1205 |
}
|
- |
|
1206 |
}
|
- |
|
1207 |
|
- |
|
1208 |
// If there is no valid path return.
|
- |
|
1209 |
if (pathAlpha.empty())
|
- |
|
1210 |
return haveBaseImage;
|
- |
|
1211 |
|
- |
|
1212 |
// On error retrieving the image, return.
|
- |
|
1213 |
if (!retrieveImage(pathAlpha, &bm))
|
- |
|
1214 |
return haveBaseImage;
|
- |
|
1215 |
|
- |
|
1216 |
// If there was no base image loaded, allocate the space for an image
|
- |
|
1217 |
// filled transparent. Make it the same size as the mask image.
|
- |
|
1218 |
if (!haveBaseImage)
|
- |
|
1219 |
{
|
- |
|
1220 |
allocPixels(bm.info().width(), bm.info().height(), image);
|
- |
|
1221 |
image->eraseColor(SK_ColorTRANSPARENT);
|
- |
|
1222 |
}
|
- |
|
1223 |
|
- |
|
1224 |
// Only if the base image and the mask image have the same size, which
|
- |
|
1225 |
// should be the case, then the visible pixels of the mask image are
|
- |
|
1226 |
// colored by the border color.
|
- |
|
1227 |
if (image->info().dimensions() == bm.info().dimensions())
|
- |
|
1228 |
{
|
- |
|
1229 |
for (int y = 0; y < image->info().height(); ++y)
|
- |
|
1230 |
{
|
- |
|
1231 |
for (int x = 0; x < image->info().width(); ++x)
|
- |
|
1232 |
{
|
- |
|
1233 |
SkColor col = bm.getColor(x, y);
|
- |
|
1234 |
SkColor alpha = SkColorGetA(col);
|
- |
|
1235 |
uint32_t *pix = bm.getAddr32(x, y);
|
- |
|
1236 |
|
- |
|
1237 |
if (alpha == 0)
|
- |
|
1238 |
*pix = SK_ColorTRANSPARENT;
|
- |
|
1239 |
else
|
- |
|
1240 |
*pix = SkColorSetA(color, alpha);
|
- |
|
1241 |
}
|
- |
|
1242 |
}
|
- |
|
1243 |
}
|
- |
|
1244 |
|
- |
|
1245 |
// Here we draw the border fragment over the base image.
|
- |
|
1246 |
SkPaint paint;
|
- |
|
1247 |
paint.setAntiAlias(true);
|
- |
|
1248 |
paint.setBlendMode(SkBlendMode::kDstATop);
|
- |
|
1249 |
SkCanvas can(*image);
|
- |
|
1250 |
sk_sp<SkImage> _image = SkImages::RasterFromBitmap(bm);
|
- |
|
1251 |
can.drawImage(_image, 0, 0, SkSamplingOptions(), &paint);
|
- |
|
1252 |
|
- |
|
1253 |
return true;
|
- |
|
1254 |
}
|
- |
|
1255 |
|
1129 |
SkBitmap TPageInterface::retrieveBorderImage(const string& pa, const string& pb, SkColor color, SkColor bgColor)
|
1256 |
SkBitmap TPageInterface::retrieveBorderImage(const string& pa, const string& pb, SkColor color, SkColor bgColor)
|
1130 |
{
|
1257 |
{
|
1131 |
DECL_TRACER("TPageInterface::retrieveBorderImage(const string& pa, const string& pb, SkColor color, SkColor bgColor)");
|
1258 |
DECL_TRACER("TPageInterface::retrieveBorderImage(const string& pa, const string& pb, SkColor color, SkColor bgColor)");
|
1132 |
|
1259 |
|
1133 |
SkBitmap bm, bma;
|
1260 |
SkBitmap bm, bma;
|