IDWriteGlyphRunAnalysis supports gray-scale antialiasing only when
created via IDWriteFactory2 (and newer), introduced in Windows 8.1
Fallback to using DIrect2D on A8 targets when IDWriteFactory2 is
not available.
...by checking for IUnknown.
This makes GeometryRecorder::QueryInterface compliant with the
rules of COM.
QueryInterface for IUnknown has a special meaning in COM: it's
used to check whether two interface pointers refer to the same
object.
STDMETHOD / IFACEMETHOD macros already add __declspec(nothrow), but
noexcept is better. From MSDN [1]:
We recommend that all new code use the noexcept operator rather than
__declspec(nothrow).
This attribute tells the compiler that the declared function and the
functions it calls never throw an exception. However, it does not
enforce the directive. In other words, it never causes std::terminate
to be invoked, unlike noexcept, or in std:c++17 mode (Visual Studio
2017 version 15.5 and later), throw().
See also [2]:
Non-throwing functions are permitted to call potentially-throwing
functions. Whenever an exception is thrown and the search for a handler
encounters the outermost block of a non-throwing function, the function
std::terminate is called:
extern void f(); // potentially-throwing
void g() noexcept {
f(); // valid, even if f throws
throw 42; // valid, effectively a call to std::terminate
}
References:
[1] https://learn.microsoft.com/en-us/cpp/cpp/nothrow-cpp?view=msvc-170
[2] https://en.cppreference.com/w/cpp/language/noexcept_spec
IFACEMETHOD already adds the __override / __allowed(on_function) SAL
annotation (only on Windows SDK, not mingw-w64), which is understood
by some code analysis tools [1]. Since we're compiling in C++11 mode,
we can add the override specifier, so that the compiler is informed
as well.
[1] https://devblogs.microsoft.com/oldnewthing/20200911-00/?p=104205
Fixes the following warnings on CLang:
../cairo/src/win32/cairo-dwrite-font.cpp:869:27: warning: exception specification
of overriding function is more lax than base version [-Wmicrosoft-exception-spec]
869 | IFACEMETHODIMP_(void) SetFillMode(D2D1_FILL_MODE fillMode)
| ^
D:/msys64/clang64/include/d2d1.h:1491:22: note: overridden virtual function is here
1491 | STDMETHOD_(void, SetFillMode)(D2D1_FILL_MODE fillMode) PURE;
|
COM objects are usually implemented like that:
1. The class is defined with only method declarations. For that,
one should use IFACEMETHOD macros.
2. Then methods are implemented (defined), outside of the class
definition. For that, one should use the IFACEMETHODIMP macros
If one really wants to provide inline method definitions (that is,
inside the class definition), then IFACEMETHOD macros should be used
(and not IFACEMETHODIMP, though it's a definition / implementation).
...and make the code use that instead of the original IDWriteFontFace
in the font face subclass. We do that because to apply a few settings
(font variations) a new IDWriteFontFace must be created out of the
original one.
For now the IDWriteFontFace in the scaled font is a copy of the one in
the font face. In the next commit we'll add code to create a different
object.
DWRITE_GLYPH_IMAGE_FORMATS is now defined by dcommon.h
In file included from C:/msys64/ucrt64/include/minwindef.h:163,
from C:/msys64/ucrt64/include/windef.h:9,
from C:/msys64/ucrt64/include/windows.h:69,
from ..\src/cairo-mutex-impl-private.h:182,
from ..\src/cairo-mutex-type-private.h:45,
from ..\src/cairo-scaled-font-private.h:45,
from ..\src/cairoint.h:415,
from ../src/win32/cairo-dwrite-font.cpp:37:
../src/win32/dw-extra.h:26:1: error: redefinition of 'DWRITE_GLYPH_IMAGE_FORMATS operator|(DWRITE_GLYPH_IMAGE_FORMATS, DWRITE_GLYPH_IMAGE_FORMATS)'
26 | DEFINE_ENUM_FLAG_OPERATORS(DWRITE_GLYPH_IMAGE_FORMATS);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~
C:/msys64/ucrt64/include/dcommon.h:67:1: note: 'DWRITE_GLYPH_IMAGE_FORMATS operator|(DWRITE_GLYPH_IMAGE_FORMATS, DWRITE_GLYPH_IMAGE_FORMATS)' previously defined here
67 | DEFINE_ENUM_FLAG_OPERATORS(DWRITE_GLYPH_IMAGE_FORMATS)
| ^~~~~~~~~~~~~~~~~~~~~~~~~~
To avoid any possibility of uninitialized memory.
The exceptions are:
- where the allocation is immediately overwritten by a memcpy or struct copy.
- arrays of structs to avoid any performance impact (except when the
array is returned by the public API).
The following clipping text tests of win32/rgb24 target were visibly
failing because clipping didn't work.
* clip-text
* partial-clip-text-bottom
* partial-clip-text-left
* partial-clip-text-right
* partial-clip-text-top
_cairo_win32_gdi_compositor_glyphs sets the clip. However,
_cairo_dwrite_show_glyphs_on_surface unset it.
Fixescairo/cairo#641
The DWRITE_COLOR_GLYPH_RUN1 struct definition of the old MinGW
dwrite_3.h was invalid. To work around the problem, dw-extra.h defined
the correct struct definition and all necessary API from dwrite_3.h.
This approach needed to redefine all necessary API.
This change added DWRITE_COLOR_GLYPH_RUN1_WORKAROUND struct and use it
for IDWriteColorGlyphRunEnumerator1::GetCurrentRun.
The most top and bottom lines of glyphs were clipped in some fonts and
conditions. The glyph bounds were inflated 1px horizontally. It should
inflate vertically too.
Fixescairo/cairo#569
The win32 compositor is using _cairo_dwrite_show_glyphs_on_surface for
DWrite. It was assuming that a glyph was painted inside 3x3 of the em
square. It should take the actual glyph bounding box by using
GetAlphaTextureBounds.
Fixescairo/cairo#641
Reuse the win32 font code to create a glyph mask for a dwrite font.
Renamed a function _compute_mask in cairo-win32-font.c to
_cairo_compute_glyph_mask.
Applying a transformation matrix to a glyph path after converting
floats to fixed point numbers caused caluculation errors. Apply the
transform before the conversion.
Fixescairo/cairo#611
GetGdiCompatibleMetrics may return a glyph metrics that yields a small
nagative glyph height. But, it was calculated in unsigned integer.
And, it resulted in a very large glyph metrics.
Calculate glyph width and height in signed integer and let them
non-negative.
The previous approach using foreground colors in user fonts does not
work for gradients since the foreground color is not available at the
time of recording.
Add a new function cairo_user_scaled_font_get_foreground_source() that
can be called by the color render function to retrieve the foreground
pattern. Calling this function signals to cairo that the foreground
color is used. In this case cairo will call the render function
whenever the foreground color has changed.
GeometryRecorder class was calling _controlfp_s with MCW_PC to reset
the floating point precision to default. However, MCW_PC isn't
supported for ARM or x64 platforms. It reports an assertion failure
for them. And, Cairo isn't changing the MCW_PC setting. Removed the
calls. Also, removed `GetFixedX` and `GetFixedY` methods because they
called only `_cairo_fixed_from_double`.
Fixescairo/cairo#566
SVG fonts are returning DWRITE_GLYPH_IMAGE_FORMATS_NONE as well
as DWRITE_GLYPH_IMAGE_FORMATS_SVG in GetCurrentRun() resulting in the
outline glyph and color glyph both rendered to the same glyph image.
There may be different versions of fonts with the same name. As an
additional check, compare the 'head' table wich contains the checksum
for the font.
Also, load the DWrite tables directly to avoid the memcpy in
load_truetype_table.