1 /*
2  * Copyright (c) 2019 Helmut Neemann.
3  * Use of this source code is governed by the GPL v3 license
4  * that can be found in the LICENSE file.
5  */
6 package de.neemann.digital.draw.graphics;
7 
8 import de.neemann.digital.draw.graphics.text.ParseException;
9 import de.neemann.digital.draw.graphics.text.Parser;
10 import de.neemann.digital.draw.graphics.text.formatter.LaTeXFormatter;
11 import de.neemann.digital.draw.graphics.text.text.Decorate;
12 import de.neemann.digital.draw.graphics.text.text.Text;
13 
14 import java.awt.*;
15 import java.util.ArrayList;
16 
17 /**
18  * Formats text in LaTeX style.
19  */
20 public class TextFormatLaTeX implements GraphicSVG.TextStyle {
21     private static final ArrayList<FontSize> FONT_SIZES = new ArrayList<>();
22     private boolean pinStyleInMathMode;
23 
24     /**
25      * Creates a new instance.
26      *
27      * @param pinStyleInMathMode if true pin lables are set in math mode
28      */
TextFormatLaTeX(boolean pinStyleInMathMode)29     public TextFormatLaTeX(boolean pinStyleInMathMode) {
30         this.pinStyleInMathMode = pinStyleInMathMode;
31     }
32 
33     private static final class FontSize {
34 
35         private final String name;
36         private final int size;
37 
FontSize(String name, int size)38         private FontSize(String name, int size) {
39             this.name = name;
40             this.size = size;
41         }
42     }
43 
44     static {
45         add("tiny", 35);     // measured pixel sizes in a BEAMER created PDF
46         add("scriptsize", 46);
47         add("footnotesize", 52);
48         add("small", 58);
49         add("normalsize", 63);
50         add("large", 69);
51         add("Large", 83);
52         add("LARGE", 100);
53         add("huge", 120);
54         add("Huge", 143);
55     }
56 
add(String name, int size)57     private static void add(String name, int size) {
58         FONT_SIZES.add(new FontSize(name, (size * Style.NORMAL.getFontSize()) / 63));
59     }
60 
getFontSizeName(int fontSize)61     private static String getFontSizeName(int fontSize) {
62         String best = "normalsize";
63         int diff = Integer.MAX_VALUE;
64         for (FontSize fs : FONT_SIZES) {
65             int d = Math.abs(fontSize - fs.size);
66             if (d < diff) {
67                 diff = d;
68                 best = fs.name;
69             }
70         }
71         return best;
72     }
73 
74     @Override
format(String text, Style style)75     public String format(String text, Style style) {
76         try {
77             Text t = new Parser(text).parse();
78             boolean decorate = style.getFontStyle() == Font.ITALIC;
79 
80             if (style == Style.INOUT && !pinStyleInMathMode)
81                 decorate = false;
82             else if (style == Style.SHAPE_PIN && pinStyleInMathMode)
83                 decorate = true;
84 
85             if (decorate)
86                 t = Decorate.math(t);
87             text = LaTeXFormatter.format(t);
88         } catch (ParseException e) {
89             e.printStackTrace();
90         }
91         if (style.getFontSize() != Style.NORMAL.getFontSize()) {
92             final String fontSizeName = getFontSizeName(style.getFontSize());
93             if (!fontSizeName.equals("normalsize"))
94                 text = "{\\" + fontSizeName + " " + text + "}";
95         }
96         return GraphicSVG.escapeXML(text);
97     }
98 }
99