1
0
mirror of https://github.com/VDR4Arch/vdr.git synced 2023-10-10 13:36:52 +02:00

Implemented anti-aliasing for cPixmap::DrawSlope()

This commit is contained in:
Klaus Schmidinger 2020-09-29 14:09:26 +02:00
parent eebe7c798a
commit bbd36d0610
5 changed files with 104 additions and 23 deletions

View File

@ -2441,6 +2441,7 @@ Christoph Haubrich <christoph1.haubrich@arcor.de>
for suggesting to add a confirmation before renaming a recording to its folder name
for reporting a problem with data loss in case renaming a recording fails
for adding support for HEVC-video and AC-4-audio
for implementing anti-aliasing for cPixmap::DrawSlope()
Pekka Mauno <pekka.mauno@iki.fi>
for fixing cSchedule::GetFollowingEvent() in case there is currently no present

View File

@ -9513,7 +9513,7 @@ Video Disk Recorder Revision History
with the main menu open.
- Official release.
2020-09-16:
2020-09-29: Version 2.4.5
- Updated the Italian OSD texts (thanks to Diego Pierotto).
- Fixed handling newline characters in ci.c's CopyString() (reported by Winfried Köhler).
@ -9521,3 +9521,6 @@ Video Disk Recorder Revision History
by Winfried Köhler).
- Fixed a possible invalid lock sequence in cMenuTimers::OnOff().
- Fixed several typos (reported by Jens Schleusener).
- Implemented anti-aliasing for cPixmap::DrawSlope() (thanks to Christoph Haubrich).
The version numbers (both VDRVERSNUM and APIVERSNUM) have been bumped to 2.4.5 to
indicate this change.

View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
* $Id: config.h 4.19 2020/07/15 15:13:08 kls Exp $
* $Id: config.h 4.20 2020/09/29 14:09:26 kls Exp $
*/
#ifndef __CONFIG_H
@ -22,13 +22,13 @@
// VDR's own version number:
#define VDRVERSION "2.4.4"
#define VDRVERSNUM 20404 // Version * 10000 + Major * 100 + Minor
#define VDRVERSION "2.4.5"
#define VDRVERSNUM 20405 // Version * 10000 + Major * 100 + Minor
// The plugin API's version number:
#define APIVERSION "2.4.3"
#define APIVERSNUM 20403 // Version * 10000 + Major * 100 + Minor
#define APIVERSION "2.4.5"
#define APIVERSNUM 20405 // Version * 10000 + Major * 100 + Minor
// When loading plugins, VDR searches them by their APIVERSION, which
// may be smaller than VDRVERSION in case there have been no changes to

104
osd.c
View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
* $Id: osd.c 4.6 2019/05/24 21:28:35 kls Exp $
* $Id: osd.c 4.7 2020/09/29 14:09:26 kls Exp $
*/
#include "osd.h"
@ -1273,6 +1273,20 @@ void cPixmapMemory::DrawPixel(const cPoint &Point, tColor Color)
Unlock();
}
void cPixmapMemory::DrawBlendedPixel(const cPoint &Point, tColor Color, uint8_t Alpha)
{
Lock();
if (DrawPort().Size().Contains(Point)) {
int p = Point.Y() * DrawPort().Width() + Point.X();
if (Alpha != ALPHA_OPAQUE)
data[p] = AlphaBlend(Color, data[p], Alpha);
else
data[p] = Color;
MarkDrawPortDirty(Point);
}
Unlock();
}
void cPixmapMemory::DrawBitmap(const cPoint &Point, const cBitmap &Bitmap, tColor ColorFg, tColor ColorBg, bool Overlay)
{
Lock();
@ -1480,7 +1494,6 @@ void cPixmapMemory::DrawEllipse(const cRect &Rect, tColor Color, int Quadrants)
void cPixmapMemory::DrawSlope(const cRect &Rect, tColor Color, int Type)
{
//TODO anti-aliasing?
//TODO also simplify cBitmap::DrawSlope()
Lock();
bool upper = Type & 0x01;
@ -1492,28 +1505,87 @@ void cPixmapMemory::DrawSlope(const cRect &Rect, tColor Color, int Type)
int y2 = Rect.Bottom();
int w = Rect.Width();
int h = Rect.Height();
bool AntiAliased = Setup.AntiAlias;
uint8_t intensity = 0;
if (vertical) {
for (int y = y1; y <= y2; y++) {
double c = cos((y - y1) * M_PI / h);
if (upper)
DrawRectangle(cRect(x1, y1, w, 1), Color);
else
DrawRectangle(cRect(x1, y2, w, 1), Color);
for (int y = 1; y <= (y2 - y1) / 2; y++) {
double c = cos(y * M_PI / (y2 - y1));
if (AntiAliased) {
double wc = (w * c + (w & 1)) / 2;
intensity = 255 * fabs(wc - floor(wc));
}
if (falling)
c = -c;
int x = (x1 + x2) / 2 + int(w * c / 2);
if (upper && !falling || !upper && falling)
DrawRectangle(cRect(x1, y, x - x1 + 1, 1), Color);
else
DrawRectangle(cRect(x, y, x2 - x + 1, 1), Color);
int x = (x1 + x2 + w * c + 1) / 2;
if (upper && !falling || !upper && falling) {
if (AntiAliased) {
DrawRectangle(cRect(x1, y1 + y, x - x1, 1), Color);
DrawBlendedPixel(cPoint(x, y1 + y), Color, upper ? intensity : 255 - intensity);
DrawRectangle(cRect(x1, y2 - y, x2 - x, 1), Color);
DrawBlendedPixel(cPoint(x1 + x2 - x, y2 - y), Color, upper ? 255 - intensity : intensity);
}
else {
DrawRectangle(cRect(x1, y1 + y, x - x1 + 1, 1), Color);
DrawRectangle(cRect(x1, y2 - y, x2 - x + 1, 1), Color);
}
}
else {
for (int x = x1; x <= x2; x++) {
double c = cos((x - x1) * M_PI / w);
if (AntiAliased) {
DrawRectangle(cRect(x + 1, y1 + y, x2 - x, 1), Color);
DrawBlendedPixel(cPoint(x, y1 + y), Color, falling ? intensity : 255 - intensity);
DrawRectangle(cRect(x1 + x2 - x + 1, y2 - y, x - x1, 1), Color);
DrawBlendedPixel(cPoint(x1 + x2 - x, y2 - y), Color, falling ? 255 - intensity : intensity);
}
else {
DrawRectangle(cRect(x, y1 + y, x2 - x + 1, 1), Color);
DrawRectangle(cRect(x1 + x2 - x, y2 - y, x - x1 + 1, 1), Color);
}
}
}
}
else {
if ((upper && !falling) || (!upper && falling))
DrawRectangle(cRect(x1, y1, 1, h), Color);
else
DrawRectangle(cRect(x2, y1, 1, h), Color);
for (int x = 1; x <= (x2 - x1) / 2; x++) {
double c = cos(x * M_PI / (x2 - x1));
if (AntiAliased) {
double hc = (h * c + (h & 1)) / 2;
intensity = 255 * fabs(hc - floor(hc));
}
if (falling)
c = -c;
int y = (y1 + y2) / 2 + int(h * c / 2);
if (upper)
DrawRectangle(cRect(x, y1, 1, y - y1 + 1), Color);
else
DrawRectangle(cRect(x, y, 1, y2 - y + 1), Color);
int y = (y1 + y2 + h * c + 1) / 2;
if (upper) {
if (AntiAliased) {
DrawRectangle(cRect(x1 + x, y1, 1, y - y1), Color);
DrawBlendedPixel(cPoint(x1 + x, y), Color, falling ? 255 - intensity : intensity);
DrawRectangle(cRect(x2 - x, y1, 1, y2 - y), Color);
DrawBlendedPixel(cPoint(x2 - x, y1 + y2 - y), Color, falling ? intensity : 255 - intensity);
}
else {
DrawRectangle(cRect(x1 + x, y1, 1, y - y1 + 1), Color);
DrawRectangle(cRect(x2 - x, y1, 1, y2 - y + 1), Color);
}
}
else {
if (AntiAliased) {
DrawRectangle(cRect(x1 + x, y + 1, 1, y2 - y), Color);
DrawBlendedPixel(cPoint(x1 + x, y), Color, falling ? intensity : 255 - intensity);
DrawRectangle(cRect(x2 - x, y1 + y2 - y + 1, 1, y - y1), Color);
DrawBlendedPixel(cPoint(x2 - x, y1 + y2 - y), Color, falling ? 255 - intensity : intensity);
}
else {
DrawRectangle(cRect(x1 + x, y, 1, y2 - y + 1), Color);
DrawRectangle(cRect(x2 - x, y1 + y2 - y, 1, y - y1 + 1), Color);
}
}
}
}
MarkDrawPortDirty(Rect);

7
osd.h
View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
* $Id: osd.h 4.6 2019/05/24 21:28:35 kls Exp $
* $Id: osd.h 4.7 2020/09/29 14:09:26 kls Exp $
*/
#ifndef __OSD_H
@ -607,6 +607,10 @@ public:
///< a full 32 bit ARGB value. If the alpha value of Color is not 0xFF
///< (fully opaque), and this is the background pixmap (layer 0), the pixel is
///< alpha blended with the existing color at the given position in this pixmap.
virtual void DrawBlendedPixel(const cPoint &Point, tColor Color, uint8_t AlphaLayer = ALPHA_OPAQUE) { DrawPixel(Point, Color); }
///< Like DrawPixel(), but with an additional AlphaLayer, and works on any
///< pixmap, not only the background. The default implementation just calls
///< DrawPixel(), ignoring AlphaLayer.
virtual void DrawBitmap(const cPoint &Point, const cBitmap &Bitmap, tColor ColorFg = 0, tColor ColorBg = 0, bool Overlay = false) = 0;
///< Sets the pixels in the OSD with the data from the given
///< Bitmap, putting the upper left corner of the Bitmap at Point.
@ -697,6 +701,7 @@ public:
virtual void DrawImage(const cPoint &Point, const cImage &Image);
virtual void DrawImage(const cPoint &Point, int ImageHandle);
virtual void DrawPixel(const cPoint &Point, tColor Color);
virtual void DrawBlendedPixel(const cPoint &Point, tColor Color, uint8_t AlphaLayer = ALPHA_OPAQUE);
virtual void DrawBitmap(const cPoint &Point, const cBitmap &Bitmap, tColor ColorFg = 0, tColor ColorBg = 0, bool Overlay = false);
virtual void DrawText(const cPoint &Point, const char *s, tColor ColorFg, tColor ColorBg, const cFont *Font, int Width = 0, int Height = 0, int Alignment = taDefault);
virtual void DrawRectangle(const cRect &Rect, tColor Color);