What unit is "advanced" stored in for True Type fonts table "hmtx"? - truetype

I am running a very simple script that I wrote to get the "advance" of True Type fonts. The font in specific is New Times Roman. This is the kind of values that I'm getting back,
{
"A" : 1479
"a" : 909,
"B" : 1366,
"b" : 1024
"C" : 1366,
"c" : 909,
"N" : 1479,
"n" : 1024,
"M" : 1821,
"m" : 1593,
"." : 512,
}
I'm using the Perl library Font::TTF, you can find the manual here. And, here is my script,
use strict;
use warnings;
use autodie;
use Font::TTF::Font;
my $f = Font::TTF::Font->open('/usr/share/fonts/truetype/msttcorefonts/Times_New_Roman.ttf')
|| die $!;
my $json = JSON::XS->new->ascii->pretty->allow_nonref;
my #chars = ( '.', '-', 'a'...'z', 'A'...'Z', 0..9 );
my %db;
foreach my $char ( #chars ) {
my $ord = ord($char);
my $snum = $f->{'cmap'}->ms_lookup($ord);
$f->{'hmtx'}->read;
my $sadv = $f->{'hmtx'}{'advance'}[$snum];
$db{$char} = $sadv;
}
use JSON::XS qw(encode_json);
print $json->encode( \%db );

It's in "units-per-em" [1]. It is a grid of glyph design space with side of size defined in HEAD tag under "unitsPerEm". TrueType usually has it 2048, .otf with Postscript outlines 1000. So if you want to get anything useful, take the size of font, multiply by the advance and divide by unitsPerEm.
[1] http://en.wikipedia.org/wiki/Em_(typography)

Related

g1ant: jsonpath with method length() not implemented

I have problem to get size items of array. Function of jsonPath "length()" not implemented in g1ant, because throwing exception "Array index expected".
Below is sample in g1ant script for test.
addon core version 4.103.0.0
addon language version 4.104.0.0
♥jsonImage = ⟦json⟧‴{ "book" : [ { "name" : "Bambi"} , { "name" : "Cinderella" } ] }‴
♥aaa = ♥jsonImage⟦$.book.length()⟧
dialog ♥aaa
Are there other solutions related to the length of the array?
It's not possible to get the number of json array elements in the way that you are trying. G1ANT is using Newtonsoft.Json library for selecting json tokens where they don't allow expressions like .length() as you can read here.
Here's how you can workaround this issue.
♥jsonImage = ⟦json⟧‴{ "book" : [ { "name" : "Bambi"} , { "name" : "Cinderella" } ] }‴
♥jsonArrLength = 0
♥hasExceptionOccurred = false
while ⊂!♥hasExceptionOccurred⊃
try errorcall NoMoreElements
♥test = ♥jsonImage⟦book[♥jsonArrLength]⟧
♥jsonArrLength = ♥jsonArrLength + 1
end try
end while
dialog ♥jsonArrLength
procedure NoMoreElements
♥hasExceptionOccurred = true
end procedure

Perl6: large gzipped files read line by line

I'm trying to read a gz file line by line in Perl6, however, I'm getting blocked:
How to read gz file line by line in Perl6 however, this method, reading everything into :out uses far too much RAM to be usable except on very small files.
I don't understand how to use Perl6's Compress::Zlib to get everything line by line, although I opened an issue on their github https://github.com/retupmoca/P6-Compress-Zlib/issues/17
I'm trying Perl5's Compress::Zlib to translate this code, which works perfectly in Perl5:
use Compress::Zlib;
my $file = "data.txt.gz";
my $gz = gzopen($file, "rb") or die "Error reading $file: $gzerrno";
while ($gz->gzreadline($_) > 0) {
# Process the line read in $_
}
die "Error reading $file: $gzerrno" if $gzerrno != Z_STREAM_END ;
$gz->gzclose() ;
to something like this using Inline::Perl5 in Perl6:
use Compress::Zlib:from<Perl5>;
my $file = 'chrMT.1.vcf.gz';
my $gz = Compress::Zlib::new(gzopen($file, 'r');
while ($gz.gzreadline($_) > 0) {
print $_;
}
$gz.gzclose();
but I can't see how to translate this :(
I'm confused by Lib::Archive example https://github.com/frithnanth/perl6-Archive-Libarchive/blob/master/examples/readfile.p6 I don't see how I can get something like item 3 here
There should be something like
for $file.IO.lines(gz) -> $line { or something like that in Perl6, if it exists, I can't find it.
How can I read a large file line by line without reading everything into RAM in Perl6?
Update Now tested, which revealed an error, now fixed.
Solution #2
use Compress::Zlib;
my $file = "data.txt.gz" ;
my $handle = try open $file or die "Error reading $file: $!" ;
my $zwrap = zwrap($handle, :gzip) ;
for $zwrap.lines {
.print
}
CATCH { default { die "Error reading $file: $_" } }
$handle.close ;
I've tested this with a small gzipped text file.
I don't know much about gzip etc. but figured this out based on:
Knowing P6;
Reading Compress::Zlib's README and choosing the zwrap routine;
Looking at the module's source code, in particular the signature of the zwrap routine our sub zwrap ($thing, :$zlib, :$deflate, :$gzip);
And trial and error, mainly to guess that I needed to pass the :gzip adverb.
Please comment on whether my code works for you. I'm guessing the main thing is whether it's fast enough for the large files you have.
A failed attempt at solution #5
With solution #2 working I would have expected to be able to write just:
use Compress::Zlib ;
.print for "data.txt.gz".&zwrap(:gzip).lines ;
But that fails with:
No such method 'eof' for invocant of type 'IO::Path'
This is presumably because this module was written before the reorganization of the IO classes.
That led me to #MattOates' IO::Handle like object with .lines ? issue. I note no response and I saw no related repo at https://github.com/MattOates?tab=repositories.
I am focusing on the Inline::Perl5 solution that you tried.
For the call to $gz.gzreadline($_): it seems like gzreadline tries to return the line read from the zip file by modifying its input argument $_ (treated as an output argument, but it is not a true Perl 5 reference variable[1]), but the modified value is not returned to the Perl 6 script.
Here is a possoble workaround:
Create a wrapper module in the curent directory, e.g. ./MyZlibWrapper.pm:
package MyZlibWrapper;
use strict;
use warnings;
use Compress::Zlib ();
use Exporter qw(import);
our #EXPORT = qw(gzopen);
our $VERSION = 0.01;
sub gzopen {
my ( $fn, $mode ) = #_;
my $gz = Compress::Zlib::gzopen( $fn, $mode );
my $self = {gz => $gz};
return bless $self, __PACKAGE__;
}
sub gzreadline {
my ( $self ) = #_;
my $line = "";
my $res = $self->{gz}->gzreadline($line);
return [$res, $line];
}
sub gzclose {
my ( $self ) = #_;
$self->{gz}->gzclose();
}
1;
Then use Inline::Perl5 on this wrapper module instead of Compress::Zlib. For example ./p.p6:
use v6;
use lib:from<Perl5> '.';
use MyZlibWrapper:from<Perl5>;
my $file = 'data.txt.gz';
my $mode = 'rb';
my $gz = gzopen($file, $mode);
loop {
my ($res, $line) = $gz.gzreadline();
last if $res == 0;
print $line;
}
$gz.gzclose();
[1]
In Perl 5 you can modify an input argument that is not a reference, and the change will be reflected in the caller. This is done by modifying entries in the special #_ array variable. For example: sub quote { $_[0] = "'$_[0]'" } $str = "Hello"; quote($str) will quote $str even if $str is not passed by reference.

HP/Tandem TACL How to use the % as a value in the SQL like clause

In my TACL, I'm trying to create a variable used as input to an SQLCI command. I want to use a LIKE clause with a % as a wildcard. Every time it replaces the % with a ? causing the SQL statement to not return the desired results.
Code snippitz:
?TACL macro
#Frame
#Set #informat plain
#Set #outformat pretty
#Push stoprun DC fidata var1 mailmast sqlvol sqlsvol IsOpen EMLFile ans emlline
#Push mailfile mfile likeit charaddr sqlin sqlout test
[#Def True text |body|-1]
[#Def False text |body|0]
Intervening code cut out to reduce length - the cutout code works
== select <program name> from <full mailmast filename> where mm_file_prefix
== like "<likename>%" for browse access;
[#If Not [StopRun]
|then|
#Setv test "~%"
#Set #trace -1
#Set SqlIn select mm_program_name from [mailmast] where mm_file_prefix
#appendv sqlin "like ""[LikeIt]~%"" for browse access;"
SQLCI/Inv Sqlin,outv sqlout/
] == end of if
When I run the code, I display the variables, and it has replaced the % with ?
-TRACE-
-19-st 1 v
Invoking variable :MAILMAST.1
#Set SqlIn select mm_program_name from $DATA5.SQL2510.MAILMAST where mm_file_p
refix
-TRACE-
-20-
#appendv sqlin "like ""[LikeIt]
^
-TRACE-
-20-
Invoking variable :LIKEIT.1
#appendv sqlin "like ""ED?"" for browse access;"
-TRACE-
-20-d test
?
-22-st 1 v
SQLCI/Inv Sqlin,outv sqlout/
-TRACE-
-23-d sqlin
select mm_program_name from $DATA5.SQL2510.MAILMAST where mm_file_prefix
like "ED?" for browse access;
-24-
Since the % is not there as a wildcard, this SQL statement fails to bring up the proper record.
The question is, how do I put a % into a TACL variable and not get it changed to a ?
Edited to replace duplicate code with the start of the TACL Macro - MEH
I really don't like answering my own question because that looks like I was just setting things up to make me look smart, but in continuing my research while waiting, I found the answer. See code snippitz below:
?TACL macro
#Frame
#Set #informat plain
#Set #outformat pretty
#Push stoprun DC fidata var1 mailmast sqlvol sqlsvol IsOpen EMLFile ans emlline
#Push mailfile mfile likeit charaddr sqlin sqlout test
[#Def True text |body|-1]
[#Def False text |body|0]
[#Def ascii struct
Begin
BYTE byt0 value 37;
CHAR pcent REDEFINES byt0;
End;
] == end of struct
Note the addition of the struct. This is to be able to assign a byte a decimal value of 37 (%) and redefine it as a character to be used in the like statement.
== select <program name> from <full mailmast filename> where mm_file_prefix
== like "<likename>%" for browse access;
[#If Not [StopRun]
|then|
#Set test [ascii:pcent]
#Set #trace -1
#Set SqlIn select mm_program_name from [mailmast] where mm_file_prefix
#append sqlin like "[LikeIt][ascii:pcent]" for browse access;
SQLCI/Inv Sqlin,outv sqlout/
] == end of if
Note the use of the struct [ascii:pcent] and this does work.
Thanks to all who read my question.

Lingo Code "[cc]" is coming up as a fault

The game is a word search game in an advanced lingo book and the lingo code is using [cc] which is coming up as a code fault. What is wrong or is this use of [cc] obsolete? And if so, how can it be corrected?
on getPropertyDescriptionList me
list = [:]
-- the text member with the words in it
addProp list, #pWordSource,[cc]
[#comment: "Word Source",[cc]
#format: #text,[cc]
#default: VOID]
addProp list, #pEndGameFrame,[cc]
[#comment: "End Game Frame",[cc]
#format: #marker,[cc]
#default: #next]
return list
end
I guess this is code from here, right?
That seems like an older version of Lingo syntax. [cc], apparently, stands for "continuation character". It basically makes the compiler ignore the linebreak right after it, so that it sees everything from [#comment: to #default: VOID] as one long line, which is the syntactically correct way to write it.
If I remember correctly, once upon a time, the guys who made Lingo made one more crazy decision and made the continuation character look like this: ¬ Of course, this didn't print in lots of places, so some texts like your book used things like [cc] in its place.
In modern versions of Lingo, the continuation character is \, just like in C.
I programmed in early director but have gone on to other languages in the many years since. I understand this code. The function attempts to generate a dictionary of dictionaries. in quasi-JSON:
{
'pWordSource': { ... } ,
'pEndGameFrame': { ... }
}
It is creating a string hash, then storing a "pWordSource" as a new key pointing to a 3 item hash of it's own. The system then repeats the process with a new key "pEndGameFrame", providing yet another 3 item hash. So just to expand the ellipses ... from the above code example:
{
'pWordSource': { 'comment': 'Word Source', 'format': 'text', 'default': null } ,
'pEndGameFrame': { 'End Game Frame': 'Word Source', 'format': 'marker', 'default': 'next' }
}
So I hope that explains the hash characters. It's lingo's way of saying "this is not just a string, it's a special director-specific system we're calling a symbol. It can be described in more conventional programming terms as a constant. The lingo compiler will replace your #string1 with an integer, and it's always going to be the same integer associated with #string1. Because the hash keys are actually integers rather than strings, we can change the json model to look something more like this:
{
0: { 2: 'Word Source', 3: 'text', 4: null } ,
1: { 2:'End Game Frame', 3: 'marker', 4: 'next' }
}
where:
0 -> pWordSource
1 -> pEndGameFrame
2 -> comment
3 -> format
4 -> default
So to mimic the same construction behavior in 2016 lingo, we use the newer object oriented dot syntax for calling addProp on property lists.
on getPropertyDescriptionList me
list = [:]
-- the text member with the words in it
list.addProp(#pWordSource,[ \
#comment: "Word Source", \
#format: #text, \
#default: void \
])
list.addProp(#pEndGameFrame,[ \
#comment: "End Game Frame", \
#format: #marker, \
#default: #next \
])
return list
end
Likewise, the same reference shows examples of how to use square brackets to "access" properties, then initialize them by setting their first value.
on getPropertyDescriptionList me
list = [:]
-- the text member with the words in it
list[#pWordSource] = [ \
#comment: "Word Source", \
#format: #text, \
#default: void \
]
list[#pEndGameFrame] = [ \
#comment: "End Game Frame", \
#format: #marker, \
#default: #next \
]
return list
end
And if you are still confused about what the backslashes are doing, there are other ways to make the code more vertical.
on getPropertyDescriptionList me
list = [:]
-- the text member with the words in it
p = [:]
p[#comment] = "Word Source"
p[#format] = #text
p[#default] = void
list[#pWordSource] = p
p = [:] -- allocate new dict to avoid pointer bug
p[#comment] = "End Game Frame"
p[#format] = #marker
p[#default] = #next
list[#pEndGameFrame] = p
return list
end
The above screenshot shows it working in Director 12.0 on OS X Yosemite.

Lua in Redis from JSON

I have a list of JSON strings stored in Redis that looks something like this:
[
{ "ID": 25, "DomainID": 23455, "Name": "Stuff", "Value": 23 },
{ "ID": 35, "DomainID": 23455, "Name": "Stuff", "Value": 10 }
]
The key would be something like "Event:23455".
Using a Lua script and ServiceStack.Redis how would I pull out an anonymous object containing only values where the value is less than 20?
So what I want to return would look like this:
[{ "ID": 35, "Value": 10}]
Thanks.
UPDATE 03/31/2013:
After trying what has been suggested I now have a new problem. A Lua script syntax error.
I'm getting a Lua syntax error about "expecting '=' near cjson". Here is the Lua script string (in C#) I am feeding to Redis:
string luaScript = "local tDecoded = cjson.decode(redis.call('GET', KEYS[1]));"
+ "local tFinal = {};"
+ "for iIndex, tValue in ipairs(tDecoded) do"
+ " if tonumber( tValue.Value ) < 20 then"
+ " table.insert(tFinal, { ID = tValue.ID, Value = tValue.Value});"
+ " end"
+ "end"
+ "return cjson.encode(tFinal);";
Are there any Lua or Redis Lua experts out there that can see what might be the problem? i.e. Does the Lua syntax look correct?
UPDATE 04/02/2013
The parsing error was resolved by adding \n newline characters to end of each line like so.
string luaScript = "local tDecoded = redis.call('GET', KEYS[1]);\n"
+ "local tFinal = {};\n"
+ "for iIndex, tValue in ipairs(tDecoded) do\n"
+ " if tonumber( tValue.Value ) < 20 then\n"
+ " table.insert(tFinal, { ID = tValue.ID, Value = tValue.Value});\n"
+ " else\n"
+ " table.insert(tFinal, { ID = 999, Value = 0});\n"
+ " end\n"
+ "end\n"
+ "return cjson.encode(tFinal);";
Unfortunately this works without errors but for some reason only returns "{}" or an empty list in the ServiceStack RedisClient. So I'm not there yet but I am one step closer.
You can use LuaJSON available on GitHub or you can also try this JSON to Lua table parser for the task. The usage will be something like this(for the GitHub link):
local json = require( "json" ) -- or JSON.lua
local tDecoded = json.decode(sJSON) -- sJSON is the original JSON string
local tFinal = {}
for iIndex, tValue in ipairs( tDecoded ) do
if tonumber( tValue.Value ) < 20 then
table.insert( tFinal, { ID = tValue.ID, Value = tValue.Value} )
end
end
print( json.encode(tFinal) )