summaryrefslogtreecommitdiff
path: root/src/svg/ftsvg.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/svg/ftsvg.c')
-rw-r--r--src/svg/ftsvg.c208
1 files changed, 208 insertions, 0 deletions
diff --git a/src/svg/ftsvg.c b/src/svg/ftsvg.c
new file mode 100644
index 000000000..901f3e82e
--- /dev/null
+++ b/src/svg/ftsvg.c
@@ -0,0 +1,208 @@
+/****************************************************************************
+ *
+ * ftsvg.c
+ *
+ * The FreeType svg renderer interface (body).
+ *
+ * Copyright (C) 1996-2019 by
+ * David Turner, Robert Wilhelm, Werner Lemberg and Moazin Khatti.
+ *
+ * This file is part of the FreeType project, and may only be used,
+ * modified, and distributed under the terms of the FreeType project
+ * license, LICENSE.TXT. By continuing to use, modify, or distribute
+ * this file you indicate that you have read the license and
+ * understand and accept it fully.
+ *
+ */
+
+#include <ft2build.h>
+#include FT_INTERNAL_DEBUG_H
+#include FT_SERVICE_PROPERTIES_H
+#include FT_OTSVG_H
+#include FT_INTERNAL_SVG_INTERFACE_H
+#include FT_BBOX_H
+
+#include <stdio.h>
+
+#include "ftsvg.h"
+
+#undef FT_COMPONENT
+#define FT_COMPONENT otsvg
+
+#ifdef FT_CONFIG_OPTION_SVG
+
+ /* ft_svg_init */
+ static FT_Error
+ ft_svg_init( SVG_Renderer svg_module )
+ {
+ FT_Error error = FT_Err_Ok;
+ svg_module->loaded = FALSE;
+ svg_module->hooks_set = FALSE;
+ return error;
+ }
+
+ static void
+ ft_svg_done( SVG_Renderer svg_module )
+ {
+ FT_Library library = svg_module->root.root.library;
+ if ( svg_module->loaded == TRUE &&
+ svg_module->hooks_set == TRUE )
+ svg_module->hooks.free_svg( library );
+ svg_module->loaded = FALSE;
+ }
+
+ static FT_Error
+ ft_svg_preset_slot( FT_Module module,
+ FT_GlyphSlot slot,
+ FT_Bool cache )
+ {
+ SVG_Renderer svg_renderer = (SVG_Renderer)module;
+ SVG_RendererHooks hooks = svg_renderer->hooks;
+
+ if ( svg_renderer->hooks_set == FALSE )
+ {
+ FT_TRACE1(( "Hooks are NOT set. Can't render OT-SVG glyphs\n" ));
+ return FT_THROW( Missing_SVG_Hooks );
+ }
+
+ return hooks.preset_slot( slot, cache );
+ }
+
+ static FT_Error
+ ft_svg_render( FT_Renderer renderer,
+ FT_GlyphSlot slot,
+ FT_Render_Mode mode,
+ const FT_Vector* origin )
+ {
+ SVG_Renderer svg_renderer = (SVG_Renderer)renderer;
+ FT_Library library = renderer->root.library;
+ FT_Memory memory = library->memory;
+ FT_Error error;
+ FT_ULong size_image_buffer;
+
+ SVG_RendererHooks hooks = svg_renderer->hooks;
+
+ if ( svg_renderer->hooks_set == FALSE )
+ {
+ FT_TRACE1(( "Hooks are NOT set. Can't render OT-SVG glyphs\n" ));
+ return FT_THROW( Missing_SVG_Hooks );
+ }
+
+ if ( svg_renderer->loaded == FALSE )
+ {
+ FT_TRACE3(( "ft_svg_render: first rendering, calling init hook\n" ));
+ error = hooks.init_svg( library );
+ svg_renderer->loaded = TRUE;
+ }
+
+ ft_svg_preset_slot( (FT_Module)renderer, slot, TRUE);
+ size_image_buffer = slot->bitmap.pitch * slot->bitmap.rows;
+ FT_MEM_ALLOC( slot->bitmap.buffer, size_image_buffer);
+ if ( error )
+ return error;
+
+ return hooks.render_svg( slot );
+ }
+
+ static const SVG_Interface svg_interface = {
+ (Preset_Bitmap_Func)ft_svg_preset_slot
+ };
+
+ static FT_Error
+ ft_svg_property_set( FT_Module module,
+ const char* property_name,
+ const void* value,
+ FT_Bool value_is_string )
+ {
+ FT_Error error = FT_Err_Ok;
+ SVG_Renderer renderer = (SVG_Renderer)module;
+
+ if ( !ft_strcmp( property_name, "svg_hooks" ) )
+ {
+ SVG_RendererHooks* hooks = (SVG_RendererHooks*)value;
+ renderer->hooks = *hooks;
+ renderer->hooks_set = TRUE;
+ }
+ else
+ {
+ error = FT_THROW( Missing_Property );
+ }
+ return error;
+ }
+
+ static FT_Error
+ ft_svg_property_get( FT_Module module,
+ const char* property_name,
+ const void* value )
+ {
+ FT_Error error = FT_Err_Ok;
+ SVG_Renderer renderer = (SVG_Renderer)module;
+
+ if ( !ft_strcmp( property_name, "svg_hooks" ) )
+ {
+ SVG_RendererHooks* hooks = (SVG_RendererHooks*)value;
+ *hooks = renderer->hooks;
+ }
+ else
+ {
+ error = FT_THROW( Missing_Property );
+ }
+ return error;
+ }
+
+ FT_DEFINE_SERVICE_PROPERTIESREC(
+ ft_svg_service_properties,
+
+ (FT_Properties_SetFunc)ft_svg_property_set, /* set_property */
+ (FT_Properties_GetFunc)ft_svg_property_get /* get_property */
+ )
+
+ FT_DEFINE_SERVICEDESCREC1(
+ ft_svg_services,
+ FT_SERVICE_ID_PROPERTIES, &ft_svg_service_properties )
+
+
+ FT_CALLBACK_DEF( FT_Module_Interface )
+ ft_svg_get_interface( FT_Module module,
+ const char* ft_svg_interface )
+ {
+ FT_Module_Interface result;
+
+
+ result = ft_service_list_lookup( ft_svg_services, ft_svg_interface );
+ if ( result )
+ return result;
+ return 0;
+ }
+
+#endif
+
+#ifdef FT_CONFIG_OPTION_SVG
+#define PUT_SVG_MODULE( a ) a
+#define SVG_GLYPH_FORMAT FT_GLYPH_FORMAT_SVG
+#else
+#define PUT_SVG_MODULE( a ) NULL
+#define SVG_GLYPH_FORMAT FT_GLYPH_FORMAT_NONE
+#endif
+
+
+ FT_DEFINE_RENDERER(
+ ft_svg_renderer_class,
+
+ FT_MODULE_RENDERER,
+ sizeof( SVG_RendererRec ),
+
+ "ot-svg",
+ 0x10000L,
+ 0x20000L,
+ (const void*)&svg_interface, /* module specific interface */
+ (FT_Module_Constructor)PUT_SVG_MODULE( ft_svg_init ), /* module_init */
+ (FT_Module_Destructor)PUT_SVG_MODULE( ft_svg_done ), /* module_done */
+ PUT_SVG_MODULE( ft_svg_get_interface ), /* get_interface */
+ SVG_GLYPH_FORMAT,
+ (FT_Renderer_RenderFunc)PUT_SVG_MODULE( ft_svg_render ),
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ )