Jump to content

We need a plugin: font to SVG path


rooofl
 Share

Recommended Posts

Hi!

We are Velvetyne Type Foundry, since 2010, we’ve designing and distributing free and open source typefaces. We are a non-profit organization. We are quite famous in the world of type design and open source design.

We are currently working on a new website. We are focused on performances, and we want to show our fonts as SVG and not webfonts on our home page. Our website is currently using Processwire, and we want to stick to it because it’s amazing. I (author of this post) will take care of most of the development.

We need a plugin that is able to generate an SVG path from a font file (present on the server), and a text. This script already does that pretty well and I think it can be a strong base for the font-to-SVG operation. We just want the admin page to be very user-friendly, taking care of the call to the font to SVG script and show its output.

I wonder if anyone is able to do such a plugin an how much it can cost. Let me know if you can be interested.

  • Like 7
Link to comment
Share on other sites

I don't know if anyone pm'd you already but it can be quite simple if you only need to generate a static svg from a text input. I found this library https://github.com/kartsims/easysvg which would allow you to do it all server-wise if you have .svg font files at hand.

My approach would be to have a file input for the font file, a text input for the text you want to generate the svg from, a textarea (closed by default and non-editable) to hold the svg code, and something like https://processwire.com/modules/inputfield-runtime-only/ to echo the textarea's content (the svg) as a preview.

Basically a hook in `ready.php`:

require "/path/to/easySVG.php";

wire()->addHookBefore("Pages::saveReady", function(HookEvent $event) {
	/** @var Page $page */
	$page = $event->arguments(0);
	if($page->template->name !== "font") return; // or whatever
	
	if(!$page->fontfile && !$page->text) return; // file and text inputs

	// copy/pasting from easySVG example
	$svg = new EasySVG();
	$svg->setFontSVG($page->fontfile->url);
	$svg->setFontSize(100);
	$svg->setFontColor('#000000');
	$svg->setLineHeight(1.2);
	$svg->setLetterSpacing(.1);
	$svg->setUseKerning(true);
	$svg->addText($page->text);
	list($textWidth, $textHeight) = $svg->textDimensions($page->text);
	$svg->addAttribute("width", $textWidth."px");
	$svg->addAttribute("height", $textHeight."px");
	$page->svgcode = $svg->asXML(); // textarea input

	$event->arguments(0, $page);
});

And in your `svgpreview` field/file (check RuntimeOnly doc) or template file:

echo $page->getUnformatted("svgcode");

(I used getUnformatted in case there are textformatters but it would best if there's none in the field's settings)

It's not tested and made on top of my head but I think this might work.

(nice to see Velvetyne here btw, I like your work and a good friend of mine made La Savate ?)

  • Like 6
  • Thanks 1
Link to comment
Share on other sites

  • 3 weeks later...

After some tests, following your recommendations @monollonom, I face this error:

 Warning: XMLReader::open(): Unable to open source data in /home/…/www/site/templates/lib/EasySVG.php on line 161

It appears the path of `$svg->setFontSVG($fonturl.".svg");` is wrong, or at least not accessible by XMLReader. I checked: the file is readable. I also tested setFontSVG on a template file, it worked (can access to the SVG font and display the generated SVG). Finally, I tested with a static SVG font file to avoid the for loop, but it wasn’t able to open it neither.

Here is my code in ready.php:

<?php

require './templates/lib/EasySVG.php';

wire()->addHookBefore("Pages::saveReady", function(HookEvent $event) {
	/** @var Page $page */
	$page = $event->arguments(0);
	if($page->template->name !== "font") return; // or whatever
	
	if(!$page->webfont_archive && !$page->text) return; // file and text inputs

      $archivePath = $page->webfont_archive->path;
      $archiveUrl = $page->webfont_archive->url;
      $files = glob($archivePath . '*.{svg}', GLOB_BRACE);
      $len = count($files);

      for ($i = 0; $i < $len; $i++) {
		
		$fontpath = $files[$i];
        $fontpath = substr($fontpath, strlen(wire()->config->urls->root));
        $fontname = basename($fontpath, ".svg");
        $fonturl = $archiveUrl.$fontname;
		echo $fonturl.".svg";
		$svg = new EasySVG();

		$svg->setFontSVG($fonturl.".svg");
		$svg->setFontSize(100);
		$svg->setFontColor('#000000');
		$svg->setLineHeight(1.2);
		$svg->setLetterSpacing(.1);
		$svg->setUseKerning(true);
		$svg->addText("demo text");
		list($textWidth, $textHeight) = $svg->textDimensions("demo text");
		$svg->addAttribute("width", $textWidth."px");
		$svg->addAttribute("height", $textHeight."px");
		// $page->svg_text = $svg->asXML(); // textarea input
		$page->svg_text = "test"; // textarea input
	
		$event->arguments(0, $page);
  }

});

Any help welcome!

Link to comment
Share on other sites

Could you share a bit more about your setup ? Is your file input set to receive several files ?

I don't really see why you're using glob when you could maybe just use:

if(!$page->webfont_archive->count() && !$page->text) return; // we're assuming webfont_archive is set to return a PageFiles and not a single PageFile

foreach($page->webfont_archive->find("ext=svg") as $svgFont) {
	$svg = new EasySVG();
	$svg->setFontSVG($svgFont->url); // try ->httpUrl or ->filename if not working
	/* ... */
}

But again it might depend on your setup ?

  • Like 1
Link to comment
Share on other sites

 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...