Beefy Boxes and Bandwidth Generously Provided by pair Networks
Think about Loose Coupling
 
PerlMonks  

comment on

( [id://3333]=superdoc: print w/replies, xml ) Need Help??
#!/usr/bin/perl use strict; $|++; use Image::Magick; use lib './lib'; use ServerApp; #NOT IN CPAN, see perlmonks.org my $app = new ServerApp({ Port => 2690, }); my $ret = $app->run_with( [ '/', sub { return indexPage(); } ], [ 'font-list', sub { my ($req, $info) = @_; use CGI; my $cgi = new CGI($req->content); #POST - this is no good...Se +rverApp must provide a better facility my %vars = %{ $cgi->Vars }; if( exists $vars{'fontDir'} ) { #print "dir: $vars{'fontDir'}\n"; if( -e $vars{'fontDir'} ) { my $ret = []; opendir DIR, $vars{'fontDir'}; foreach( readdir DIR ) { next if /^\.{1,2}/ || !/\.ttf$/i; push @$ret, $_; } closedir DIR; @$ret = sort { lc $a cmp lc $b } @$ret; return { js => $ret }; } } } ], [ 'render', sub { my ($req, $info) = @_; use CGI; my $cgi = new CGI($req->url->query); #POST - this is no good.. +.ServerApp must provide a better facility my %vars = %{ $cgi->Vars }; if( exists $vars{'f'} ) { if( -e $vars{'f'} ) { my $text = $vars{'t'} || 'AaBbCcDd'; my $font = $vars{'f'}; my $size = $vars{'p'} || '30'; my $antiAlias = $vars{'a'}; my $color = $vars{'c'} || 'black'; my $baseColor = $vars{'bg'} || 'white'; my $newline_ct = $text =~ tr/\n/\n/; my $im = new Image::Magick( 'size'=>'1000x1000', magick => 'gif', #~ debug=>'All', ); my $params = { 'font'=>$font, 'pointsize'=>$size, 'fill'=> $color, 'gravity'=>'NorthWest', 'text'=>$text, 'antialias'=>$antiAlias, }; my $r; $r = $im->Read( 'xc:'.$baseColor ); warn "$r" if "$r"; my @values = $im->QueryFontMetrics( %$params ); use Data::Dumper;print Dumper($params); my ($charWidth, $charHeight, $ascender, $descender, $w +idth, $height, $max_advance) = @values; $height = ($height + 1) * ($newline_ct + 1); print $width.'x'.$height . "\n"; $r = $im->Resize( width=>$width+30, height=> $height+5 +); warn "$r" if "$r"; $r = $im->Annotate( %$params ); warn "$r" if "$r"; my @blobs = $im->ImageToBlob( ); return $blobs[0]; } } }, ], ['quit', undef, 1], ); print "Exited with $ret\n"; sub indexPage { return join '', <DATA>; } __END__ <script> /* REMOTE request object ******************************************** +********** Release 1.0 Copyright (C) 2005 bxbd. REMOTE request object is licensed under the GNU General Public License *****************************************************/ function Remote() {}; Remote.pending = []; Remote.Request = function (url, postdata, events) { var request; //the generic XMLHttpRequest object this library abst +racts var isIE; if (window.XMLHttpRequest) { request = new XMLHttpRequest(); } else if (window.ActiveXObject) { // branch for IE/Windows ActiveX version isIE = true; request = new ActiveXObject("Microsoft.XMLHTTP"); //always go +t to be different..! } if(request) {//no XMLHttpRequest object?, we have a problem var reqid = Remote.pending.length; request.id = "a" + reqid; //this is preparing our request object for what to do later on request.onreadystatechange = function() { if (Remote.pending[reqid].readyState == 4) {//complete +... if (Remote.pending[reqid].status == 200) { //serve +r returned code 200: OK var response = Remote.pending[reqid]; //add methods to our response object to parse +the return value (if applicable) response.responseObj = function() { if(typeof(response["_responseObj"]) == 'un +defined') { var x; try { eval("x = " + response.responseTex +t); } catch(e) { throw "remote.js ____ Could not pa +rse server return value:\n" + response.responseText; } response["_responseObj"] = x; } return response["_responseObj"]; } //coming soon: response.responseXML Remote._execute(events.onCompleted, response); } else { Remote._execute(events.onError, Remote.pending +[reqid]); } Remote.pending[reqid] = null; //see, it's being re +moved. } else { Remote._execute(events.onUpdate, Remote.pending[re +qid]); } } Remote.pending[reqid] = request; //add to the running hash, th +e finished case will remove it. if(postdata) { request.open("POST", url, true); request.setRequestHeader('Content-Type', 'application/x-ww +w-form-urlencoded'); request.send(postdata); } else { alert("Remote.Request, GET: " + url) request.open("GET", url, true); request.send(null); } return reqid; } else { alert("Could not allocate an XMLHttpRequest object (isIE = " + + (isIE ? 'yes' : 'no') + ")"); } }; Remote._execute = function(excode, Response) { //the return statements only exist so this method is testable, no +other reason (right now). if(typeof(excode) == 'function') { return excode(Response); ///booooo only 1 argument supported r +ight now!! } else { return eval(excode); } }; Remote.BuildQuery = function() { //Helper function, takes a list of arguments // for each argument, if it's a string it seeks out that element (by i +d) in the DOM tree, //If an id turns out to be a FORM element, buildQuery will add all the + *named* form elements of that form //otherwise, if it's a hash or object, it'll just copy those right int +o the finished hash //returns a GET/POST compatible string from the values of those elemen +ts var post = []; for(var i=0; i<arguments.length; i++) { if(typeof(arguments[i]) == 'string') { var elt = document.getElementById(arguments[i]); if(elt) { if(elt.tagName.toLowerCase() == 'form') { + for(var e=0; e<elt.elements.length; e++) { if(!elt.elements[e].name) { continue; } var value = Remote.getValue(elt.elements[e]); + post[elt.elements[e].name] = Remote.escapeURI( +value); } } else { var value = Remote.getValue(elt); if(value) { post[arguments[i]] = Remote.escapeURI(value); } } } else { post[arguments[i]] = ''; } } else if(typeof(arguments[i]) == 'object') { for(var x in arguments[i]) { post[x] = arguments[i][x]; } } } var post_terms = []; for(var p in post) { post_terms[post_terms.length] = p + '=' + post[p]; } return post_terms.join("&"); }; Remote.escapeURI = function(str) { if(encodeURIComponent) { return encodeURIComponent(str); } else { return escape(str); } }; Remote.getValue = function(elt) { if(elt.tagName.toLowerCase().match('^(input|select|textarea)$')) { var value = ""; if(elt.type.toLowerCase() == 'checkbox') { if(elt.checked) { return 1; } else { return; } } else { return elt.value; } } return; }; </script> <script> var fontDir; monitor( function(){ checkInput("fontDir") }, 500); function monitor( fcn, time ) { setTimeout(fcn, time); setTimeout( function(){ monitor(fcn, time) }, time ); } function checkInput(id) { var elt; if( elt = document.getElementById(id) ) { if( elt.value != fontDir ) { loadFonts( elt.value ); } } } function loadFonts(dir) { fontDir = dir; var reqid = Remote.Request( "font-list", Remote.BuildQuery('fontDir'), { onCompleted: function(Response) { var list = Response.responseObj(); var div = document.getElementById('fontList'); var html = ''; for( var l=0; l<list.length; l++ ) { //html += "<a style='text-decoration:none;' hr +ef=\"javascript:render('" + list[l] + "')\">" + list[l] + "</a><br>"; html += "<option value='" + list[l] + "'>" + l +ist[l] + "</option>"; } div.innerHTML = html; }, onError: function(Response) { //what to do when the se +rver returns anything but a code 200 to this request + alert("The server returned an ERROR: " + Response. +responseText); } } ); } function nextFont() { var sel = document.getElementById('fontList'); if( sel.selectedIndex > sel.options.length ) { sel.selectedIndex = 0; } else { sel.selectedIndex += 1; } render(); } function prevFont() { var sel = document.getElementById('fontList'); if( sel.selectedIndex <= 0) { sel.selectedIndex = sel.options.length - 1; } else { sel.selectedIndex -= 1; } render(); } function render() { var ttf = document.getElementById('fontList').value; var img = document.getElementById('fontDisplay'); var src = "/render?f=" + escape(document.getElementById('fontDir').value + "\\" + t +tf); var v; if( v = document.getElementById('fontSize').value ) { src += "&p=" + v; } src += "&a=" + (document.getElementById('fontAlias').checked ? + '1':'0') ; if( v = document.getElementById('fontText').value ) { src += "&t=" + escape(v); } img.src = ""; setTimeout( function() { img.src = src; }, 50 ); } </script> <table border=0 cellpadding=0 cellspacing=0> <tr> <td colspan=2 style="padding-bottom: 10px;"> Pick a directory to browse: <br> <input type=text size=75 id="fontDir" value="C:\Windows\fonts" > </td> </tr> <tr> <td> <select multiple id="fontList" style="height: 300px; width +: 250px;border: 2px solid navy; padding: 10px; font: 8pt verdana; tex +t-decoration: none; overflow: scroll;"> </select> <br> <input type=button value="Previous &lt;&lt;" onclick="prev +Font();"> <input type=button value="Next &gt;&gt;" onclick="nextFont +();"> &nbsp;&nbsp;&nbsp; <input type=button value="Render." onclick="render()"> </td> <td valign="top" style="padding: 20px;" align="left"> <table border=0 cellpadding=0 cellspacing=2> <tr> <td nowrap> Point size: </td> <td> <input type=text id="fontSize" size=1> </td> </tr> <tr> <td> Antialias? </td> <td> <input type=checkbox id="fontAlias" checked> </td> </tr> <tr valign="top"> <td> Text: </td> <td> <textarea wrap=hard rows=6 cols=25 id="fontTex +t"></textarea> </td> </tr> <tr> <td colspan=2 align="right"> <input type=button value="Render." onclick="re +nder()"> </td> </tr> </table> </td> </tr> </table> <br> <img id="fontDisplay" border=0 style="padding: 20px;">

In reply to FontPreview by qbxk

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post; it's "PerlMonks-approved HTML":



  • Are you posting in the right place? Check out Where do I post X? to know for sure.
  • Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
    <code> <a> <b> <big> <blockquote> <br /> <dd> <dl> <dt> <em> <font> <h1> <h2> <h3> <h4> <h5> <h6> <hr /> <i> <li> <nbsp> <ol> <p> <small> <strike> <strong> <sub> <sup> <table> <td> <th> <tr> <tt> <u> <ul>
  • Snippets of code should be wrapped in <code> tags not <pre> tags. In fact, <pre> tags should generally be avoided. If they must be used, extreme care should be taken to ensure that their contents do not have long lines (<70 chars), in order to prevent horizontal scrolling (and possible janitor intervention).
  • Want more info? How to link or How to display code and escape characters are good places to start.
Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others admiring the Monastery: (3)
As of 2024-04-24 00:03 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found