EuAndreh
EuAndreh

Reputation: 578

How to iterate through an array of arrays in PostScript? How to use a font with musical signs?

I have struggled with some PostScript code, and I'm reaching my goal little by little (the PostScript language is really cool!)

What I have so far is:

%!PS-Adobe-2.0
/Times-Roman findfont 20 scalefont setfont
/r 360 12 / def

/triades [
(C Dm Em F G Am Bmb5)
(F Gm Am Bb C Dm Emb5)
(Bb Cm Dm Eb F Gm Amb5)
(Eb Fm Gm Ab Bb Cm Dmb5)
(Ab Bbm Cm Db Eb Fm Gmb5)
(Db Ebm Fm Gb Ab Bbm Cmb5)
(F# G#m A#m B C# D#m E#mb5)
(B C#m D#m E F# G#m A#mb5)
(E F#m G#m A B C#m D#mb5)
(A Bm C#m D E F#m G#mb5)
(D Em F#m G A Bm C#mb5)
(G Am Bm C D Em F#b5)
] def

336 396 translate
triades  { 50 0 moveto show 30 rotate } forall
showpage

It gives me a page with 12 chord sequences spread through a circle. But there is a problem with this approach: it does automatic spacing, so the line where many chords have # in it, the line gets bigger and the chords are more distant from one another. I tried to do a nested loop, printing chors one by one, but that didn't really work. Here's what I tried:

%!PS-Adobe-2.0
/Times-Roman findfont 20 scalefont setfont
/r 360 12 / def

/triadesArr [
[(C Dm Em F G Am Bmb5)]
[(F Gm Am Bb C Dm Emb5)]
[(Bb Cm Dm Eb F Gm Amb5)]
[(Eb Fm Gm Ab Bb Cm Dmb5)]
[(Ab Bbm Cm Db Eb Fm Gmb5)]
[(Db Ebm Fm Gb Ab Bbm Cmb5)]
[(F# G#m A#m B C# D#m E#mb5)]
[(B C#m D#m E F# G#m A#mb5)]
[(E F#m G#m A B C#m D#mb5)]
[(A Bm C#m D E F#m G#mb5)]
[(D Em F#m G A Bm C#mb5)]
[(G Am Bm C D Em F#b5)]
] def

336 396 translate
triadesArr { 50 0 moveto { 50 0 moveto show } forall 30 rotate } forall

showpage

For some reason, both outputs are the same. How can I fix it?


There's another topic: how to use a font with musical signs with it? I wanted chords like Bbm to have an actual flat sign, instead of a b letter. I tried downloading and using fonts like Feta, Bravura or Gonville (or even the font used in the songs package)

Any directions here would be appreciated.

Thank you very much.

Obs.: is an array of strings the most suitable data structure for the job? It seamed to me like the most simple and straighfoward one. If you were the one doing this program, would you use another data structure instead?

Upvotes: 1

Views: 1310

Answers (2)

Duane Semcert
Duane Semcert

Reputation: 1

I think your problem was that you were trying to get the notes at a particular radius for each line. That meant each note had to be a separate string and each chord had to be rotated and restarted like so:

%!PS-Adobe-2.0
/Times-Roman findfont 12 scalefont setfont
/r 360 12 / def

/triadesArr [
[(C ) (Dm ) (Em ) (F ) (G ) (Am ) (Bmb5 )]
[(F ) (Gm ) (Am ) (Bb) (C ) (Dm ) (Emb5 )]
[(Bb) (Cm ) (Dm ) (Eb) (F ) (Gm ) (Amb5 )]
[(Eb) (Fm ) (Gm ) (Ab) (Bb) (Cm ) (Dmb5 )]
[(Ab) (Bbm) (Cm ) (Db) (Eb) (Fm ) (Gmb5 )]
[(Db) (Ebm) (Fm ) (Gb) (Ab) (Bbm) (Cmb5 )]
[(F#) (G#m) (A#m) (B ) (C#) (D#m) (E#mb5)]
[(B ) (C#m) (D#m) (E ) (F#) (G#m) (A#mb5)]
[(E ) (F#m) (G#m) (A ) (B ) (C#m) (D#mb5)]
[(A ) (Bm ) (C#m) (D ) (E ) (F#m) (G#mb5)]
[(D ) (Em ) (F#m) (G ) (A ) (Bm ) (C#mb5)]
[(G ) (Am ) (Bm ) (C ) (D ) (Em ) (F#b5 )]
] def

336 396 translate
triadesArr { 50 0 moveto { 10 0 rmoveto show } forall 30 rotate } forall

showpage

This code has been tested and the font had to be reduced to fit on the page.

Upvotes: 0

KenS
KenS

Reputation: 31199

I think you are expecting moveto to be relative, it isn't, it specifies an absolute position on the page. So your outer loop moves to 50,0 then your inner loop moves to 50,0 (which is the same place) and draws the string. Then you rotate by 30 degrees, move to 50,0, move to 50,0 again and so on. Which as you will immediately notice is the same as your first code fragment, which is why you get the same output.

If you want a relative moveto then you need to do rmoveto instead of moveto.

Of course, its entirely possible I'm misunderstanding what you want to achieve.....

As for using a font there are a couple of ways depending what you are using;

You can install the font to the interpreter, then simply call the font just as you are doing for Times-Roman.

You can embed the font in the PostScript file and do exactly the same, but in this case you can send the PostScript file to someone who doesn't have the fonts and it will still print correctly.

If the fonts are type 1 fonts then you can embed them directly. NOTE: looking at one of these packages I notice it contains .pfb files (Printer Font Binary) which you cannot use directly, you need to decode them. You cannot use TrueType (or OpenType) fonts directly at all, they need to be converted to type 42 fonts (or in the case of an OpenType font with CFF outlines, to a type 2 font).

I'm not entirely sure what you are trying to do, so its kind of hard to critique your approach. Note that my musical knowledge is essentially nil, which probably doesn't help.....

Upvotes: 2

Related Questions