# GDI+ This library provides the implementation of the [WIN32 GDI+ API](https://docs.microsoft.com/en-us/windows/win32/gdiplus/-gdiplus-class-gdi-reference), as a Wrapper of the [Low Level API](low-level-api/nanovg-api/) via [NanoVG](https://github.com/memononen/nanovg). In order to use GDI+ on WebAssembly gauges, it is required to include the static {{< glossterm >}}wasm{{< /glossterm >}} library, and in the project settings, please include the following information: - Additional include directories: `Additional Include Directories += $(MSFS2024_SDK)WASM\include\gdiplus` - Additional library directories: `Additional Library Directories += $(MSFS2024_SDK)WASM\lib` - Additional dependencies: - `Additional Dependencies (RELEASE) += gdiplus.a` - `Additional Dependencies (DEBUG) += gdiplus_debug.a` - In the source files using GDI+, include the `GdiPlus.h` header: `#include `     ### Differences With WIN32 GDI+ This is a re-implementation of the GDI+ API using the underlying Low-Level Graphic API provided by Microsoft Flight Simulator 2024. Given constraints in the graphic back-end, some method signatures have been changed, and some functionality is currently unavailable. In addition, some low priority functionality has not yet been implemented (such as pen caps). {{< callout context="note" title="NOTE" icon="outline/bulb" >}} These differences might be reduced in future releases of the SDK {{< /callout >}}   The main differences that must be considered when using GDI+ for WASM are: 1. The creation of a `GdiPlus::Graphics` object requires a `FScontext` (instead of an `HDC`). 2. Some graphical elements need to be associated to a `GdiPlus::Bitmap`. They should be initialized before being used, ideally on `PANEL_SERVICE_POST_INSTALL`. 3. Frames need to be explicitly started using `GdiPlus::Graphics::StartFrame()`, passing the resolution information provided by `(sGaugeDrawData*)pData`. 4. Frames need to be explicitly flushed using `GdiPlus::Graphics::Flush()`. 5. `GdiPlus::Graphics` (and other context-dependent objects) need to be destroyed before the graphical context is released, either before or during `PANEL_SERVICE_PRE_KILL`.   Below is an example snippet of code so you can get a better picture of what is going on: ``` wasm GdiPlus::Graphics* gfx; GdiPlus::Bitmap* bitmap; extern "C" { MSFS_CALLBACK bool my_gauge_callback(FsContext fsctx, int service_id, void* pData) { switch (service_id) { case PANEL_SERVICE_POST_INSTALL: { ... (1) gfx = new GdiPlus::Graphics(fsctx); (2) bitmap = new GdiPlus::Bitmap(gfx,...); ... } case PANEL_SERVICE_PRE_DRAW: { (3) sGaugeDrawData* p_draw_data = (sGaugeDrawData*)pData; (3) float fSize = (float)min(p_draw_data->winWidth, p_draw_data->winHeight); (3) float pxRatio = (float)p_draw_data->fbWidth / (float)p_draw_data->winWidth; (3) gfx->StartFrame(p_draw_data->winWidth, p_draw_data->winHeight, pxRatio); ... (4) gfx->Flush(); ... } case PANEL_SERVICE_PRE_KILL: { ... (5) delete (bitmap); (5) delete (gfx); ... } } } } ```     ### Status All methods present in the GDI+ API are declared, providing support for compilation of projects for previous instances of Flight Simulator. As not all GDI+ functionality is yet supported, non-implemented methods will return `GpStatus::NotImplemented`. For more details about the implementation, please refer to [Building The Library](gdi-plus/#building).   The functionality available in the previous versions of the GDI+ wrapper is supported in the new implementation. Those functions that are not present in the official GDI+ API are considered experimental, and they might be changed or removed in the future.   #### Missing Image Functionality - `GdiPlus::Bitmap` requires a graphical context on construction. ``` wasm GdiPlus::Graphics* gfx = new Graphics(fsctx); ... bitmap = new Bitmap(gfx,L"{path-to-file-in-vfs.png}" ``` - `GdiPlus::Bitmap` can ***either*** be loaded from a file or manipulated per pixel, ***but not both***. - `GdiPlus::Image` does not support draw-to-image. - `GdiPlus::MetaFile` is not supported.   #### Missing Drawing Functionality - `GdiPlus::Pen` only supports simple caps. - `GdiPlus::Brush` supports `SolidBrush` and `HatchBrush`; neither `TextureBrush` nor `GradientBrush` are supported at this moment.   #### Missing Text Functionality - Fonts can only be created by file name: ``` wasm font = new Font(L"{alias}", L".ttf", {size-in-px}, {unused}); ``` - `GdiPlus::Graphics::DrawString()` is restricted to **UTF8** strings (even when the method signature accepts `WCHAR` strings). - `GdiPlus::Font` provides minimal functionality, neither `GdiPlus::FontFamily` nor `GdiPlus::FontCollection` are supported at this moment.     ### Building The Library The source files for the GDI+ library are also provided in `$(MSFS_SDK)WASM\projects\gdiplus`. The project can be included to the Visual Studio solution used to build WebAssembly gauges. Using this approach allows the navigation of symbols and their debug. Modifying and rebuilding this project will update the GDI+ contents present in `$(MSFS_SDK)WASM\include` and `$(MSFS_SDK)WASM\lib`. **Note that the modifications to the GDI+ library will be overridden by future SDK installs**.   #### Build Configuration using Preprocessor Definitions Some debug options can be enabled by using preprocessor definitions: - `DEBUG_CLIP_MASK`: Displays the contour of clipping masks. - `DEBUG_TEXT`: Displays bounding boxes and pivot of text rectangles. - `DEBUG_IMAGE_CONTOUR`: Displays bounding boxes and clipping regions for images and patterns. - `GDIFLAT_SAFE`: Checks for valid parameters on each call to the FLAT API. This is safer, but slower and it can hide parameter issues. This definition is present by default on RELEASE builds, and not on DEBUG.     ### Extra Links The following links are provided to give you extra context as well as additional tools when working with the WASM Module.   - [MinGW GDI+ headers](https://github.com/Alexpux/mingw-w64/tree/master/mingw-w64-headers/include/gdiplus) - [LibGdiplus GDI+ Flat implementation](https://github.com/mono/libgdiplus/tree/master/src) - [NanoVG](https://github.com/memononen/nanovg) - [NanoVG API](low-level-api/nanovg-api/)