diff --git a/api/c/indigo-renderer/src/indigo_render2d.cpp b/api/c/indigo-renderer/src/indigo_render2d.cpp index 6156620b11..01e333955a 100644 --- a/api/c/indigo-renderer/src/indigo_render2d.cpp +++ b/api/c/indigo-renderer/src/indigo_render2d.cpp @@ -690,6 +690,7 @@ void IndigoRenderer::setOptionsHandlers() mgr->setOptionHandlerString("render-output-format", indigoRenderSetOutputFormat, indigoRenderGetOutputFormat); mgr->setOptionHandlerString("render-comment", SETTER_GETTER_STR_OPTION(rp.cnvOpt.comment)); + mgr->setOptionHandlerString("render-font-family", SETTER_GETTER_STR_OPTION(rp.cnvOpt.fontFamily)); mgr->setOptionHandlerString("render-comment-position", indigoRenderSetCommentPosition, indigoRenderGetCommentPosition); mgr->setOptionHandlerString("render-stereo-style", indigoRenderSetStereoStyle, indigoRenderGetStereoStyle); mgr->setOptionHandlerString("render-catalysts-placement", indigoRenderSetCatalystsPlacement, indigoRenderGetCatalystsPlacement); diff --git a/api/c/tests/unit/tests/renderer.cpp b/api/c/tests/unit/tests/renderer.cpp index b07ecbc9d8..33e6344651 100644 --- a/api/c/tests/unit/tests/renderer.cpp +++ b/api/c/tests/unit/tests/renderer.cpp @@ -72,6 +72,31 @@ class IndigoApiRendererTest : public IndigoApiTest indigoRendererDispose(_session); indigoReleaseSessionId(_session); } + + std::string renderWithFontFamily(const char* format, const char* font_family = nullptr) + { + indigoResetOptions(); + indigoSetOption("render-comment", "Font comment"); + indigoSetOption("render-output-format", format); + indigoSetOptionXY("render-image-size", 300, 200); + if (font_family != nullptr) + indigoSetOption("render-font-family", font_family); + + int m = indigoLoadMoleculeFromString("C"); + int buf = indigoWriteBuffer(); + char* raw = nullptr; + int size = 0; + + indigoRender(m, buf); + indigoToBuffer(buf, &raw, &size); + + std::string output(raw, size); + + indigoFree(buf); + indigoFree(m); + + return output; + } }; TEST_F(IndigoApiRendererTest, layout_rings) @@ -132,3 +157,23 @@ TEST_F(IndigoApiRendererTest, render_superatoms) thread.join(); } } + +TEST_F(IndigoApiRendererTest, svg_font_family_option_changes_rendering) +{ + auto default_svg = renderWithFontFamily("svg"); + auto arial_svg = renderWithFontFamily("svg", "Arial"); + auto courier_svg = renderWithFontFamily("svg", "Courier New"); + + ASSERT_EQ(default_svg, arial_svg); + ASSERT_NE(default_svg, courier_svg); +} + +TEST_F(IndigoApiRendererTest, png_font_family_option_changes_rendering) +{ + auto default_png = renderWithFontFamily("png"); + auto arial_png = renderWithFontFamily("png", "Arial"); + auto courier_png = renderWithFontFamily("png", "Courier New"); + + ASSERT_EQ(default_png, arial_png); + ASSERT_NE(default_png, courier_png); +} diff --git a/core/render2d/render_common.h b/core/render2d/render_common.h index 8cecc73abd..1cdd549c4e 100644 --- a/core/render2d/render_common.h +++ b/core/render2d/render_common.h @@ -527,6 +527,7 @@ namespace indigo int commentOffset; int titleOffset; Array comment; + Array fontFamily; Array titleProp; COMMENT_POS commentPos; MultilineTextLayout commentAlign; diff --git a/core/render2d/render_context.h b/core/render2d/render_context.h index 3e93aba952..450520819a 100644 --- a/core/render2d/render_context.h +++ b/core/render2d/render_context.h @@ -46,7 +46,7 @@ namespace indigo void checkPathNonEmpty() const; - RenderContext(const RenderOptions& opt, float relativeThickness, float bondLineWidthFactor); + RenderContext(const RenderOptions& opt, const CanvasOptions& cnvOpt, float relativeThickness, float bondLineWidthFactor); void setDefaultScale(float scale); void setHDC(PVOID hdc); int getMaxPageSize() const; @@ -217,6 +217,7 @@ namespace indigo cairo_scaled_font_t* _scaled_fonts[FONT_SIZE_COUNT * 2]; bool metafileFontsToCurves; + bool _hasCustomFontFamily; cairo_t* _cr; cairo_surface_t* _surface; void* _meta_hdc; diff --git a/core/render2d/src/render_common.cpp b/core/render2d/src/render_common.cpp index 061e15d58b..30936dd47e 100644 --- a/core/render2d/src/render_common.cpp +++ b/core/render2d/src/render_common.cpp @@ -414,6 +414,7 @@ void CanvasOptions::clear() titleOffset = 0; gridColumnNumber = 1; comment.clear(); + fontFamily.clear(); titleProp.clear(); titleProp.appendString("^NAME", true); outputSheetWidth = -1; diff --git a/core/render2d/src/render_context.cpp b/core/render2d/src/render_context.cpp index ce69873369..754d06757c 100644 --- a/core/render2d/src/render_context.cpp +++ b/core/render2d/src/render_context.cpp @@ -119,9 +119,9 @@ void RenderContext::storeAndDestroyMetafile(bool discard) CP_DEF(RenderContext); -RenderContext::RenderContext(const RenderOptions& ropt, float relativeThickness, float bondLineWidthFactor) - : CP_INIT, TL_CP_GET(_fontfamily), TL_CP_GET(transforms), metafileFontsToCurves(false), _cr(NULL), _surface(NULL), _meta_hdc(NULL), opt(ropt), - _pattern(NULL), _settings() +RenderContext::RenderContext(const RenderOptions& ropt, const CanvasOptions& cnvOpt, float relativeThickness, float bondLineWidthFactor) + : CP_INIT, TL_CP_GET(_fontfamily), TL_CP_GET(transforms), metafileFontsToCurves(false), _hasCustomFontFamily(cnvOpt.fontFamily.size() > 0), + _cr(NULL), _surface(NULL), _meta_hdc(NULL), opt(ropt), _pattern(NULL), _settings() { AcsOptions acs; if (ropt.fontSize > 0) @@ -138,7 +138,10 @@ RenderContext::RenderContext(const RenderOptions& ropt, float relativeThickness, acs.bondSpacing = ropt.bondSpacing; _settings.init(relativeThickness, bondLineWidthFactor, &acs); - bprintf(_fontfamily, "Arial"); + if (cnvOpt.fontFamily.size() > 0) + bprintf(_fontfamily, "%s", cnvOpt.fontFamily.ptr()); + else + bprintf(_fontfamily, "Arial"); bbmin.x = bbmin.y = 1; bbmax.x = bbmax.y = -1; _defaultScale = 0.0f; diff --git a/core/render2d/src/render_fonts.cpp b/core/render2d/src/render_fonts.cpp index ba706f0fe2..7d46a39079 100644 --- a/core/render2d/src/render_fonts.cpp +++ b/core/render2d/src/render_fonts.cpp @@ -118,6 +118,16 @@ void RenderContext::fontsSetFont(const TextItem& ti) { std::lock_guard _lock(_cairo_mutex); + if (_hasCustomFontFamily) + { + cairo_select_font_face(_cr, _fontfamily.ptr(), ti.italic ? CAIRO_FONT_SLANT_ITALIC : CAIRO_FONT_SLANT_NORMAL, + ti.bold ? CAIRO_FONT_WEIGHT_BOLD : CAIRO_FONT_WEIGHT_NORMAL); + cairoCheckStatus(); + cairo_set_font_size(_cr, ti.size > 0 ? ti.size : fontGetSize(ti.fontsize)); + cairoCheckStatus(); + return; + } + cairo_font_face_t* _cairo_face = _font_face_manager.selectCairoFontFace(ti); cairoCheckStatus(); diff --git a/core/render2d/src/render_params.cpp b/core/render2d/src/render_params.cpp index 1cdfcb4682..9c91bb7cbb 100644 --- a/core/render2d/src/render_params.cpp +++ b/core/render2d/src/render_params.cpp @@ -193,7 +193,7 @@ void RenderParamInterface::render(RenderParams& params) if (params.rmode == RENDER_NONE) throw Error("No object to render specified"); - RenderContext rc(params.rOpt, params.relativeThickness, params.bondLineWidthFactor); + RenderContext rc(params.rOpt, params.cnvOpt, params.relativeThickness, params.bondLineWidthFactor); int bondLength_px = (int)(params.rOpt.bond_length_px > EPSILON ? params.rOpt.bond_length_px : LayoutOptions::DEFAULT_BOND_LENGTH_PX);