Skip to content

Commit

Permalink
filter: add x11 text rendering
Browse files Browse the repository at this point in the history
limit: no opacity support
  • Loading branch information
wang-bin committed Dec 1, 2015
1 parent 2d280d2 commit f4cf8d4
Show file tree
Hide file tree
Showing 4 changed files with 327 additions and 23 deletions.
70 changes: 57 additions & 13 deletions src/QtAV/FilterContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ class Q_AV_EXPORT VideoFilterContext
OpenGL, //Not implemented
Direct2D, //Not implemeted
GdiPlus, //Not implemented
XV, //Not implemented
X11,
None //user defined filters, no context can be used
};
static VideoFilterContext* create(Type t);
Expand All @@ -54,9 +54,9 @@ class Q_AV_EXPORT VideoFilterContext

// map to Qt types
//drawSurface?
virtual void drawImage(const QPointF& pos, const QImage& image, const QRectF& source, Qt::ImageConversionFlags flags = Qt::AutoColor);
virtual void drawImage(const QPointF& pos, const QImage& image, const QRectF& source = QRectF(), Qt::ImageConversionFlags flags = Qt::AutoColor);
// if target is null, draw image at target.topLeft(). if source is null, draw the whole image
virtual void drawImage(const QRectF& target, const QImage& image, const QRectF& source, Qt::ImageConversionFlags flags = Qt::AutoColor);
virtual void drawImage(const QRectF& target, const QImage& image, const QRectF& source = QRectF(), Qt::ImageConversionFlags flags = Qt::AutoColor);
virtual void drawPlainText(const QPointF& pos, const QString& text);
// if rect is null, draw single line text at rect.topLeft(), ignoring flags
virtual void drawPlainText(const QRectF& rect, int flags, const QString& text);
Expand Down Expand Up @@ -97,29 +97,73 @@ class Q_AV_EXPORT VideoFilterContext

class VideoFrameConverter;
//TODO: font, pen, brush etc?
class Q_AV_EXPORT QPainterFilterContext : public VideoFilterContext
class Q_AV_EXPORT QPainterFilterContext Q_DECL_FINAL: public VideoFilterContext
{
public:
QPainterFilterContext();
virtual ~QPainterFilterContext();
virtual Type type() const; //QtPainter
Type type() const Q_DECL_OVERRIDE { return VideoFilterContext::QtPainter;}
// empty source rect equals to the whole source rect
virtual void drawImage(const QPointF& pos, const QImage& image, const QRectF& source = QRectF(), Qt::ImageConversionFlags flags = Qt::AutoColor);
virtual void drawImage(const QRectF& target, const QImage& image, const QRectF& source = QRectF(), Qt::ImageConversionFlags flags = Qt::AutoColor);
virtual void drawPlainText(const QPointF& pos, const QString& text);
void drawImage(const QPointF& pos, const QImage& image, const QRectF& source = QRectF(), Qt::ImageConversionFlags flags = Qt::AutoColor) Q_DECL_OVERRIDE;
void drawImage(const QRectF& target, const QImage& image, const QRectF& source = QRectF(), Qt::ImageConversionFlags flags = Qt::AutoColor) Q_DECL_OVERRIDE;
void drawPlainText(const QPointF& pos, const QString& text) Q_DECL_OVERRIDE;
// if rect is null, draw single line text at rect.topLeft(), ignoring flags
virtual void drawPlainText(const QRectF& rect, int flags, const QString& text);
virtual void drawRichText(const QRectF& rect, const QString& text, bool wordWrap = true);
void drawPlainText(const QRectF& rect, int flags, const QString& text) Q_DECL_OVERRIDE;
void drawRichText(const QRectF& rect, const QString& text, bool wordWrap = true) Q_DECL_OVERRIDE;

protected:
virtual bool isReady() const;
virtual bool prepare();
virtual void initializeOnFrame(VideoFrame *vframe);
bool isReady() const Q_DECL_OVERRIDE;
bool prepare() Q_DECL_OVERRIDE;
void initializeOnFrame(VideoFrame *vframe) Q_DECL_OVERRIDE;

QTextDocument *doc;
VideoFrameConverter *cvt;
};

class Q_AV_EXPORT X11FilterContext Q_DECL_FINAL: public VideoFilterContext
{
public:
typedef struct _XDisplay Display;
typedef struct _XGC *GC;
typedef quintptr Drawable;
typedef quintptr Pixmap;
struct XImage;

X11FilterContext();
virtual ~X11FilterContext();
Type type() const Q_DECL_OVERRIDE { return VideoFilterContext::X11;}
void resetX11(Display* dpy = 0, GC g = 0, Drawable d = 0);
// empty source rect equals to the whole source rect
void drawImage(const QPointF& pos, const QImage& image, const QRectF& source = QRectF(), Qt::ImageConversionFlags flags = Qt::AutoColor) Q_DECL_OVERRIDE;
void drawImage(const QRectF& target, const QImage& image, const QRectF& source = QRectF(), Qt::ImageConversionFlags flags = Qt::AutoColor) Q_DECL_OVERRIDE;
void drawPlainText(const QPointF& pos, const QString& text) Q_DECL_OVERRIDE;
// if rect is null, draw single line text at rect.topLeft(), ignoring flags
void drawPlainText(const QRectF& rect, int flags, const QString& text) Q_DECL_OVERRIDE;
void drawRichText(const QRectF& rect, const QString& text, bool wordWrap = true) Q_DECL_OVERRIDE;
protected:
bool isReady() const Q_DECL_OVERRIDE;
bool prepare() Q_DECL_OVERRIDE;
void initializeOnFrame(VideoFrame *vframe) Q_DECL_OVERRIDE;
void shareFrom(VideoFilterContext *vctx) Q_DECL_OVERRIDE;
// null image: use the old x11 image/pixmap
void renderTextImageX11(QImage* img, const QPointF &pos);
void destroyX11Resources();

QTextDocument *doc;
VideoFrameConverter *cvt;

Display* display;
GC gc;
Drawable drawable;
XImage *text_img;
XImage *mask_img;
Pixmap mask_pix;

bool plain;
QString text;
QImage test_img; //for computing bounding rect
};

} //namespace QtAV

#endif // QTAV_FILTERCONTEXT_H
18 changes: 8 additions & 10 deletions src/filter/FilterContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
******************************************************************************/

#include "QtAV/FilterContext.h"
#include <QtGui/QFontMetrics>
#include <QtGui/QImage>
#include <QtGui/QPainter>
#include <QtGui/QTextDocument>
Expand All @@ -35,6 +36,8 @@ VideoFilterContext *VideoFilterContext::create(Type t)
case QtPainter:
ctx = new QPainterFilterContext();
break;
case X11:
ctx = new X11FilterContext();
default:
break;
}
Expand All @@ -58,7 +61,7 @@ VideoFilterContext::VideoFilterContext():
font.setBold(true);
font.setPixelSize(26);
pen.setColor(Qt::white);
rect = QRect(32, 32, 0, 0); //TODO: why painting will above the visible area if the draw at (0, 0)?
rect = QRect(32, 32, 0, 0); //TODO: why painting will above the visible area if the draw at (0, 0)? ascent
}

VideoFilterContext::~VideoFilterContext()
Expand Down Expand Up @@ -132,8 +135,8 @@ void VideoFilterContext::shareFrom(VideoFilterContext *vctx)
video_height = vctx->video_height;
}

QPainterFilterContext::QPainterFilterContext()
: doc(0)
QPainterFilterContext::QPainterFilterContext() : VideoFilterContext()
, doc(0)
, cvt(0)
{}

Expand All @@ -149,11 +152,6 @@ QPainterFilterContext::~QPainterFilterContext()
}
}

VideoFilterContext::Type QPainterFilterContext::type() const
{
return VideoFilterContext::QtPainter;
}

void QPainterFilterContext::drawImage(const QPointF &pos, const QImage &image, const QRectF& source, Qt::ImageConversionFlags flags)
{
if (!prepare())
Expand All @@ -180,7 +178,8 @@ void QPainterFilterContext::drawPlainText(const QPointF &pos, const QString &tex
{
if (!prepare())
return;
painter->drawText(pos, text);
QFontMetrics fm(font);
painter->drawText(pos + QPoint(0, fm.ascent()), text);
painter->restore();
}

Expand Down Expand Up @@ -279,5 +278,4 @@ void QPainterFilterContext::initializeOnFrame(VideoFrame *vframe)
own_paint_device = true; //TODO: what about renderer is not a widget?
painter->begin((QImage*)paint_device);
}

} //namespace QtAV
Loading

0 comments on commit f4cf8d4

Please sign in to comment.