This PR adds conhost support for downloadable soft fonts - also known as dynamically redefinable character sets (DRCS) - using the `DECDLD` escape sequence. These fonts are typically designed to work on a specific terminal model, and each model tends to have a different character cell size. So in order to support as many models as possible, the code attempts to detect the original target size of the font, and then scale the glyphs to fit our current cell size. Once a font has been downloaded to the terminal, it can be designated in the same way you would a standard character set, using an `SCS` escape sequence. The identification string for the set is defined by the `DECDLD` sequence. Internally we map the characters in this set to code points `U+EF20` to `U+EF7F` in the Unicode private use are (PUA). Then in the renderer, any characters in that range are split off into separate runs, which get painted with a special font. The font itself is dynamically generated as an in-memory resource, constructed from the downloaded character bitmaps which have been scaled to the appropriate size. If no soft fonts are in use, then no mapping of the PUA code points will take place, so this shouldn't interfere with anyone using those code points for something else, as along as they aren't also trying to use soft fonts. I also tried to pick a PUA range that hadn't already been snatched up by Nerd Fonts, but if we do receive reports of a conflict, it's easy enough to change. ## Validation Steps Performed I added an adapter test that runs through a bunch of parameter variations for the `DECDLD` sequence, to make sure we're correctly detecting the font sizes for most of the known DEC terminal models. I've also tested manually on a wide range of existing fonts, of varying dimensions, and from multiple sources, and made sure they all worked reasonably well. Closes #9164
71 lines
2.6 KiB
C++
71 lines
2.6 KiB
C++
/*++
|
|
Copyright (c) Microsoft Corporation
|
|
Licensed under the MIT license.
|
|
|
|
Module Name:
|
|
- XtermEngine.hpp
|
|
|
|
Abstract:
|
|
- This is the definition of the VT specific implementation of the renderer.
|
|
This is the xterm implementation, which supports advanced sequences such as
|
|
inserting and deleting lines, but only 16 colors.
|
|
|
|
This engine supports both xterm and xterm-ascii VT modes.
|
|
The difference being that xterm-ascii will render any characters above 0x7f
|
|
as '?', in order to support older legacy tools.
|
|
|
|
Author(s):
|
|
- Mike Griese (migrie) 01-Sept-2017
|
|
--*/
|
|
|
|
#pragma once
|
|
|
|
#include "vtrenderer.hpp"
|
|
|
|
namespace Microsoft::Console::Render
|
|
{
|
|
class XtermEngine : public VtEngine
|
|
{
|
|
public:
|
|
XtermEngine(_In_ wil::unique_hfile hPipe,
|
|
const Microsoft::Console::Types::Viewport initialViewport,
|
|
const bool fUseAsciiOnly);
|
|
|
|
virtual ~XtermEngine() override = default;
|
|
|
|
[[nodiscard]] HRESULT StartPaint() noexcept override;
|
|
[[nodiscard]] HRESULT EndPaint() noexcept override;
|
|
|
|
[[nodiscard]] HRESULT PaintCursor(const CursorOptions& options) noexcept override;
|
|
|
|
[[nodiscard]] virtual HRESULT UpdateDrawingBrushes(const TextAttribute& textAttributes,
|
|
const gsl::not_null<IRenderData*> pData,
|
|
const bool usingSoftFont,
|
|
const bool isSettingDefaultBrushes) noexcept override;
|
|
[[nodiscard]] HRESULT PaintBufferLine(gsl::span<const Cluster> const clusters,
|
|
const COORD coord,
|
|
const bool trimLeft,
|
|
const bool lineWrapped) noexcept override;
|
|
[[nodiscard]] HRESULT ScrollFrame() noexcept override;
|
|
|
|
[[nodiscard]] HRESULT InvalidateScroll(const COORD* const pcoordDelta) noexcept override;
|
|
|
|
[[nodiscard]] HRESULT WriteTerminalW(const std::wstring_view str) noexcept override;
|
|
|
|
protected:
|
|
const bool _fUseAsciiOnly;
|
|
bool _needToDisableCursor;
|
|
bool _lastCursorIsVisible;
|
|
bool _nextCursorIsVisible;
|
|
|
|
[[nodiscard]] HRESULT _MoveCursor(const COORD coord) noexcept override;
|
|
|
|
[[nodiscard]] HRESULT _DoUpdateTitle(const std::wstring_view newTitle) noexcept override;
|
|
|
|
#ifdef UNIT_TESTING
|
|
friend class VtRendererTest;
|
|
friend class ConptyOutputTests;
|
|
#endif
|
|
};
|
|
}
|