12#include <QtGui/private/qwindowsfontdatabase_p.h>
15#include <QtCore/qmath.h>
16#include <QtCore/qstack.h>
17#include <QtCore/qsettings.h>
18#include <QtGui/private/qpaintengine_p.h>
19#include <QtGui/private/qtextengine_p.h>
20#include <QtGui/private/qfontengine_p.h>
21#include <QtGui/private/qstatictext_p.h>
67#define D2D_TAG(tag) d->dc()->SetTags(tag, tag)
78 const qreal halfWidth = penWidth / 2;
83 line.p1().y() + dashOffset * sinA - cosA * halfWidth);
93 QList<D2D1_GRADIENT_STOP> stops(qstops.count());
95 stops[
i].position = FLOAT(qstops.at(
i).first);
108 qWarning(
"%s: Could not create path geometry: %#lx", __FUNCTION__, hr);
112 hr = m_geometry->Open(&m_sink);
114 qWarning(
"%s: Could not create geometry sink: %#lx", __FUNCTION__, hr);
124 m_sink->SetFillMode(D2D1_FILL_MODE_WINDING);
126 m_sink->SetFillMode(D2D1_FILL_MODE_ALTERNATE);
131 m_roundCoordinates =
enable;
136 m_adjustPositivelySlopedLines =
enable;
147 m_sink->EndFigure(D2D1_FIGURE_END_OPEN);
149 m_sink->BeginFigure(adjusted(point), D2D1_FIGURE_BEGIN_FILLED);
151 m_previousPoint = point;
161 m_sink->AddLine(adjusted(pt));
164 m_previousPoint = point;
169 D2D1_BEZIER_SEGMENT
segment = {
176 m_previousPoint = p3;
182 m_sink->EndFigure(D2D1_FIGURE_END_OPEN);
193 D2D1_POINT_2F adjusted(
const QPointF &point)
198 if (m_roundCoordinates)
204 ComPtr<ID2D1PathGeometry1> m_geometry;
205 ComPtr<ID2D1GeometrySink> m_sink;
207 bool m_inFigure =
false;
208 bool m_roundCoordinates =
false;
209 bool m_adjustPositivelySlopedLines =
false;
235 dc()->SetAntialiasMode(D2D1_ANTIALIAS_MODE_ALIASED);
257 inline void reset() {
270 ComPtr<ID2D1Brush>
brush;
272 inline void reset() {
279 inline ID2D1DeviceContext *
dc()
const
282 return bitmap->deviceContext()->get();
289 : D2D1_INTERPOLATION_MODE_NEAREST_NEIGHBOR;
296 : D2D1_ANTIALIAS_MODE_ALIASED;
302 return D2D1_LAYER_OPTIONS1_NONE;
304 return D2D1_LAYER_OPTIONS1_INITIALIZE_FROM_BACKGROUND;
315 brush.brush->SetOpacity(FLOAT(opacity));
317 pen.brush->SetOpacity(FLOAT(opacity));
324 if (
path.isEmpty()) {
325 D2D_RECT_F
rect = {0, 0, 0, 0};
342 qWarning(
"%s: Could not convert vector path to painter path!", __FUNCTION__);
346 dc()->PushLayer(D2D1::LayerParameters1(D2D1::InfiniteRect(),
349 D2D1::IdentityMatrix(),
363 dc()->PopAxisAlignedClip();
400 dc()->SetPrimitiveBlend(D2D1_PRIMITIVE_BLEND_COPY);
403 dc()->SetPrimitiveBlend(D2D1_PRIMITIVE_BLEND_SOURCE_OVER);
409 dc()->SetPrimitiveBlend(D2D1_PRIMITIVE_BLEND_COPY);
423 brush.qbrush = newBrush;
426 brush.brush->SetOpacity(FLOAT(
q->state()->opacity));
443 brush.brush->SetTransform(*(D2D1::Matrix3x2F::ReinterpretBaseType(&
transform))
455 brush.brush->SetTransform(*(D2D1::Matrix3x2F::ReinterpretBaseType(&
transform))
456 * D2D1::Matrix3x2F::Translation(FLOAT(origin.
x()), FLOAT(origin.
y())));
478 pen.brush->SetOpacity(FLOAT(
q->state()->opacity));
480 D2D1_STROKE_STYLE_PROPERTIES1
props = {};
482 switch (newPen.capStyle()) {
495 switch (newPen.joinStyle()) {
497 props.lineJoin = D2D1_LINE_JOIN_BEVEL;
500 props.lineJoin = D2D1_LINE_JOIN_ROUND;
504 props.lineJoin = D2D1_LINE_JOIN_MITER;
508 props.miterLimit = FLOAT(newPen.miterLimit() *
qreal(2.0));
509 props.dashOffset = FLOAT(newPen.dashOffset());
511 if (newPen.widthF() == 0)
512 props.transformType = D2D1_STROKE_TRANSFORM_TYPE_HAIRLINE;
513 else if (newPen.isCosmetic())
514 props.transformType = D2D1_STROKE_TRANSFORM_TYPE_FIXED;
516 props.transformType = D2D1_STROKE_TRANSFORM_TYPE_NORMAL;
518 switch (newPen.style()) {
520 props.dashStyle = D2D1_DASH_STYLE_SOLID;
527 if (newPen.widthF() <= 1.0)
532 props.dashStyle = D2D1_DASH_STYLE_CUSTOM;
538 if (
props.dashStyle == D2D1_DASH_STYLE_CUSTOM) {
539 QList<qreal> dashes = newPen.dashPattern();
540 QList<FLOAT> converted(dashes.size());
542 qreal brushWidth = 0;
543 for (
int i = 0;
i < dashes.size();
i++) {
544 converted[
i] = FLOAT(dashes[
i]);
545 brushWidth += penWidth * dashes[
i];
548 hr =
factory()->CreateStrokeStyle(
props, converted.constData(), UINT32(converted.size()), &
pen.strokeStyle);
552 bitmap.
resize(
int(ceil(brushWidth)),
int(ceil(penWidth)));
553 bitmap.deviceContext()->begin();
555 bitmap.deviceContext()->get()->SetTransform(D2D1::IdentityMatrix());
556 bitmap.deviceContext()->get()->Clear();
559 bitmap.deviceContext()->get()->DrawLine(D2D1::Point2F(FLOAT(offsetX), FLOAT(offsetY)),
560 D2D1::Point2F(FLOAT(brushWidth), FLOAT(offsetY)),
561 pen.brush.Get(), FLOAT(penWidth),
pen.strokeStyle.Get());
562 bitmap.deviceContext()->end();
563 D2D1_BITMAP_BRUSH_PROPERTIES1 bitmapBrushProperties = D2D1::BitmapBrushProperties1(
564 D2D1_EXTEND_MODE_WRAP, D2D1_EXTEND_MODE_CLAMP, D2D1_INTERPOLATION_MODE_LINEAR);
565 hr =
dc()->CreateBitmapBrush(
bitmap.bitmap(), bitmapBrushProperties, &
pen.dashBrush);
568 hr =
factory()->CreateStrokeStyle(
props,
nullptr, 0, &
pen.strokeStyle);
572 qWarning(
"%s: Could not create stroke style: %#lx", __FUNCTION__, hr);
578 ComPtr<ID2D1Brush>
result;
584 switch (newBrush.style()) {
590 ComPtr<ID2D1SolidColorBrush> solid;
594 qWarning(
"%s: Could not create solid color brush: %#lx", __FUNCTION__, hr);
600 qWarning(
"%s: Could not convert solid color brush: %#lx", __FUNCTION__, hr);
618 ComPtr<ID2D1BitmapBrush1> bitmapBrush;
619 D2D1_BITMAP_BRUSH_PROPERTIES1 bitmapBrushProperties = {
620 D2D1_EXTEND_MODE_WRAP,
621 D2D1_EXTEND_MODE_WRAP,
626 brushImg.setColor(0, newBrush.color().rgba());
627 brushImg.setColor(1,
qRgba(0, 0, 0, 0));
632 qWarning(
"%s: Could not create Direct2D bitmap from Qt pattern brush image", __FUNCTION__);
636 hr =
dc()->CreateBitmapBrush(
bitmap.bitmap(),
637 bitmapBrushProperties,
640 qWarning(
"%s: Could not create Direct2D bitmap brush for Qt pattern brush: %#lx", __FUNCTION__, hr);
644 hr = bitmapBrush.As(&
result);
646 qWarning(
"%s: Could not convert Direct2D bitmap brush for Qt pattern brush: %#lx", __FUNCTION__, hr);
654 ComPtr<ID2D1LinearGradientBrush> linear;
655 const auto *qlinear =
static_cast<const QLinearGradient *
>(newBrush.gradient());
657 D2D1_LINEAR_GRADIENT_BRUSH_PROPERTIES linearGradientBrushProperties;
658 ComPtr<ID2D1GradientStopCollection> gradientStopCollection;
660 linearGradientBrushProperties.startPoint =
to_d2d_point_2f(qlinear->start());
661 linearGradientBrushProperties.endPoint =
to_d2d_point_2f(qlinear->finalStop());
665 hr =
dc()->CreateGradientStopCollection(stops.constData(),
666 UINT32(stops.size()),
667 &gradientStopCollection);
669 qWarning(
"%s: Could not create gradient stop collection for linear gradient: %#lx", __FUNCTION__, hr);
673 hr =
dc()->CreateLinearGradientBrush(linearGradientBrushProperties, gradientStopCollection.Get(),
676 qWarning(
"%s: Could not create Direct2D linear gradient brush: %#lx", __FUNCTION__, hr);
682 qWarning(
"%s: Could not convert Direct2D linear gradient brush: %#lx", __FUNCTION__, hr);
692 ComPtr<ID2D1RadialGradientBrush> radial;
693 const auto *qradial =
static_cast<const QRadialGradient *
>(newBrush.gradient());
695 D2D1_RADIAL_GRADIENT_BRUSH_PROPERTIES radialGradientBrushProperties;
696 ComPtr<ID2D1GradientStopCollection> gradientStopCollection;
699 radialGradientBrushProperties.gradientOriginOffset =
to_d2d_point_2f(qradial->focalPoint() - qradial->center());
700 radialGradientBrushProperties.radiusX = FLOAT(qradial->radius());
701 radialGradientBrushProperties.radiusY = FLOAT(qradial->radius());
705 hr =
dc()->CreateGradientStopCollection(stops.constData(), stops.size(), &gradientStopCollection);
707 qWarning(
"%s: Could not create gradient stop collection for radial gradient: %#lx", __FUNCTION__, hr);
711 hr =
dc()->CreateRadialGradientBrush(radialGradientBrushProperties, gradientStopCollection.Get(),
714 qWarning(
"%s: Could not create Direct2D radial gradient brush: %#lx", __FUNCTION__, hr);
720 qWarning(
"%s: Could not convert Direct2D radial gradient brush: %#lx", __FUNCTION__, hr);
732 ComPtr<ID2D1BitmapBrush1> bitmapBrush;
733 D2D1_BITMAP_BRUSH_PROPERTIES1 bitmapBrushProperties = {
734 D2D1_EXTEND_MODE_WRAP,
735 D2D1_EXTEND_MODE_WRAP,
741 hr =
dc()->CreateBitmapBrush(
bitmap->bitmap(),
742 bitmapBrushProperties,
746 qWarning(
"%s: Could not create texture brush: %#lx", __FUNCTION__, hr);
750 hr = bitmapBrush.As(&
result);
752 qWarning(
"%s: Could not convert texture brush: %#lx", __FUNCTION__, hr);
757 if (
result && !newBrush.transform().isIdentity())
767 const bool alias = !
q->antiAliasingEnabled();
774 if (alias && e->aliased)
776 else if (!alias && e->antiAliased)
777 return e->antiAliased;
785 writer.setAliasingEnabled(alias);
830 qWarning(
"%s: Unhandled Curve Data Element", __FUNCTION__);
840 if (writer.isInFigure())
841 if (
path.hasImplicitClose())
845 ComPtr<ID2D1PathGeometry1> geometry = writer.geometry();
847 if (
path.isCacheable()) {
855 e->antiAliased = geometry;
857 path.makeCacheable();
869 IDWriteFontFace *fontFace,
872 const UINT16 *glyphIndices,
873 const FLOAT *glyphAdvances,
874 const DWRITE_GLYPH_OFFSET *glyphOffsets,
879 DWRITE_GLYPH_RUN glyphRun = {
893 ? D2D1_TEXT_ANTIALIAS_MODE_GRAYSCALE : D2D1_TEXT_ANTIALIAS_MODE_CLEARTYPE;
894 dc()->SetTextAntialiasMode(antiAlias ?
antialiasMode : D2D1_TEXT_ANTIALIAS_MODE_ALIASED);
896 dc()->DrawGlyphRun(
pos,
900 DWRITE_MEASURING_MODE_GDI_CLASSIC);
913 qWarning(
"%s: Could not convert path to d2d geometry", __FUNCTION__);
916 dc()->DrawGeometry(geometry.Get(),
pen.brush.Get(),
917 FLOAT(
pen.qpen.widthF()),
pen.strokeStyle.Get());
924 const bool skipJoin = !isPolygon
927 const int lastElement =
path.elementCount() - (implicitClose ? 1 : 2);
928 qreal dashOffset = 0;
930 ID2D1Brush *
brush =
pen.dashBrush ?
pen.dashBrush.Get() :
pen.brush.Get();
931 for (
int i = 0;
i <= lastElement; ++
i) {
939 if (
p1 ==
p2 &&
pen.qpen.widthF() <= 1.0) {
944 if (!
q->antiAliasingEnabled())
947 q->adjustForAliasing(&
p1);
948 q->adjustForAliasing(&
p2);
954 dashOffset =
pen.dashLength - fmod(lineLength - dashOffset,
pen.dashLength);
957 brush, FLOAT(
pen.qpen.widthF()),
nullptr);
963 const qreal patchSegment =
pen.dashBrush ?
qBound(0.0, (
pen.dashLength - dashOffset) / lineLength, 1.0)
968 writer.moveTo(jointStart);
970 writer.lineTo(
line.pointAt(patchSegment));
972 dc()->DrawGeometry(writer.geometry().Get(),
pen.brush.Get(),
973 FLOAT(
pen.qpen.widthF()),
pen.strokeStyle.Get());
976 jointStart =
line.pointAt(1 - patchSegment);
978 if (implicitClose &&
i == lastElement) {
981 writer.moveTo(jointStart);
985 dc()->DrawGeometry(writer.geometry().Get(),
pen.brush.Get(),
986 FLOAT(
pen.qpen.widthF()),
pen.strokeStyle.Get());
993 const QFontDef fontDef = fe->fontDef;
994 ComPtr<IDWriteFontFace> fontFace =
fontCache.value(fontDef);
1001 static const char keyC[] =
"HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Windows NT\\CurrentVersion\\FontSubstitutes";
1004 if (nameSubstitute != familyName) {
1005 const int nameSubstituteLength =
qMin(nameSubstitute.length(), LF_FACESIZE - 1);
1006 memcpy(lf.lfFaceName, nameSubstitute.data(),
size_t(nameSubstituteLength) *
sizeof(
wchar_t));
1007 lf.lfFaceName[nameSubstituteLength] = 0;
1010 ComPtr<IDWriteFont> dwriteFont;
1013 qDebug(
"%s: CreateFontFromLOGFONT failed: %#lx", __FUNCTION__, hr);
1017 hr = dwriteFont->CreateFontFace(&fontFace);
1019 qDebug(
"%s: CreateFontFace failed: %#lx", __FUNCTION__, hr);
1033 QPaintEngine::PaintEngineFeatures unsupported =
1053 d->bitmap->deviceContext()->begin();
1054 d->dc()->SetTransform(D2D1::Matrix3x2F::Identity());
1064 d->dc()->PushLayer(D2D1::LayerParameters1(D2D1::InfiniteRect(),
1067 D2D1::IdentityMatrix(),
1093 if (!
d->fallbackImage.isNull()) {
1094 if (emulatingComposition)
1095 drawImage(
d->fallbackImage.rect(),
d->fallbackImage,
d->fallbackImage.rect());
1103 d->dc()->PopAxisAlignedClip();
1104 d->clipFlags &= ~SimpleSystemClip;
1106 d->dc()->PopLayer();
1109 return d->bitmap->deviceContext()->end();
1138 if (emulationRequired(BrushEmulation))
1146 if (emulationRequired(PenEmulation))
1162 if (emulationRequired(BrushEmulation)) {
1167 if (!
d->brush.brush)
1170 ComPtr<ID2D1Geometry> geometry =
d->vectorPathToID2D1PathGeometry(
path);
1172 qWarning(
"%s: Could not convert path to d2d geometry", __FUNCTION__);
1176 d->dc()->FillGeometry(geometry.Get(),
d->brush.brush.Get());
1188 if (emulationRequired(PenEmulation)) {
1208 d->updateClipEnabled(
state()->clipEnabled);
1214 d->updatePen(
state()->pen);
1226 d->updateBrushOrigin(
state()->brushOrigin);
1232 d->updateOpacity(
state()->opacity);
1238 d->updateCompositionMode(
state()->compositionMode());
1260 if (emulationRequired(BrushEmulation)) {
1264 adjustForAliasing(&
r);
1279 if (emulationRequired(BrushEmulation) || emulationRequired(PenEmulation)) {
1283 for (
int i = 0;
i < rectCount;
i++) {
1285 adjustForAliasing(&
rect);
1290 d->dc()->FillRectangle(d2d_rect,
d->brush.brush.Get());
1293 d->dc()->DrawRectangle(d2d_rect,
d->pen.brush.Get(),
1294 FLOAT(
d->pen.qpen.widthF()),
d->pen.strokeStyle.Get());
1307 if (emulationRequired(BrushEmulation) || emulationRequired(PenEmulation)) {
1311 for (
int i = 0;
i < rectCount;
i++) {
1313 adjustForAliasing(&
rect);
1318 d->dc()->FillRectangle(d2d_rect,
d->brush.brush.Get());
1321 d->dc()->DrawRectangle(d2d_rect,
d->pen.brush.Get(),
1322 FLOAT(
d->pen.qpen.widthF()),
d->pen.strokeStyle.Get());
1329 if (
p2.x() >
p1.x())
1330 return p2.y() <
p1.y();
1332 if (
p1.x() >
p2.x())
1333 return p1.y() <
p2.y();
1354 if (emulationRequired(BrushEmulation) || emulationRequired(PenEmulation)) {
1358 adjustForAliasing(&
p);
1362 FLOAT(
r.width() / 2.0),
1363 FLOAT(
r.height() / 2.0)
1371 FLOAT(
d->pen.qpen.widthF()),
1372 d->pen.strokeStyle.Get());
1384 if (emulationRequired(BrushEmulation) || emulationRequired(PenEmulation)) {
1388 adjustForAliasing(&
p);
1392 FLOAT(
r.width() / 2.0),
1393 FLOAT(
r.height() / 2.0)
1401 FLOAT(
d->pen.qpen.widthF()),
1402 d->pen.strokeStyle.Get());
1429 i.setColor(1,
d->pen.qpen.color().rgba());
1437 r.x() +
r.width(),
r.y(),
1438 r.x() +
r.width(),
r.y() +
r.height(),
1439 r.x(),
r.y() +
r.height()
1444 rasterFill(vp,
brush);
1453 if (
bitmap->bitmap() !=
d->bitmap->bitmap()) {
1456 d->dc()->DrawBitmap(
bitmap->bitmap(),
1458 d->interpolationMode(),
1461 d->dc()->DrawBitmap(
bitmap->bitmap(),
1463 d->interpolationMode());
1471 bool r = intermediate.
resize(
int(sr.width()),
int(sr.height()));
1473 qWarning(
"%s: Could not resize intermediate bitmap to source rect size", __FUNCTION__);
1478 HRESULT hr = intermediate.bitmap()->CopyFromBitmap(
nullptr,
1482 qWarning(
"%s: Could not copy source rect area from source bitmap to intermediate bitmap: %#lx", __FUNCTION__, hr);
1486 bool r = intermediate.resize(
bitmap->size().width(),
1487 bitmap->size().height());
1489 qWarning(
"%s: Could not resize intermediate bitmap to source bitmap size", __FUNCTION__);
1493 HRESULT hr = intermediate.bitmap()->CopyFromBitmap(
nullptr,
1497 qWarning(
"%s: Could not copy source bitmap to intermediate bitmap: %#lx", __FUNCTION__, hr);
1502 d->dc()->DrawBitmap(intermediate.bitmap(),
1504 d->interpolationMode());
1513 if (staticTextItem->numGlyphs == 0)
1519 if (emulationRequired(PenEmulation)) {
1524 ComPtr<IDWriteFontFace> fontFace =
d->fontFaceFromFontEngine(staticTextItem->fontEngine());
1526 qWarning(
"%s: Could not find font - falling back to slow text rendering path.", __FUNCTION__);
1531 QVarLengthArray<UINT16> glyphIndices(staticTextItem->numGlyphs);
1532 QVarLengthArray<FLOAT> glyphAdvances(staticTextItem->numGlyphs);
1533 QVarLengthArray<DWRITE_GLYPH_OFFSET> glyphOffsets(staticTextItem->numGlyphs);
1535 for (
int i = 0;
i < staticTextItem->numGlyphs;
i++) {
1536 glyphIndices[
i] = UINT16(staticTextItem->glyphs[
i]);
1539 glyphAdvances[
i] = 0;
1540 glyphOffsets[
i].advanceOffset = FLOAT(staticTextItem->glyphPositions[
i].x.toReal());
1542 glyphOffsets[
i].ascenderOffset = FLOAT(staticTextItem->glyphPositions[
i].y.toReal() * -1);
1545 d->drawGlyphRun(D2D1::Point2F(0, 0),
1547 staticTextItem->fontEngine()->fontDef,
1548 staticTextItem->numGlyphs,
1549 glyphIndices.constData(),
1550 glyphAdvances.constData(),
1551 glyphOffsets.constData(),
1560 const auto &ti =
static_cast<const QTextItemInt &
>(textItem);
1561 if (ti.glyphs.numGlyphs == 0)
1567 if (emulationRequired(PenEmulation)) {
1572 ComPtr<IDWriteFontFace> fontFace =
d->fontFaceFromFontEngine(ti.fontEngine);
1574 qWarning(
"%s: Could not find font - falling back to slow text rendering path.", __FUNCTION__);
1579 QVarLengthArray<UINT16> glyphIndices(ti.glyphs.numGlyphs);
1580 QVarLengthArray<FLOAT> glyphAdvances(ti.glyphs.numGlyphs);
1581 QVarLengthArray<DWRITE_GLYPH_OFFSET> glyphOffsets(ti.glyphs.numGlyphs);
1583 for (
int i = 0;
i < ti.glyphs.numGlyphs;
i++) {
1584 glyphIndices[
i] = UINT16(ti.glyphs.glyphs[
i]);
1585 glyphAdvances[
i] = FLOAT(ti.glyphs.effectiveAdvance(
i).toReal());
1586 glyphOffsets[
i].advanceOffset = FLOAT(ti.glyphs.offsets[
i].x.toReal());
1589 glyphOffsets[
i].ascenderOffset = FLOAT(ti.glyphs.offsets[
i].y.toReal());
1597 ti.fontEngine->fontDef,
1598 ti.glyphs.numGlyphs,
1599 glyphIndices.constData(),
1600 glyphAdvances.constData(),
1601 glyphOffsets.constData(),
1605void QWindowsDirect2DPaintEngine::ensureBrush()
1610void QWindowsDirect2DPaintEngine::ensureBrush(
const QBrush &
brush)
1616void QWindowsDirect2DPaintEngine::ensurePen()
1618 ensurePen(
state()->pen);
1621void QWindowsDirect2DPaintEngine::ensurePen(
const QPen &pen)
1631 if (
d->fallbackImage.isNull()) {
1634 d->fallbackImage =
d->bitmap->toImage();
1646 p.setRenderHints(
state()->renderHints);
1647 p.setCompositionMode(
state()->compositionMode());
1648 p.setOpacity(
state()->opacity);
1649 p.setBrushOrigin(
state()->brushOrigin);
1658 switch (
info.clipType) {
1686 qWarning(
"%s: Paint Engine end returned false", __FUNCTION__);
1689 d->updateClipEnabled(
false);
1697 qWarning(
"%s: Could not fall back to QImage", __FUNCTION__);
1701bool QWindowsDirect2DPaintEngine::emulationRequired(EmulationType
type)
const
1713 return d->pen.emulate;
1715 case BrushEmulation:
1716 return d->brush.emulate;
1723bool QWindowsDirect2DPaintEngine::antiAliasingEnabled()
const
1728void QWindowsDirect2DPaintEngine::adjustForAliasing(
QRectF *
rect)
1730 if (!antiAliasingEnabled()) {
1738void QWindowsDirect2DPaintEngine::adjustForAliasing(
QPointF *point)
1743 if (!antiAliasingEnabled())
1744 (*point) += adjustment;
1747void QWindowsDirect2DPaintEngine::suspend()
1752void QWindowsDirect2DPaintEngine::resume()
1776 m_engine->suspend();
ComPtr< ID2D1PathGeometry1 > geometry() const
void setWindingFillEnabled(bool enable)
void moveTo(const QPointF &point)
void curveTo(const QPointF &p1, const QPointF &p2, const QPointF &p3)
void lineTo(const QPointF &point)
void setPositiveSlopeAdjustmentEnabled(bool enable)
void setAliasingEnabled(bool enable)
QPen pen() const
Returns the item's pen.
QBrush brush() const
Returns the item's brush, or an empty brush if no brush has been set.
@ Format_ARGB32_Premultiplied
void setColor(int i, QRgb c)
Sets the color at the given index in the color table, to the given to colorValue.
\inmodule QtCore\compares equality \compareswith equality QLine \endcompareswith
bool isEmpty() const noexcept
void replayClipOperations()
virtual void drawRects(const QRect *rects, int rectCount) override
This is an overloaded member function, provided for convenience. It differs from the above function o...
virtual void stroke(const QVectorPath &path, const QPen &pen)
virtual void drawEllipse(const QRectF &r) override
Reimplement this function to draw the largest ellipse that can be contained within rectangle rect.
virtual void fillRect(const QRectF &rect, const QBrush &brush)
virtual void setState(QPainterState *s)
virtual void drawStaticTextItem(QStaticTextItem *)
void setActive(bool newState)
Sets the active state of the paint engine to state.
virtual void drawTextItem(const QPointF &p, const QTextItem &textItem)
This function draws the text item textItem at position p.
PaintEngineFeatures gccaps
QRegion systemClip() const
QPaintDevice * paintDevice() const
Returns the device that this engine is painting on, if painting is active; otherwise returns \nullptr...
Type
\value X11 \value Windows \value MacPrinter \value CoreGraphics \macos's Quartz2D (CoreGraphics) \val...
ElementType
This enum describes the types of elements used to connect vertices in subpaths.
void addRegion(const QRegion ®ion)
Adds the given region to the path by adding each rectangle in the region as a separate closed subpath...
QPainter::RenderHints renderHints
The QPainter class performs low-level painting on widgets and other paint devices.
CompositionMode
Defines the modes supported for digital image compositing.
@ CompositionMode_SourceOver
QBrush brush() const
Returns the brush used to fill strokes generated with this pen.
Returns a copy of the pixmap that is transformed using the given transformation transform and transfo...
QImage toImage() const
Converts the pixmap to a QImage.
bool isNull() const
Returns true if this is a null pixmap; otherwise returns false.
QPlatformPixmap * handle() const
QPixmap copy(int x, int y, int width, int height) const
This is an overloaded member function, provided for convenience. It differs from the above function o...
static QPixmap fromImage(const QImage &image, Qt::ImageConversionFlags flags=Qt::AutoColor)
Converts the given image to a pixmap using the specified flags to control the conversion.
\inmodule QtCore\reentrant
constexpr qreal x() const noexcept
Returns the x coordinate of this point.
constexpr qreal y() const noexcept
Returns the y coordinate of this point.
bool isNull() const noexcept
Returns true if both the x and y coordinates are set to 0.0 (ignoring the sign); otherwise returns fa...
QPointF center() const
Returns the center of this radial gradient in logical coordinates.
\inmodule QtCore\reentrant
QRectF normalized() const noexcept
Returns a normalized rectangle; i.e., a rectangle that has a non-negative width and height.
\inmodule QtCore\reentrant
QRect normalized() const noexcept
Returns a normalized rectangle; i.e., a rectangle that has a non-negative width and height.
QRect boundingRect() const noexcept
Returns the bounding rectangle of this region.
void reset(T *other=nullptr) noexcept(noexcept(Cleanup::cleanup(std::declval< T * >())))
Deletes the existing object it is pointing to (if any), and sets its pointer to other.
QVariant value(QAnyStringView key, const QVariant &defaultValue) const
Returns the value for setting key.
T pop()
Removes the top item from the stack and returns it.
void push(const T &t)
Adds element t to the top of the stack.
\macro QT_RESTRICTED_CAST_FROM_ASCII
static QString fromWCharArray(const wchar_t *string, qsizetype size=-1)
qsizetype length() const noexcept
Returns the number of characters in this string.
QString toString() const
Returns the variant as a QString if the variant has a userType() including, but not limited to:
ID2D1Bitmap1 * bitmap() const
bool resize(int width, int height)
bool fromImage(const QImage &image, Qt::ImageConversionFlags flags)
static QWindowsDirect2DContext * instance()
ComPtr< ID2D1StrokeStyle1 > strokeStyle
void updatePen(const QPen &newPen)
ID2D1DeviceContext * dc() const
void clip(const QVectorPath &path, Qt::ClipOperation operation)
void updateBrushOrigin(const QPointF &brushOrigin)
void drawGlyphRun(const D2D1_POINT_2F &pos, IDWriteFontFace *fontFace, const QFontDef &fontDef, int numGlyphs, const UINT16 *glyphIndices, const FLOAT *glyphAdvances, const DWRITE_GLYPH_OFFSET *glyphOffsets, bool rtl)
void pushClip(const QVectorPath &path)
QWindowsDirect2DPaintEngine::Flags flags
QStack< ClipType > pushedClips
void applyBrushOrigin(const QPointF &origin)
QHash< QFontDef, ComPtr< IDWriteFontFace > > fontCache
QWindowsDirect2DPaintEnginePrivate(QWindowsDirect2DBitmap *bm, QWindowsDirect2DPaintEngine::Flags flags)
void stroke(const QVectorPath &path)
D2D1_ANTIALIAS_MODE antialiasMode() const
ComPtr< ID2D1Brush > brush
void updateTransform(const QTransform &transform)
QPointF currentBrushOrigin
D2D1_INTERPOLATION_MODE interpolationMode() const
ComPtr< IDWriteFontFace > fontFaceFromFontEngine(QFontEngine *fe)
void updateOpacity(qreal opacity)
void updateBrush(const QBrush &newBrush)
void updateCompositionMode(QPainter::CompositionMode mode)
struct QWindowsDirect2DPaintEnginePrivate::@430 pen
void negateCurrentBrushOrigin()
ComPtr< ID2D1Brush > to_d2d_brush(const QBrush &newBrush, bool *needsEmulation)
QWindowsDirect2DBitmap * bitmap
D2D1_LAYER_OPTIONS1 layerOptions() const
ComPtr< ID2D1PathGeometry1 > vectorPathToID2D1PathGeometry(const QVectorPath &path)
void updateClipEnabled(bool enabled)
ComPtr< ID2D1BitmapBrush1 > dashBrush
~QWindowsDirect2DPaintEngineSuspenderImpl()
QWindowsDirect2DPaintEngineSuspenderImpl(QWindowsDirect2DPaintEngine *engine)
QWindowsDirect2DPaintEngineSuspenderImpl engineSuspender
QWindowsDirect2DPaintEngineSuspenderPrivate(QWindowsDirect2DPaintEngine *engine)
QWindowsDirect2DDeviceContextSuspender dcSuspender
~QWindowsDirect2DPaintEngineSuspender()
QWindowsDirect2DPaintEngineSuspender(QWindowsDirect2DPaintEngine *engine)
void penChanged() override
void fillRect(const QRectF &rect, const QBrush &brush) override
Type type() const override
Reimplement this function to return the paint engine \l{Type}.
void opacityChanged() override
void renderHintsChanged() override
@ TranslucentTopLevelWindow
void brushOriginChanged() override
void compositionModeChanged() override
void drawRects(const QRect *rects, int rectCount) override
This is an overloaded member function, provided for convenience. It differs from the above function o...
void transformChanged() override
void draw(const QVectorPath &path) override
void drawEllipse(const QRectF &r) override
Reimplement this function to draw the largest ellipse that can be contained within rectangle rect.
void clipEnabledChanged() override
void drawTextItem(const QPointF &p, const QTextItem &textItem) override
This function draws the text item textItem at position p.
void brushChanged() override
void setState(QPainterState *s) override
void stroke(const QVectorPath &path, const QPen &pen) override
void drawStaticTextItem(QStaticTextItem *staticTextItem) override
void drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr) override
Reimplement this function to draw the part of the pm specified by the sr rectangle in the given r.
void fill(const QVectorPath &path, const QBrush &brush) override
void clip(const QVectorPath &path, Qt::ClipOperation op) override
QWindowsDirect2DPaintEngine(QWindowsDirect2DBitmap *bitmap, Flags flags)
bool end() override
Reimplement this function to finish painting on the current paint device.
void drawImage(const QRectF &rectangle, const QImage &image, const QRectF &sr, Qt::ImageConversionFlags flags=Qt::AutoColor) override
Reimplement this function to draw the part of the image specified by the sr rectangle in the given re...
bool begin(QPaintDevice *pdev) override
Reimplement this function to initialise your paint engine when painting is to start on the paint devi...
static LOGFONT fontDefToLOGFONT(const QFontDef &fontDef, const QString &faceName)
Combined button and popup list for selecting options.
bool qFuzzyIsNull(qfloat16 f) noexcept
constexpr float qDegreesToRadians(float degrees)
constexpr const T & qMin(const T &a, const T &b)
constexpr const T & qBound(const T &min, const T &val, const T &max)
GLint GLint GLint GLint GLint x
[0]
GLsizei GLenum GLenum * types
GLenum GLenum GLsizei count
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLenum GLenum GLsizei const GLuint GLboolean enabled
GLenum const void GLbitfield GLsizei numGlyphs
GLenum GLuint GLsizei const GLenum * props
GLenum GLuint GLintptr offset
GLuint GLenum GLenum transform
GLfixed GLfixed GLint GLint GLfixed points
GLfixed GLfixed GLfixed y2
GLsizei GLfixed GLfixed GLfixed GLfixed const GLubyte * bitmap
GLdouble GLdouble GLdouble GLdouble q
GLsizei const GLchar *const * path
const QVectorPath & qtVectorPathForPath(const QPainterPath &path)
static bool needsEmulation(const QBrush &brush)
Qt::BrushStyle qbrush_style(const QBrush &b)
bool qpen_fast_equals(const QPen &a, const QPen &b)
Qt::PenStyle qpen_style(const QPen &p)
QBrush qpen_brush(const QPen &p)
bool qbrush_fast_equals(const QBrush &a, const QBrush &b)
constexpr QRgb qRgba(int r, int g, int b, int a)
D2D1::ColorF to_d2d_color_f(const QColor &c)
D2D1_POINT_2F to_d2d_point_2f(const QPointF &qpoint)
D2D1_MATRIX_3X2_F to_d2d_matrix_3x2_f(const QTransform &transform)
QT_BEGIN_NAMESPACE D2D1_RECT_U to_d2d_rect_u(const QRect &qrect)
D2D1_RECT_F to_d2d_rect_f(const QRectF &qrect)
static D2D1_MATRIX_3X2_F transformFromLine(const QLineF &line, qreal penWidth, qreal dashOffset)
Q_GUI_EXPORT QImage qt_imageForBrush(int brushStyle, bool invert)
static ID2D1Factory1 * factory()
static const qreal MAGICAL_ALIASING_OFFSET
static void adjustLine(QPointF *p1, QPointF *p2)
static QList< D2D1_GRADIENT_STOP > qGradientStopsToD2DStops(const QGradientStops &qstops)
static bool isLinePositivelySloped(const QPointF &p1, const QPointF &p2)
@ D2DDebugDrawInitialStateTag
@ D2DDebugDrawTextItemTag
@ D2DDebugDrawEllipseFTag
@ D2DDebugDrawStaticTextItemTag
QGraphicsEllipseItem * ellipse
ComPtr< ID2D1PathGeometry1 > antiAliased
static void cleanup_func(QPaintEngineEx *engine, void *data)
ComPtr< ID2D1PathGeometry1 > aliased