Prince XML
Product  Download  Purchase  Samples  Documentation  Forum  Company
It is currently Fri Sep 03, 2010 12:18 am

All times are UTC




Post new topic Reply to topic  [ 4 posts ] 
Author Message
 Post subject: text width and vertical text with SVG
PostPosted: Wed Jan 16, 2008 9:46 pm 
Offline

Joined: Wed Jan 16, 2008 12:22 am
Posts: 9
After many laborious hours I have come up with a method of determining the approximate width/height needed for creating SVG for vertical text on the fly... I figured I'd share it with everyone else... This may not be perfect, and there may be another way, however this seems to work well for what I need.

Also, this is all written in PHP...

So to begin with I have create a file called svgfunc.php:

Code:
<?php
function get_text_width($text,$font,$fontSize){
   //I start by counting the width, giving each character a modifying value
   $count = 0;
   $count = $count + ((strlen($text) - strlen(str_replace(array("i","j","l"),"",$text)))*0.23);//ijl
   $count = $count + ((strlen($text) - strlen(str_replace(array("f"),"",$text)))*0.27);//f
   $count = $count + ((strlen($text) - strlen(str_replace(array("t","I"),"",$text)))*0.28);//tI
   $count = $count + ((strlen($text) - strlen(str_replace(array("r"),"",$text)))*0.34);//r
   $count = $count + ((strlen($text) - strlen(str_replace(array("1"),"",$text)))*0.49);//1
   $count = $count + ((strlen($text) - strlen(str_replace(array("c","k","s","v","x","y","z","J"),"",$text)))*0.5);//cksvxyzJ
   $count = $count + ((strlen($text) - strlen(str_replace(array("a","b","d","e","g","h","n","o","p","q","u","L","0","2","3","4","5","6","7","8","9"),"",$text)))*0.56);//abdeghnopquL023456789
   $count = $count + ((strlen($text) - strlen(str_replace(array("F","T","Z"),"",$text)))*0.61);//FTZ
   $count = $count + ((strlen($text) - strlen(str_replace(array("A","B","E","K","P","S","V","X","Y"),"",$text)))*0.67);//ABEKPSVXY
   $count = $count + ((strlen($text) - strlen(str_replace(array("w","C","D","H","N","R","U"),"",$text)))*0.73);//wCDHNRU
   $count = $count + ((strlen($text) - strlen(str_replace(array("G","O","Q"),"",$text)))*0.78);//GOQ
   $count = $count + ((strlen($text) - strlen(str_replace(array("m","M"),"",$text)))*0.84);//mM
   $count = $count + ((strlen($text) - strlen(str_replace("W","",$text)))*.95);//W
   $count = $count + ((strlen($text) - strlen(str_replace(" ","",$text)))*.28);//" "
   $text = str_replace(" ","",$text);//remove the " "'s
   $count = $count + (strlen(preg_replace("/[a-z0-9]/i","",$text))*0.3); //all other chrs
   
   //then I adjust the value based on the fontsize*count and the modifer based on the type of font
   return ceil(adjust_font($count*$fontSize,$font));
}
function adjust_font($textWidth,$font){
   //you will need to add additional modifiers for other fonts..
   //  start with a string containing all lower alpha, upper alpha, numbers and a space
   //  continue adjusting till it's slightly larger (2-5 pixels) than it needs to be
   
   $modifier = 1;
   $font = strtolower($font);
   switch($font){
      //no modifier for arial and sans-serif
      case 'arial':
      case 'sans-serif':
         break;
      //.92 modifer for time, serif, brushscriptstd, and californian fb
      case 'times':
      case 'serif':
      case 'brushscriptstd':
      case 'californian fb':
         $modifier = .92;
         break;
      //1.23 modifier for broadway
      case 'broadway':
         $modifier = 1.23;
         break;
   }
   return ceil($textWidth*$modifier);
}
?>


Next, I created a file called svg.php:

Code:
<?php
header("Content-type: image/svg+xml");
include( "svgfunc.php" );
$text = $_REQUEST['text'];
$fontSize = $_REQUEST['fontSize'];
$font = ($_REQUEST['font'])?$_REQUEST['font']:'Arial';
$textWidth = get_text_width($text,$font,$fontSize);
?>

<svg xmlns="http://www.w3.org/2000/svg"
   xmlns:xlink="http://www.w3.org/1999/xlink"
   version="1.1"
   baseProfile="full"
   viewBox="0 0 <?= $fontSize+1; ?> <?= $textWidth+1; ?>"
   width="<?= $fontSize+1; ?>px"
   height="<?= $textWidth+1; ?>px">
   <text x="-<?= $textWidth+1; ?>px" y="<?= ceil($fontSize*0.8); ?>px" fill="red icc-color(#CMYK, 0,100,100,0)" font-family="<?= $font; ?>" font-size="<?= $fontSize; ?>px" transform="rotate(270)">
      <?= $text; ?>
   </text>
</svg>


It expects a query string like: svg.php?text=this is a test&amp;fontSize=16$amp;font=serif

Don't forget Prince needs you to use &amp; instead of just &

Finally, I created a file called testsvg.php which has the following:

Code:
<?

$text = $_REQUEST['text'];
$fontSize = $_REQUEST['fontSize'];
$fontFamily = $_REQUEST['fontFamily'];

include( "svgfunc.php" );//I include the svgfunc.php to get the text width for the height of the svg
$height = get_text_width($text,$fontFamily,$fontSize);

//then I build the svg link
$src = "svg.php?text=".$text."&fontSize=".$fontSize."&font=".$fontFamily;
$src = str_replace(" ","%20",$src);

?>

<html>
<head></head>
<body>
<table border="1" cellspacing="0">
   <tr>
      <td style="vertical-align:bottom;">
         Hello
      </td>
      <td>
<!-- here is the embed method -->
         <embed width="<?= $fontSize+1; ?>" height="<?= $height+2; ?>" src="<?= $src; ?>"  type="image/svg+xml"></embed>
      </td>
      <td>
<!-- here is the object method -->
         <object width="<?= $fontSize+1; ?>" height="<?= $height+2; ?>" data="<?= $src; ?>" type="image/svg+xml"></object>
      </td>
      <td style="vertical-align:bottom;">
         Goodbye
      </td>
   </tr>
</table>
<br><br>
Enter some text, a font-size, and a font-family to see the dynamic SVG in action... please note that the height of the text box is currently only correctly calculated for arial/sans-serif font face... The others could also be calculated fairly easily... Currently FireFox's implementation of <a href="http://www.mozilla.org/projects/svg/status.html">SVG</a> does not support embeding other fonts.
<br><br>
<form action="testsvg.php" method="get">
Text:<input type="text" name="text" id="text" value="<?= $text; ?>"><br>
Font Size:<input type="text" name="fontSize" id="fontSize" value="<?= $fontSize; ?>"><br>
Font-Family:<input type="text" name="fontFamily" id="fontFamily" value="<?= $fontFamily; ?>"> (Arial (sans-serif), Times (serif), Fantasy, Monospace, Bakersville (only IE), & Symbol)<br>
<input type="submit">
</form>
</body>
</html>



Remember, this is still a work in progress... Hope this helps someone out!!! If you have a better method, please share it!

Jake


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jan 18, 2008 7:23 am 
Offline

Joined: Tue Jun 07, 2005 11:03 pm
Posts: 2625
Location: Melbourne
That's very clever! :)

So how could Prince make this process easier for you? Or would you still need to do this for browsers?


Top
 Profile  
 
 Post subject:
PostPosted: Mon Apr 07, 2008 10:32 am 
Offline

Joined: Mon Apr 07, 2008 10:01 am
Posts: 7
Instead of calculating all the font size stuff yourself, why not use the PHP function imagettfbbox (Description: Give the bounding box of a text using TrueType fonts). Of course, if the font you have isn't true type or open type then you can't use it.

Otherwise, looks good. Instead of your solution I was dynamically generating vertical images using PHP. SVG is the way of the future though!


Top
 Profile  
 
 Post subject:
PostPosted: Wed May 07, 2008 4:45 pm 
Offline

Joined: Mon Apr 07, 2008 2:09 pm
Posts: 10
Is there a way to do this with xsl? Say need to have something such as the line below that I need to display vertically. The "some strings" are of variable length. How do I determine the location of the image and the size of the whole svg if all I have to work with is xsl?

some string (an image) some string


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 4 posts ] 

All times are UTC


Who is online

Users browsing this forum: No registered users and 0 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group