summaryrefslogtreecommitdiff
path: root/softhddevice.cpp
diff options
context:
space:
mode:
authorJohns <johns98@gmx.net>2015-06-30 10:12:09 +0200
committerJohns <johns98@gmx.net>2015-06-30 10:12:09 +0200
commitec58e456072d962a18cb50f4324d266ba4a2aae8 (patch)
tree1dab1b0faa267b7b73de336f5a5876a2632608ec /softhddevice.cpp
parent396d5fac055aae8afeb4626d2b56e4bf989f8fd6 (diff)
downloadvdr-plugin-softhddevice-ec58e456072d962a18cb50f4324d266ba4a2aae8.tar.gz
vdr-plugin-softhddevice-ec58e456072d962a18cb50f4324d266ba4a2aae8.tar.bz2
Fix bug: wrong and crash, if vdr draws pixmaps outside OSD.
Diffstat (limited to 'softhddevice.cpp')
-rw-r--r--softhddevice.cpp119
1 files changed, 103 insertions, 16 deletions
diff --git a/softhddevice.cpp b/softhddevice.cpp
index e933955..7310a1f 100644
--- a/softhddevice.cpp
+++ b/softhddevice.cpp
@@ -1,7 +1,7 @@
///
/// @file softhddevice.cpp @brief A software HD device plugin for VDR.
///
-/// Copyright (c) 2011 - 2013 by Johns. All Rights Reserved.
+/// Copyright (c) 2011 - 2015 by Johns. All Rights Reserved.
///
/// Contributor(s):
///
@@ -431,6 +431,8 @@ void cSoftOsd::Flush(void)
// draw all bitmaps
for (i = 0; (bitmap = GetBitmap(i)); ++i) {
uint8_t *argb;
+ int xs;
+ int ys;
int x;
int y;
int w;
@@ -449,22 +451,52 @@ void cSoftOsd::Flush(void)
} else if (!bitmap->Dirty(x1, y1, x2, y2)) {
continue; // nothing dirty continue
}
- // convert and upload only dirty areas
+ // convert and upload only visible dirty areas
+ xs = bitmap->X0() + Left();
+ ys = bitmap->Y0() + Top();
+ // FIXME: negtative position bitmaps
w = x2 - x1 + 1;
h = y2 - y1 + 1;
+ // clip to screen
if (1) { // just for the case it makes trouble
int width;
int height;
double video_aspect;
+ if (xs < 0) {
+ if (xs + x1 < 0) {
+ x1 -= xs + x1;
+ w += xs + x1;
+ if (w <= 0) {
+ continue;
+ }
+ }
+ xs = 0;
+ }
+ if (ys < 0) {
+ if (ys + y1 < 0) {
+ y1 -= ys + y1;
+ h += ys + y1;
+ if (h <= 0) {
+ continue;
+ }
+ }
+ ys = 0;
+ }
::GetOsdSize(&width, &height, &video_aspect);
- if (w > width) {
- w = width;
- x2 = x1 + width - 1;
+ if (w > width - xs - x1) {
+ w = width - xs - x1;
+ if (w <= 0) {
+ continue;
+ }
+ x2 = x1 + w - 1;
}
- if (h > height) {
- h = height;
- y2 = y1 + height - 1;
+ if (h > height - ys - y1) {
+ h = height - ys - y1;
+ if (h <= 0) {
+ continue;
+ }
+ y2 = y1 + h - 1;
}
}
#ifdef DEBUG
@@ -482,10 +514,10 @@ void cSoftOsd::Flush(void)
}
#ifdef OSD_DEBUG
dsyslog("[softhddev]%s: draw %dx%d%+d%+d bm\n", __FUNCTION__, w, h,
- Left() + bitmap->X0() + x1, Top() + bitmap->Y0() + y1);
+ xs + x1, ys + y1);
#endif
- OsdDrawARGB(Left() + bitmap->X0() + x1, Top() + bitmap->Y0() + y1,
- w, h, argb);
+ OsdDrawARGB(0, 0, w, h, w * sizeof(uint32_t), argb, xs + x1,
+ ys + y1);
bitmap->Clean();
// FIXME: reuse argb
@@ -497,21 +529,76 @@ void cSoftOsd::Flush(void)
LOCK_PIXMAPS;
while ((pm = (dynamic_cast < cPixmapMemory * >(RenderPixmaps())))) {
+ int xp;
+ int yp;
+ int stride;
int x;
int y;
int w;
int h;
- x = Left() + pm->ViewPort().X();
- y = Top() + pm->ViewPort().Y();
+ x = pm->ViewPort().X();
+ y = pm->ViewPort().Y();
w = pm->ViewPort().Width();
h = pm->ViewPort().Height();
+ stride = w * sizeof(tColor);
+
+ // clip to osd
+ xp = 0;
+ if (x < 0) {
+ xp = -x;
+ w -= xp;
+ x = 0;
+ }
+
+ yp = 0;
+ if (y < 0) {
+ yp = -y;
+ h -= yp;
+ y = 0;
+ }
+
+ if (w > Width() - x) {
+ w = Width() - x;
+ }
+ if (h > Height() - y) {
+ h = Height() - y;
+ }
+ x += Left();
+ y += Top();
+
+ // clip to screen
+ if (1) { // just for the case it makes trouble
+ // and it can happen!
+ int width;
+ int height;
+ double video_aspect;
+
+ if (x < 0) {
+ w += x;
+ xp += -x;
+ x = 0;
+ }
+ if (y < 0) {
+ h += y;
+ yp += -y;
+ y = 0;
+ }
+
+ ::GetOsdSize(&width, &height, &video_aspect);
+ if (w > width - x) {
+ w = width - x;
+ }
+ if (h > height - y) {
+ h = height - y;
+ }
+ }
#ifdef OSD_DEBUG
- dsyslog("[softhddev]%s: draw %dx%d%+d%+d %p\n", __FUNCTION__, w, h, x,
- y, pm->Data());
+ dsyslog("[softhddev]%s: draw %dx%d%+d%+d*%d -> %+d%+d %p\n",
+ __FUNCTION__, w, h, xp, yp, stride, x, y, pm->Data());
#endif
- OsdDrawARGB(x, y, w, h, pm->Data());
+ OsdDrawARGB(xp, yp, w, h, stride, pm->Data(), x, y);
#if APIVERSNUM >= 20110
DestroyPixmap(pm);