diff --git a/include/aribcaption/renderer.h b/include/aribcaption/renderer.h index da04ba3..8595951 100644 --- a/include/aribcaption/renderer.h +++ b/include/aribcaption/renderer.h @@ -317,7 +317,8 @@ ARIBCC_API bool aribcc_renderer_set_language_specific_font_family(aribcc_rendere * If the font has Std, Pr5, Pr6, Pr7, or Pro in the name, it is likely to be compliant. * Fonts such as IBM Plex Sans JP, Morisawa BIZ UDGothic, Morisawa BIZ UDMincho, * Yu Gothic, Yu Mincho, and Meiryo are also supported. - * It is enabled by default when using the FreeType renderer, but has no effect when using other renderers. + * It is only effective when using the FreeType or DirectWrite renderer, + * and is enabled by default for these renderers. * * @param decoder @aribcc_decoder_t * @param replace If true is specified, Captions that use halfwidth kana, halfwidth symbol and diff --git a/include/aribcaption/renderer.hpp b/include/aribcaption/renderer.hpp index 1b75b3a..0e717d8 100644 --- a/include/aribcaption/renderer.hpp +++ b/include/aribcaption/renderer.hpp @@ -252,7 +252,8 @@ class Renderer { * If the font has Std, Pr5, Pr6, Pr7, or Pro in the name, it is likely to be compliant. * Fonts such as IBM Plex Sans JP, Morisawa BIZ UDGothic, Morisawa BIZ UDMincho, * Yu Gothic, Yu Mincho, and Meiryo are also supported. - * It is enabled by default when using the FreeType renderer, but has no effect when using other renderers. + * It is only effective when using the FreeType or DirectWrite renderer, + * and is enabled by default for these renderers. * * @param replace If true is specified, Captions that use halfwidth kana, halfwidth symbol and * halfwidth alphanumeric characters will look better. diff --git a/src/renderer/text_renderer_directwrite.cpp b/src/renderer/text_renderer_directwrite.cpp index 0241c11..ce94f1a 100644 --- a/src/renderer/text_renderer_directwrite.cpp +++ b/src/renderer/text_renderer_directwrite.cpp @@ -275,6 +275,10 @@ bool TextRendererDirectWrite::SetFontFamily(const std::vector& font return false; } +void TextRendererDirectWrite::SetReplaceMSZHalfWidthGlyph(bool replace) { + replace_msz_halfwidth_glyph_ = replace; +} + struct TextRenderContextPrivateDirectWrite : public TextRenderContext::ContextPrivate { public: TextRenderContextPrivateDirectWrite() = default; @@ -467,6 +471,31 @@ auto TextRendererDirectWrite::DrawChar(TextRenderContext& render_ctx, int target return TextRenderStatus::kOtherError; } + // Check if the font has a half width glyph for this character. + if (replace_msz_halfwidth_glyph_ && is_requesting_halfwidth) { + ComPtr typography; + DWRITE_TEXT_METRICS full_width_text_metrics = metrics; + DWRITE_FONT_FEATURE feature = {DWRITE_FONT_FEATURE_TAG_HALF_WIDTH, 1}; + if (SUCCEEDED(dwrite_factory_->CreateTypography(&typography)) && + SUCCEEDED(typography->AddFontFeature(feature)) && + SUCCEEDED(text_layout->SetTypography(typography.Get(), DWRITE_TEXT_RANGE{0, 1}))) { + hr = text_layout->GetMetrics(&metrics); + if (FAILED(hr)) { + log_->e("TextRendererDirectWrite: GetMetrics() failed"); + return TextRenderStatus::kOtherError; + } + // Avoid scaling because it has a half width glyph. + if (full_width_text_metrics.width / 2 == metrics.width) { + char_width = char_height; + horizontal_scale = 1.0f; + } else { + if (SUCCEEDED(dwrite_factory_->CreateTypography(&typography))) { + text_layout->SetTypography(typography.Get(), DWRITE_TEXT_RANGE{0, 1}); + } + } + } + } + // Calculate charbox size int charbox_width = static_cast(ceilf((metrics.width + (float)margin_x * 2) * horizontal_scale)); int charbox_height = static_cast(ceilf(metrics.height)) + margin_y * 2; diff --git a/src/renderer/text_renderer_directwrite.hpp b/src/renderer/text_renderer_directwrite.hpp index 180e67f..f8215a9 100644 --- a/src/renderer/text_renderer_directwrite.hpp +++ b/src/renderer/text_renderer_directwrite.hpp @@ -41,6 +41,7 @@ class TextRendererDirectWrite : public TextRenderer { bool Initialize() override; void SetLanguage(uint32_t iso6392_language_code) override; bool SetFontFamily(const std::vector& font_family) override; + void SetReplaceMSZHalfWidthGlyph(bool replace) override; auto BeginDraw(Bitmap& target_bmp) -> TextRenderContext override; void EndDraw(TextRenderContext& context) override; auto DrawChar(TextRenderContext& render_ctx, int x, int y, @@ -82,6 +83,8 @@ class TextRendererDirectWrite : public TextRenderer { ComPtr main_text_format_; ComPtr fallback_text_format_; + + bool replace_msz_halfwidth_glyph_ = true; }; } // namespace aribcaption