Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to control style of digits in Mathematica?

I use the Constantia font (that came with Windows 7) for my book and would like to prepare graphics for this book using the same font in Mathematica. Problem is that that Constantia by default outputs oldstyle digits. I know that, e.g. in XeTeX, it is possible to control whether oldstyle or normal digits are used for output.

Is it possible to control style of digits in Mathematica?

like image 601
Igor Avatar asked Sep 13 '11 15:09

Igor


2 Answers

I think this is rather difficult. Constantia is directly usable in Mathematica:

Style["0123456789", FontFamily -> "Constantia", FontSize -> 100]

enter image description here

However, the font is specifically designed to be balanced this way. If you tweak sizes and positions of the letters using FontSize and AdjustmentBox you get this:

shift = {0, 0, 0, -1, -1, -1, 0.0, -1, 0.0, -1} 0.5;
s = 0.65;
sizeScale = {1, 1, 1, s, s, s, s, s, s, s, s};
Row[Table[
   AdjustmentBox[
    Style[num, FontFamily -> "Constantia", 
     FontSize -> 100 sizeScale[[num + 1]]], 
    BoxBaselineShift -> shift[[num + 1]]], {num, 0, 
    9}]
] // DisplayForm

enter image description here

You see the shifted and scaled letters have a different body weight. Font weight can be adjusted, but only very roughly. Usually you only have Plain and Bold styles. So you can get as close as this:

body = {Plain, Plain, Plain, Bold, Bold, Bold, Bold, Bold, Bold, Bold};
Row[Table[
   AdjustmentBox[
    Style[num, FontFamily -> "Constantia" , 
     FontWeight -> body[[num + 1]], 
     FontSize -> 100 sizeScale[[num + 1]]], 
    BoxBaselineShift -> shift[[num + 1]]], {num, 0, 
    9}]] // DisplayForm

enter image description here

Somewhat better, but still ugly. I assume a complete new design of the letters is necessary for this to work. Perhaps the normal letters can be found somewhere further on in the font table?


UPDATE

Found the alternative number set. They are at positions 8320 - 8329 in the font table. You should be able to switch them using a font utility.

Style[FromCharacterCode[Range[8320, 8329]],FontFamily -> "Constantia", FontSize -> 100]

enter image description here

like image 184
Sjoerd C. de Vries Avatar answered Oct 14 '22 10:10

Sjoerd C. de Vries


For ticks, there is a workaround, but it requires a bit of programming. First, there is an auxiliary function.

getDigits[n_Integer] := IntegerDigits[n]
getDigits[0.] := {0}
getDigits[n_Real] := 
 With[{rd = RealDigits[n]}, 
  Join[Take[rd[[1]], rd[[2]]], {"."}, 
   Drop[rd[[1]], rd[[2]]] ] /. {".", z___} -> {0, ".", z} /. {a__,
    0 ..} -> {a} /. {a__, Repeated[0, {4, 150}],  q__} -> {a} /.
    {b__, "."} -> {b}] 
Attributes[getDigits] = Listable

getDigits[{14.3, 2, 274, 2345.67}]
  {{1, 4, ".", 3}, {2}, {2, 7, 4}, {2, 3, 4, 5, ".", 6, 7}} 

Then, a function like this:

ConstantiaTicks[a_?VectorQ, opts : OptionsPattern[Style]] := 
 Transpose@{a, 
   Style[#, FontFamily -> "Constantia", 
      Sequence @@ {opts}] & /@ (StringJoin /@ 
      Map[ToString[
         Style[Which[IntegerQ[#], 
           FromCharacterCode[# + 8320], # === ".", "."]]] &, 
   (getDigits[a]), {2}])}

Yields the following result: enter image description here

This can then be used in a FrameTicks or Ticks option. Of course it does mean specifying your ticks rather than letting Mathematica work out their values automatically. It also means taking the default tick length unless you want to have another argument to ConstantiaTicks that specifies that.

like image 34
Verbeia Avatar answered Oct 14 '22 09:10

Verbeia