Step by step Instructions to fix MacPorts 'freetype' problem

Bill Hernandez ms at mac-specialist.com
Wed Jul 9 21:03:59 PDT 2008


Ryan and Chris Janton posted a couple of messages that started me down  
the right path to fix 'freetype' so after a couple of days of working  
on this I thought I would post step by step instructions, along with a  
corrected really good demo of the captcha image verification. The  
original one I posted had some logic flaws that I did not find until I  
got 'freetype' fixed.

Anyway its all here, it now works great for me. Hope it's helpful to  
somedy else...

Bill Hernandez
Plano, Texas

This shows the STEP BY STEP METHOD to fix the MacPorts 'freetype'  
problem.
The 'freetype' fix allows the PHP command 'imagettftext' to work  
correctly without going bonkers, and generating the myriad of errors,  
including the one below :

The process has forked and you cannot use this CoreFoundation  
functionality safely. You MUST exec().
Break on  
__THE_PROCESS_HAS_FORKED_AND_YOU_CANNOT_USE_THIS_COREFOUNDATION_FUNCTIONALITY___YOU_MUST_EXEC__ 
() to debug.

------------------------------------
THIS FIXES THE PROBLEM :
------------------------------------

I use BBEdit as my editor of choice, so adjust this to reflect your  
editor :

------------------------------------
( 1 ) SHUTDOWN APACHE
------------------------------------
$ sudo /opt/local/apache2/bin/apachectl stop

------------------------------------
( 2 ) MAKE SURE APACHE HAS SHUTDOWN, there should only be one line as  
shown
------------------------------------
$ ps aux | grep httpd
     --->  roscoe   902   0.0  0.0   599740    388 s000  S+     
7:08PM   0:00.00 grep httpd
------------------------------------
( 3 ) find the Portfile
------------------------------------
$ sudo find /opt/local -name Portfile | grep freetype
     --->  /opt/local/var/macports/sources/rsync.macports.org/release/ 
ports/print/freetype/Portfile
------------------------------------
( 4 ) open the folder containing the Portfile
         optional step, you can drop the Portfile on top of BBEdit to  
open it, or do step ( 4 ) below
------------------------------------
$ open /opt/local/var/macports/sources/rsync.macports.org/release/ 
ports/print/freetype/
------------------------------------
( 5 ) OPEN the Portfile (skip this step if you did step ( 3 ))
------------------------------------
$ sudo open -a /Applications/BBEdit.app /opt/local/var/macports/ 
sources/rsync.macports.org/release/ports/print/freetype/Portfile
------------------------------------
( 6 ) Once the document opens, find the lines that follow :
        FIND
------------------------------------
configure.args \
     --with-old-mac-fonts

------------------------------------
( 7 ) REPLACE '--with-old-mac-fonts' WITH
        When done, save the Portfile and close it.
------------------------------------
configure.args \
     --with-fsspec=no \
     --with-fsref=no \
     --with-quickdraw-toolbox=no \
     --with-quickdraw-carbon=no \
     --with-old-mac-fonts=no

------------------------------------
( 8 ) Find which version of freetype is '(active)', it will have to be  
DE-ACTIVATED
------------------------------------
$ sudo port installed | grep freetype
     --->  freetype @2.3.5_1
     --->  freetype @2.3.7_1 (active)

------------------------------------
( 9 ) DE-ACTIVATE the version of freetype that is '(active)'
------------------------------------
$ sudo port deactivate freetype @2.3.7_1
     --->  Deactivating freetype 2.3.7_1

------------------------------------
( 10 ) UN-INSTALL the version of freetype that was '(active)', and has  
now been DE-ACTIVATED
         If there are dependencies, it will not want to uninstall  
unless it is FORCED using '-f' switch
------------------------------------
$ sudo port uninstall -f freetype @2.3.7_1
     --->  Unable to uninstall freetype 2.3.7_1, the following ports  
depend on it:
     --->  fontconfig
     --->  gd2
     --->  php5
     --->  fontconfig
     --->  php5
Warning: Uninstall forced.  Proceeding despite dependencies.
     --->  Uninstalling freetype 2.3.7_1

------------------------------------
( 11 ) CONFIGURE the version of freetype that is referred to by the  
modified 'Portfile'
------------------------------------
$ sudo port configure freetype
     --->  Fetching freetype
     --->  Verifying checksum(s) for freetype
     --->  Extracting freetype
     --->  Applying patches to freetype
     --->  Configuring freetype

------------------------------------
( 12 ) BUILD the version of freetype that is referred to by the  
modified 'Portfile'
------------------------------------
$ sudo port build freetype
     --->  Building freetype with target all

------------------------------------
( 13 ) INSTALL the version of freetype that is referred to by the  
modified 'Portfile'
         It will automatically be activated
------------------------------------
$ sudo port install -f freetype
     --->  Installing freetype 2.3.7_1
     --->  Activating freetype 2.3.7_1
     --->  Cleaning freetype

------------------------------------
( 14 ) CHECK to see if the NEW freetype is now '(active)'
------------------------------------
$ sudo port installed | grep freetype
     --->  freetype @2.3.5_1
     --->  freetype @2.3.7_1 (active)

------------------------------------
( 15 ) STARTUP APACHE
------------------------------------
$ sudo /opt/local/apache2/bin/apachectl start

------------------------------------
( 16 ) MAKE SURE APACHE IS RUNNING, there should now be several lines  
as shown
------------------------------------
$ ps aux | grep httpd
     --->  roscoe  5118   0.0  0.0   100780    716   ??  S      
7:13PM   0:00.00 /opt/local/apache2/bin/httpd -k start
     --->  roscoe  5117   0.0  0.0   100780    716   ??  S      
7:13PM   0:00.00 /opt/local/apache2/bin/httpd -k start
     --->  roscoe  5116   0.0  0.0   100780    716   ??  S      
7:13PM   0:00.00 /opt/local/apache2/bin/httpd -k start
     --->  roscoe  5115   0.0  0.0   100780    716   ??  S      
7:13PM   0:00.00 /opt/local/apache2/bin/httpd -k start
     --->  root      5114   0.0  0.0   100700    876   ??  S      
7:13PM   0:00.00 /opt/local/apache2/bin/httpd -k start
     --->  root      5111   0.0  0.3   100780   6304   ??  Ss     
7:13PM   0:00.02 /opt/local/apache2/bin/httpd -k start
     --->  roscoe  5121   0.0  0.0   599700    320 s000  R+     
7:13PM   0:00.00 grep httpd
     --->  roscoe  5119   0.0  0.0   100780    716   ??  S      
7:13PM   0:00.00 /opt/local/apache2/bin/httpd -k start

ALL DONE UPGRADING FREETYPE...


#  
----------------------------------------------------------------------------------
WORKING CAPTCHA DEMO TO TEST THE MacPorts 'freetype' problem
#  
----------------------------------------------------------------------------------

When I first ran into the 'imagettftext' problems associated with the  
MacPorts 'freetype' port, I had downloaded two different captcha demos  
from the web, but neither one worked due to logic problems, and I  
didn't catch the problems them until I got the 'freetype' issue  
resolved. Now that I had a chance to play with the demo's I fixed the  
logic problems, and this demo works very well, it is actually really  
good. PLEASE IGNORE any previous demo's I posted with the original  
email titled : 'Calls to imagettftext cause fatal error in php'.

This demo works on its own, and in conjunction with ZEND DEBUGGER now  
that 'freetype' is fixed.

#  
----------------------------------------------------------------------------------
( 1 ) This demo requires "images/noise.jpg", which can be downloaded  
from
#  
----------------------------------------------------------------------------------
http://www.reconn.us/images/noise.png

#  
----------------------------------------------------------------------------------
( 2 ) The hierarchy of folders and fonts is as follows :
#  
----------------------------------------------------------------------------------
captcha_one										// MAIN FOLDER (you create)
	image_loader.php							// actually loads the image
	inc_random_image_one.php			// included does the php imaging
	random_image_sample.php			// main url

	fonts											// FONTS FOLDER (you create)
         Andale Mono.ttf
         Arial.ttf
         Chalkboard.ttf
         Comic Sans MS Bold.ttf
         Courier New Bold.ttf
         Georgia.ttf
         Tahoma.ttf
         Times New Roman Bold.ttf
         Trebuchet MS.ttf
         Verdana.ttf

	images											// IMAGES FOLDER (you create)
		noise.png
#  
----------------------------------------------------------------------------------


#  
----------------------------------------------------------------------------------
( 3 ) shell script to copy the correct font files to the local fonts  
folder
        change the path to the fonts folder where it shows 'target='
#  
----------------------------------------------------------------------------------

#!/bin/bash
# name : captcha_copy_fonts.sh (call it whatever you want)
# ---------------------------------------------------------
# This shell script copies the ttf fonts I found.
# Some fonts within the /Library/Fonts were not ttf in type. These  
worked very well for me...
# ---------------------------------------------------------
# copy ttf fonts from library

source=/Library/Fonts
target=/WebServer/path/to/project/folder/captcha_one/fonts/

sudo cp $source/Andale\ Mono.ttf $target
sudo cp $source/Arial.ttf $target
sudo cp $source/Chalkboard.ttf $target
sudo cp $source/Comic\ Sans\ MS\ Bold.ttf $target
sudo cp $source/Courier\ New\ Bold.ttf $target
sudo cp $source/Georgia.ttf $target
sudo cp $source/Tahoma.ttf $target
sudo cp $source/Times\ New\ Roman\ Bold.ttf $target
sudo cp $source/Trebuchet\ MS.ttf $target
sudo cp $source/Verdana.ttf $target
#  
----------------------------------------------------------------------------------

#  
----------------------------------------------------------------------------------
( 4 ) SAVE 'image_loader.php' BELOW TO A FILE
        AS SHOWN IN THE HIERARCHY ABOVE
#  
----------------------------------------------------------------------------------

<?php
// <!-- [4327] ( BEGIN ) filename : image_loader.php -->
// set the PNG header type for the request
header("Content-Type: image/png");
$image_path = "/tmp/random_image.png";
if (file_exists($image_path))
{
	// send the cached image to the output buffer (browser)
	readfile($image_path);
}
// <!-- [4327] ( _END_ ) filename : image_loader.php -->
?>

#  
----------------------------------------------------------------------------------
( 5 ) SAVE 'inc_random_image_one.php' BELOW TO A FILE
        AS SHOWN IN THE HIERARCHY ABOVE
#  
----------------------------------------------------------------------------------

<?php
// <!-- [4326] ( BEGIN ) filename : inc_random_image_one.php -->

// This demo requires "images/noise.jpg", which can be downloaded from http://www.reconn.us/images/noise.png

//start a session
// session_start();
//this function is called recursivelly
function random_string($len=5, $str='')
{
   for($i=1; $i<=$len; $i++)
    {
     //generates a random number that will be the ASCII code of the  
character. We only want numbers (ascii code from 48 to 57) and caps  
letters.
     $ord=rand(48, 90);
     if((($ord >= 48) && ($ord <= 57)) || (($ord >= 65) && ($ord <=  
90)))
         $str.=chr($ord);
     //If the number is not good we generate another one
     else
         $str.=random_string(1);
   }
   return $str;
}

function get_image()
{
global $_SESSION ;

//create the random string using the upper function (if you want more  
than 5 characters just modify the parameter)
$rand_str=random_string(5);

//We memorize the md5 sum of the string into a session variable
if($_SESSION['id'] == session_id())
{
	$_SESSION['image_value'] = md5($rand_str);
}

//Get each letter in one valiable, we will format all letters different
$letter1=substr($rand_str,0,1);
$letter2=substr($rand_str,1,1);
$letter3=substr($rand_str,2,1);
$letter4=substr($rand_str,3,1);
$letter5=substr($rand_str,4,1);

//Creates an image from a png file. If you want to use gif or jpg  
images, just use the coresponding functions: imagecreatefromjpeg and  
imagecreatefromgif.

// You can download "noise.png" at http://www.reconn.us/images/noise.png
$use_file = true ;
if($use_file)
{
	$image=imagecreatefrompng("images/noise.png");
}
else
{
	//Create an image
	$image=imagecreatetruecolor(160,80);
	
	//Create some colors
	$white=imagecolorallocate($image,255,255,255);
	$grey=imagecolorallocate($image,128,128,128);
	$black=imagecolorallocate($image,0,0,0);
	imagefilledrectangle($image,0,0,159,79,$white);
}

//Get a random angle for each letter to be rotated with.
$angle1 = rand(-20, 20);
$angle2 = rand(-20, 20);
$angle3 = rand(-20, 20);
$angle4 = rand(-20, 20);
$angle5 = rand(-20, 20);

$aFont = array( ) ;
$aFont[1] = "Andale Mono.ttf" ;
$aFont[2] = "Arial.ttf" ;
$aFont[3] = "Chalkboard.ttf" ;
$aFont[4] = "Comic Sans MS Bold.ttf" ;
$aFont[5] = "Courier New Bold.ttf" ;
$aFont[6] = "Georgia.ttf" ;
$aFont[7] = "Tahoma.ttf" ;
$aFont[8] = "Times New Roman Bold.ttf" ;
$aFont[9] = "Trebuchet MS.ttf" ;
$aFont[10] = "Verdana.ttf" ;

// The easiest thing here is to copy 10 different named fonts from / 
Library/Fonts/  to ./fonts/ and rename them
$font1 = "fonts/".$aFont[rand(1, 10)];
$font2 = "fonts/".$aFont[rand(1, 10)];
$font3 = "fonts/".$aFont[rand(1, 10)];
$font4 = "fonts/".$aFont[rand(1, 10)];
$font5 = "fonts/".$aFont[rand(1, 10)];

//Define a table with colors (the values are the RGB components for  
each color).
$colors[0]=array(122,229,112);
$colors[1]=array(85,178,85);
$colors[2]=array(226,108,97);
$colors[3]=array(141,214,210);
$colors[4]=array(214,141,205);
$colors[5]=array(100,138,204);

//Get a random color for each letter.
$color1=rand(0, 5);
$color2=rand(0, 5);
$color3=rand(0, 5);
$color4=rand(0, 5);
$color5=rand(0, 5);

//Allocate colors for letters.
$textColor1 = imagecolorallocate ($image, $colors[$color1][0], 
$colors[$color1][1], $colors[$color1][2]);
$textColor2 = imagecolorallocate ($image, $colors[$color2][0], 
$colors[$color2][1], $colors[$color2][2]);
$textColor3 = imagecolorallocate ($image, $colors[$color3][0], 
$colors[$color3][1], $colors[$color3][2]);
$textColor4 = imagecolorallocate ($image, $colors[$color4][0], 
$colors[$color4][1], $colors[$color4][2]);
$textColor5 = imagecolorallocate ($image, $colors[$color5][0], 
$colors[$color5][1], $colors[$color5][2]);

// Write text to the image using TrueType fonts.
$size = 20;
// ZEND DEBUGGER NOW WORKS FINE WITH THE MODIFIED 'freetype'
imagettftext($image, $size, $angle1, 10, $size+15, $textColor1,  
$font1, $letter1);
imagettftext($image, $size, $angle2, 35, $size+15, $textColor2,  
$font2, $letter2);
imagettftext($image, $size, $angle3, 60, $size+15, $textColor3,  
$font3, $letter3);
imagettftext($image, $size, $angle4, 85, $size+15, $textColor4,  
$font4, $letter4);
imagettftext($image, $size, $angle5, 110, $size+15, $textColor5,  
$font5, $letter5);

return $image ;
}

// <!-- [4326] ( _END_ ) filename : inc_random_image_one.php -->
?>

#  
----------------------------------------------------------------------------------
( 6 ) SAVE 'random_image_sample.php' BELOW TO A FILE
        AS SHOWN IN THE HIERARCHY ABOVE
#  
----------------------------------------------------------------------------------

<?php session_start(); ?>
<!-- [4325] ( BEGIN ) filename : random_image_sample.php -->
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
         "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
	<meta http-equiv=content-type content="text/html; charset=iso-8859-1">
	<title>Captcha - Random Image Verification</title>
	<meta name="generator" content="BBEdit 8.7">
</head>
<body>
<div align="center">
<?php
$br = "<br>\n" ;
$hr = "<hr>\n" ;
$_SESSION['id'] = session_id() ;
$show_debug = false ;
if($show_debug)
{
	echo "\$_SESSION['id'] = " . $_SESSION['id'] . $br ;
	echo "inc_random_image_one.php?" . SID . $br ;
}

$url = $_SERVER['PHP_SELF'] . '?' . SID ;

$form =<<<EOD
<form name="verify" method="post" action="$url">
<table border="1" cellpadding="10" cellspacing="0" width="600">
<tr><td valign="top" align="right">Comments</td>
<td><input name="message" size=40 value="...your message here">
</td></tr>
<tr><td colspan="2">
<div align="left">

<font size="1" face="Comic Sans MS"><strong><font size="2">
Please enter the string shown in the image in the form.<br> The  
possible characters are letters from A to Z in capitalized form and  
the numbers from 0 to 9.
</font>
</div>
</td></tr>
<tr><td align="center" colspan=2><input name="number" type="text" id= 
\"number\"></td></tr>
<tr><td colspan=2 align="center">

<img src="image_loader.php">

</td></tr>
<tr><td colspan=2 align="center"><input name="Submit" type="submit"
value="Submit"></td></tr>
</table>
</form>
EOD;
if(isset($_POST['Submit']))
{
	if($show_debug)
	{
		echo "\$_SESSION['image_value'] = " . $_SESSION['image_value'] . $br ;
		print "<pre>" ;
		print_r($_POST) ;
		print "</pre>" ;
	}
	
	$number = $_POST['number'];
	$image_value = md5($number) ;
	if($image_value !== $_SESSION['image_value'])
	{
		echo '<h1>Validation string not valid! Please try again!</h1>';
		
		require_once("inc_random_image_one.php") ;
		imagepng(get_image(), "/tmp/random_image.png") ;
		echo $form ;
	}
	else
	{
		echo '<h1>Your string is valid!</h1>';
		//do something with the data
	}
}
else
{
	require_once("inc_random_image_one.php") ;
	imagepng(get_image(), "/tmp/random_image.png") ;
	echo $form ;
}

?>
</div>
</body>
</html>
<!-- [4325] ( _END_ ) filename : random_image_sample.php -->
#  
----------------------------------------------------------------------------------

Hope this is useful,

Bill Hernandez
Plano, Texas





More information about the macports-users mailing list