Here is a variation on part 2 of Ulrik's answer, which works on my system (Mac) with the Tempera font. One can bypass file generation with ExportString
and ImportString
; the results can be stored in the CDF notebook. The result of each Import
is Graphics
, not a formatted String
. Consequently all the font information is lost (e.g. kerning, baseline position) as well as other font advantages (e.g. smoothing). One the other hand, the graphics (at least in this case) are scalable.
Creating the images
There are two primary functions, temperaSign
for a single music sign and graphicsForm
for a combination of a letter and sign as in the OP's question; the auxiliary function combine
creates a text-based combination of a letter and sign like the OP's example.
temperaSign[sign_] :=
First @ ImportString[ExportString[Style[sign, FontFamily -> "Tempera"], "PDF"], "PDF"];
combine[letter_, sign_] :=
StringForm["````", Style[letter, FontFamily -> "Mathematica6"],
Style[sign, FontFamily -> "Tempera", FontSize -> 18, FontWeight -> "Plain"]];
temperaForm[letter_, sign_] :=
First @ ImportString[ExportString[combine[letter, sign], "PDF"], "PDF"]
Here's what the imported Graphics
look like:
temperaSign["U"] // InputForm
(* Graphics[{Thickness[0.6361323155216285],
Style[{FilledCurve[{{{0, 2, 0}, {0, 1, 0}, {0, 1, 0}, {0, 1, 0}, {0, 1, 0},
{0, 1, 0}, {0, 1, 0}, {0, 1, 0}, {0, 1, 0}, {0, 1, 0}, {0, 1, 0}, {0, 1, 0}}},
{{{0.01200488090515137, 6.366542406082154}, {0.01200488090515137, 5.374395179748535},
... 10 points omitted ...
{0.01200488090515137, 6.366542406082154}}}]},
Thickness[0.6361323155216285]]},
ImageSize -> {2., 12.}, PlotRange -> {{0., 1.572}, {0., 12.}}, AspectRatio -> Automatic] *)
To get good size and positioning, one has to play with ImageSize
and BaselinePosition
. Close inspection shows the size is slightly off.
Row[{combine["A", "U"],
Show[temperaSign["U"], ImageSize -> {Automatic, 24}, BaselinePosition -> Scaled[0.41]]}]
Here is a somewhat high-resolution rendering comparing the text, graphics, and rasterized versions. (At screen resolution, the rasterized version is only slightly fuzzy.)
{combine["A", "U"],
Show[graphicsForm["A", "U"], ImageSize -> {Automatic, 24},
BaselinePosition -> Scaled[0.37]],
Rasterize@combine["A", "U"]}
Creating the database
One can compute all of the signs to be used and store them in a notebook.
For instance:
m[#] -> temperaSign[#] & /@ CharacterRange["A", "Z"]
Then type sub =
and copy the output:
Here I used m
as a wrapper; you might wish to use a more expressive symbol such as musicSign
(but beware reusing temperaSign
). Or you may wish to use letter-strings ("A" ->...
).
One could process music text with something like:
baselineAdjust[m["U"]] = Scaled[0.37];
baselineAdjust[m["A"]] = Scaled[0.16];
(* add more baseline defs as desired *)
baselineAdjust[_] := Center;
temperaAdjust[expr_Graphics, opts___] := Show[expr, opts];
temperaAdjust[expr_] /; Head[expr] =!= m :=
expr /. sign_m :> temperaAdjust[sign, ImageSize -> {Automatic, 24},
BaselinePosition -> baselineAdjust[sign]];
note = {"A", m["U"]};
temperaAdjust @ Row[note, BaseStyle -> {FontFamily -> "Mathematica6"}] /. sub
note = {"B", m["A"]};
temperaAdjust @ Row[note, BaseStyle -> {FontFamily -> "Mathematica6"}] /. sub