Commit Graph

85 Commits

Author SHA1 Message Date
New Pagodi
b936bfe85e Add Direct2D support to wxSTC 2018-01-25 16:07:54 -06:00
Vadim Zeitlin
76fd05b147 Leave only wxGraphicsRenderer::CreatePen(wxGraphicsPenInfo) overload
It doesn't make much sense to require all the graphics backends to
create wxGraphicsPen from either wxPen or wxGraphicsPenInfo when the
former can be handled just once in the common code.

So do just this, leaving CreatePen() overload taking wxGraphicsPenInfo
where the real pen construction takes place and implementing
wxGraphicsPen creation from wxPen in the common wxGraphicsContext code.

This is not 100% backwards-compatible as any code inheriting from
wxGraphicsRenderer and overriding its CreatePen() will now be broken,
however this should be extremely rare (there is no good reason to
inherit from this class in the user code) and result in compile errors
if it does happen.
2017-09-10 01:48:30 +02:00
Vadim Zeitlin
cc91a7d6d4 Minor formatting and style changes in wxPenInfo code
Use more standard formatting, wrap some overlong lines.
2017-09-10 01:11:06 +02:00
Adrien Tétar
999c750ca7 Review feedback 2017-09-10 01:02:21 +02:00
Adrien Tétar
2305604565 Introduce wxGraphicsPenInfo class 2017-09-10 01:02:20 +02:00
Oliver Smith
b8f83725ed Fix D2D wxGraphics build with wxUSE_UNICODE==0
Revert one of the changes of 5520702674 which
replaced direct check with a call to lstrlen() which seems to be unneeded and
doesn't compile in non-Unicode build.
2017-06-28 02:53:46 +02:00
Artur Wieczorek
7f9453dfdf Handle unsuccessful creation of graphics font in Direct2D
Apparently, DirectWrite fonts can be created only from TrueType fonts and
therefore only such fonts can be used with Direct2D-based wxGraphicsContext.
When unsuported GDI font is passed to CreateFont() then no graphics font is
created and this unsuccessful attempt is signalled by returning
wxNullGraphicsFont. This null object can be used in e.g. wxGC::SetFont()
to check if font was actually created.

See #17790.
2017-04-17 18:57:02 +02:00
Artur Wieczorek
5520702674 Typeface name of the font must not exceed LF_FACESIZE characters 2017-01-28 21:47:49 +01:00
Artur Wieczorek
f0bf5b6fd7 Add more status checks in Direct2D renderer
See #17790.
2017-01-28 21:46:42 +01:00
Václav Slavík
e71be91ebe Add API to create wxGraphicsContext from win32 HDC
Add wxGraphicsContext::CreateFromNativeHDC() and wxGraphicsRenderer::
CreateContextFromNativeHDC() to allow creation not only from native
renderer object, but also from HDC, which is something universally
supported by win32 implementations.
2017-01-06 14:35:09 +01:00
Paul Cornett
9b19a6e529 use wxOVERRIDE in wxMSW sources 2016-09-23 07:59:11 -07:00
Artur Wieczorek
aa687ec86e Implement wxGraphicsMatrixData::Clone() method for Direct2D renderer 2016-09-18 23:08:49 +02:00
Artur Wieczorek
b6d44d5329 Fix wxGraphicsMatrix concatenation (Direct2D)
1. Elements of resulting matrix are modified directly (in-place) in Matrix3x2F::SetProduct() so none of the multiplied matrices can be the instance of the resulting matrix.
2. The parameter matrix in wxGraphicsMatrixData::Concat() should be a multiplicand, not a multiplier.

See #17670.
2016-09-18 23:06:14 +02:00
Artur Wieczorek
588425a9d4 Add caching of clipping box values for Direct2D graphics context
Since retrieving actual clipping box is an expensive operation so to improve performance of wxD2DContext::GetClipBox() we need to store just retrieved clipping box data in the cache. These stored data will be then used in the forthcoming requests for clipping box values. Cached clipping box data are invalidated whenever clipping region is explicitly set using Clip()/ResetClip() or whenever transformation matrix is changed (to take into account new coordinates). If there is a call for clipping box (with GetClipBox) and cached data are marked as invalid then clipping box is retrieved/recalculated and stored in the cache.
2016-09-01 21:42:27 +02:00
Artur Wieczorek
78f00da98a Fix wxGraphicsMatrix::TransformDistance for Direct2D implementation
Current transformation matrix without translation component should be used in calculations.
2016-08-21 21:01:52 +02:00
Artur Wieczorek
480a003c00 Add wxGraphicsContext::GetClipBox() function
This method returns bounding box of the current clipping region.
Added declaration, documentation and implemented for GDI+, Direct2D, Cairo renderers.
2016-08-21 20:57:40 +02:00
Artur Wieczorek
d9193d5368 Fix saving/restoring drawing state for wxGraphicsContext with Direct2D
Native ID2D1RenderTarget::SaveDrawingState method stores in ID2D1DrawingStateBlock only transform, antialiasing mode, text-rendering options and tags but not currently set ID2D1Layers (which are used in wxD2DContext for clipping purposes). Therefore current stack of layers has to be stored "manually" alongside ID2D1DrawingStateBlock in a dedicated data structure (LayerData) in PushState() and restored also "manually" in PopState().

Closes #17626.
2016-08-12 23:16:09 +02:00
Artur Wieczorek
c468dd67cb Fix setting rectangular clipping region for Direct2D
If transformation matrix of wxGraphicsContext with Direct2D renderer is e.g. rotated then rectangular clipping region represented by layer created with ID2D1RenderTarget::PushAxisAlignedClip is invalid because this kind of layers create axis-aligned clipping regions which edges are always horizontal or vertical (not e.g. rotated).
To take into account current transformation matrix when clipping region is set there is necessary to represent all clipping regions (even rectangular) by generic layers (ID2D1Layer) created with ID2D1RenderTarget::CreateLayer.

Closes #17622
2016-08-09 20:47:57 +02:00
Artur Wieczorek
947c6d4954 Fixed setting clipping region (passed in wxRegion) for Direct2D renderer.
If empty wxRegion is passed to wxD2DContext::Clip() then ID2D1RectangleGeometry object representing geometric mask used by ID2D1Layer object (clipping layer) has to be created in a special way because wxRegionIterator doesn't extract empty rectangle.

ID2D1RectangleGeometry object representing geometric mask has to be maintained as long as corresponding clipping layer is in use so we have to store a reference to this object together with other layer data. Object is released when layer is destroyed.

Closes #17596
2016-07-15 21:01:57 +02:00
Artur Wieczorek
832db47346 Fixed layer management in Direct2D renderer.
ID2D1RenderTarget::PushAxisAlignedClip/PopAxisAlignedClip used to clip the region (with wxGraphicsRenderer::Clip) and ID2D1RenderTarget::PushLayer/PopLayer used to rendering to the transparent layer (with wxGraphicsRenderer::BeginLayer) are non independent but have to be used in the controlled sequences: "A PushAxisAlignedClip and PopAxisAlignedClip pair can occur around or within a PushLayer and PopLayer, but cannot overlap" (and of course finally each Push* call must have a matching Pop* call).
To control the sequence of access to the AxisAlignedClips and Layers there is implemented a wxStack data member holding Clips/Layers parameters which reflects a physical stack of respective Clips/Layers in ID2D1RenderTarget. This way we know in which order to pop and what to pop from ID2D1RenderTarget stack if there is a need to do so.

Closes #17590
2016-07-05 21:58:34 +02:00
Artur Wieczorek
a735371b0e Fixed creating wxGraphicsContext with Direct2D renderer.
When render target to draw to a DC (created with ID2D1Factory::CreateDCRenderTarget method) is bound to the device context with ID2D1DCRenderTarget::BindDC method then not only the logical size of a DC needs to be taken into account but also the origin of this DC.
To get proper drawing output the coordinates of all drawing operations should be internally adjusted by this initial origin.
This corrective translation should be used only internally by wxGraphicsContext object and shouldn't be exposed through e.g. GetTransform() function and therefore it is stored separately (in a dedicated variable) and "subtracted" from actual transformation settings for reporting purposes.

See #17564
2016-06-11 23:18:09 +02:00
Artur Wieczorek
edabb01032 Add initial line segment when adding arc to wxGraphicsPath with GDI+
For the sake of compatibility with Cairo (and Direct2D) an initial line segment should be added to the path from the current point (if set) to the beginning of the arc.

Closes #17557
2016-06-05 19:00:13 +02:00
Artur Wieczorek
9f9d593019 Fixed adding arc to wxGraphicsPath with Direct2D renderer.
To handle properly all combinations of the start and end angles and to ensure consistency with Cairo renderer behaviour there is necessary
1. To normalize angle values the same way as it is done in Cairo.
and
2. When difference between end angle and start angle >= 2*pi then in addition to the arc itself also one or more full circles have to be added to the path.

See #17558
See #17557
2016-06-04 11:12:55 +02:00
Artur Wieczorek
eb2fc93a9b Fixed adding arc to wxGraphicsPath with Direct2D renderer
Modified calculations of sweep angle to get its correct value for all combinations of start/end angle values and clockwise/counter-clockwise drawing.

See #17552
2016-05-29 17:39:03 +02:00
Artur Wieczorek
7923cb222e Fixed cloning wxD2DPathData.
In addition to copying the underlying geometry sink itself also auxiliary data, like collection of transformed geometries and positional data have to copied the the new wxD2DPathData instance.
2016-05-26 17:55:34 +02:00
Artur Wieczorek
2b13dc7473 Modified wxGraphicsPath concatenation (with AddPath) for Direct2D renderer.
Because wxGraphicsPath comprises current ID2D1PathGeometry object and the collection of transformed (sub-)geometries (ID2D1TransformedGeometry objects) so to concatenate two paths we need to concatenate their current geometries as well as to combine the collections of transformed geometries.
2016-05-26 17:54:45 +02:00
Artur Wieczorek
fa01392788 Fixed transformation of wxGraphicsPath for Direct2D renderer.
Unfortunately, it seems that this is not a straightforward method to apply transformation to the current underlying path geometry (ID2D1PathGeometry object) "in-place" (ie. transform it and use for further graphics operations). Some simple methods offered by Direct2D are not useful for these purposes:
1. ID2D1Factory::CreateTransformedGeometry() converts ID2D1PathGeometry object to ID2D1TransformedGeometry object and ID2D1TransformedGeometry inherits from ID2D1Geometry (not from ID2D1PathGeometry) and cannot be used for path operations.
2. ID2D1Geometry::CombineWithGeometry() which could be used to get final geometry by combining empty geometry with transformed geometry doesn't offer any combine mode which would produce a "sum" of geometries (D2D1_COMBINE_MODE_UNION gives kind of outline). Moreover the result is stored in ID2D1SimplifiedGeometrySink not in ID2DGeometrySink.

So, it seems that ability to transform the wxGraphicsPath (even several times) and still use it after this operation(s) can be achieved by using a geometry group object (ID2D1GeometryGroup) this way:
1. After applying transformation to the current path geometry with ID2D1Factory::CreateTransformedGeometry() the result is stored in the collection of transformed geometries (an auxiliary array) and after that a new (empty) geometry is open (in the same state as just closed one) and this geometry is used as a current one for further graphics operations.
2. Above steps are done at every transformation so our effective geometry will be a superposition of all previously transformed geometries stored in the collection (array) and the current operational geometry.
3. If there is necessary to use this combined effective geometry in any operation then ID2D1GeometryGroup created with ID2D1Factory::CreateGeometryGroup() from the collection of stored geometries will act as a proxy geometry.

Closes #17549
2016-05-26 17:51:53 +02:00
Artur Wieczorek
b92c91bafb Fixed flushing underlying graphics path data for Direct2D renderer
Don't attempt to close already closed geometry sink.
2016-05-26 17:33:59 +02:00
Artur Wieczorek
a64a204749 Add more error checks to Direct2D wxGraphicsRenderer code.
Check the results of the native Direct2D operations.
2016-05-26 17:32:58 +02:00
Artur Wieczorek
993fcdac7d Added missing references to some dynamically loaded Direct2D API's.
Without this fix invoking D2D1::Matrix3x2F::IsInvertible() or D2D1::Matrix3x2F::Skew() functions breaks the build.
2016-05-26 17:32:09 +02:00
Artur Wieczorek
360416dfed Check if path geometry contents was successfully transferred while cloning wxD2DPathData.
Since only geometry with closed sink (immutable) can be transferred to another geometry object with ID2D1PathGeometry::Stream() so we have to check if actual transfer succeeded and return NULL if not.
2016-05-12 21:34:53 +02:00
Artur Wieczorek
bd55ce4d37 Fixed closing sub-path of wxGraphicsPath with Direct2D renderer.
To ensure compatibility with Cairo renderer the new sub-path should be started at the joined endpoint of the current (just closed) sub-path.

Closes #17532
2016-05-12 21:33:50 +02:00
Artur Wieczorek
4014000a98 Fixed wxGraphicsPath concatenation (with AddPath) for Direct2D renderer.
Because only ID2D1PathGeometry with closed sink (in the immutable state) can be transferred to another geometry object with ID2D1PathGeometry::Stream() so appending one wxGraphicsPath to another has to be done with source path geometry in the non-writable state and closing this geometry has to be done prior to any other operation.
But we want source wxGraphicsPath to stay in the writable state after appending it to another path so we have to prepare a writable copy of the source ID2D1PathGeometry and assign it to the source wxGraphicPath after the appending.

See #17532
2016-05-12 21:32:20 +02:00
Artur Wieczorek
66e3a3f724 Fixed adding a Bezier curve to wxGraphicsPath with Direct2D renderer.
When current point is not set before the call to wxGraphicsPath::AddCurveToPoint() then it should be set at first control point prior to adding a curve (function should behave as if preceded by MoveToPoint).

Closes #17526
2016-05-09 18:41:16 +02:00
Artur Wieczorek
43ba49285b Fixed closing sub-path of wxGraphicsPath with Direct2D renderer.
Ensure that sub-path being closed contains at least one point.

Closes #17525
2016-05-08 21:54:11 +02:00
Artur Wieczorek
fa5f3818b9 Fixed adding a line to wxGraphicsPath with Direct2D renderer.
When current point is not yet set then wxGraphicsPath::AddLineToPoint() should behave as MoveToPoint(). We have to determine whether current point is set or not using additional flag because native renderer doesn't provide any support regarding this matter.

See #17525
2016-05-08 21:53:15 +02:00
Artur Wieczorek
dc75ae2bf7 Fixed appending a curve to wxGraphicsPath with Direct2D renderer.
If there is necessary to start a new D2D figure prior to appending a curve to the path then this new figure should be started at the current point and not always at (0,0).

Closes #17521
2016-05-06 18:49:05 +02:00
Artur Wieczorek
329aee5660 Fixed closing sub-path of wxGraphicsPath with Direct2D renderer.
When sub-path is closed with CloseSubpath() then current point should be moved to the joined endpoint of the sub-path (what is equivalent of moving it to the starting point of the sub-path). To implement this behaviour we need to store on our own the starting point of the figure in a dedicate data member because native D2D renderer apparently doesn't offer any support for retrieving it.

See #17520
2016-05-05 13:51:27 +02:00
Artur Wieczorek
a28f1b7f44 Fixed appending a line to wxGraphicsPath with Direct2D renderer.
If there is necessary to start a new D2D figure prior to appending the line to the path it should be started at the current point and not always at (0,0).

See #17520
2016-05-05 13:50:09 +02:00
Artur Wieczorek
008a162241 Fixed appending circle/ellipse to wxGraphicsPath with Direct2D renderer.
Circle/ellipse should be appended as a closed sub-path and the current point after the operation should be moved to "the rightmost point" of the figure ((x+r,y) and (x+w,y+h/2) respectively).

See #17520
2016-05-05 13:49:36 +02:00
Maarten Bent
7c16c93807 Fix for PCH-less build for wxD2DContext.
It is required for FLT_MAX in Direct2D graphics context.

Closes https://github.com/wxWidgets/wxWidgets/pull/276
2016-05-01 19:03:58 +02:00
Artur Wieczorek
1e6cf64a2a Fixed creating wxGraphicsPath with Direct2D renderer.
When current endpoint is moved to a new position with MoveToPoint() then current sub-path should be ended without closing the figure (no line from the current point to the beginning of the sub-path should be added).

Closes #17516
2016-05-01 19:02:58 +02:00
Artur Wieczorek
6243e0e507 Use wxList instead of std::list in Direct2D renderer.
This would remove explicit dependency on STL.
2016-04-22 21:17:01 +02:00
Artur Wieczorek
e962172cd9 Don't call std::sin, std::cos functions.
This is for the sake of consistency because everywhere else there are used trigonometric functions from standard C library (only <math.h> is included).
2016-04-22 21:15:41 +02:00
Artur Wieczorek
8a7374e5ca Fixed drawing with wxGraphicsContext and Direct2D renderer.
When render target to draw to a DC (created with ID2D1Factory::CreateDCRenderTarget method) is bound to the device context with ID2D1DCRenderTarget::BindDC method then the size of the area of drawing has to be a logical size of a DC (with its scaling factor taken int account). This can be determined directly using GetClipBox API and there is no need to pass it as a parameter of wxD2DDCRenderTargetResourceHolder ctor.

Closes #17504.
2016-04-21 20:24:43 +02:00
Artur Wieczorek
deb162fc5a Fixes for PCH-less build for Direct2D graphics context.
Include the required headers inside "#ifndef WX_PRECOMP" block.

See #17502.
2016-04-20 22:03:38 +02:00
Artur Wieczorek
4b0732269d Fixed determining Direct2D graphics context size (wxMSW).
Determine actual size of wxD2DContext instance and initialize respective data members to report proper size of wxGraphicsContext created by wxGraphicsRenderer::CreateContextFromNativeContext / CreateContextFromNativeWindow.

Closes #17502.
2016-04-20 20:54:48 +02:00
Václav Slavík
7c709be652 Silence VC14 warning in d2d1helper.h system header 2016-03-29 18:54:58 +02:00
Artur Wieczorek
95e63ed062 Pass D2D1_ALPHA_MODE value instead of Boolean flag to wxD2DContext.
Using non-Boolean argument should be more clear.

See #17465.
2016-03-28 21:47:09 +02:00
Artur Wieczorek
e07aa294a4 Fixed drawing on wxMemoryDC with Direct2DRenderer.
32bpp wxBitmaps selected into wxMemoryDC can represent either 0RGB or ARGB bitmaps and hence there is necessary to instruct renderer how to interpret 32bpp contents while creating a wxGraphicsContext. wxBitmap::HasAlpha() flag is used for these purposes and its value is passed to wxD2DContext ctor (wxD2DContext is used internally as a backend D2D component) and next used to configure physical renderer created with ID2D1Factory::CreateDCRenderTarget.

Closes #17465.
2016-03-28 21:22:06 +02:00