2

I am trying to generate an image using Java/Clojure made up mainly of text that uses a custom font with opentype features. I have tried to use the current OTF Font support in Java even upgraded to oracle Java 8 and set the TextAttribute Ligatures to On but to no help. Can anyone provide suggestions on what is possible.

Note I need the ability to determine font-size, line-height and width of image so I am not sure if using TEX is possible in that situation.

Mackram
  • 135
  • 1
  • 5

2 Answers2

3

I believe the answer for the Java side was answered in this SO question. But I did a translation to Clojure because java interop gets a bit tricky. Notice that ImageIO/write takes the BufferedImage instance not the Graphics2D, throughout the program image gets mutated using an instance of Graphics2D.

(ns so-33725486.core
  (:import [java.awt Graphics2D Color Font]
           [java.awt.image BufferedImage]
           [javax.imageio ImageIO]
           [java.io File]))

(defn str->img [string filename]
  (let [file (File. (str "./" filename ".png"))
        width 250
        height 100
        image (BufferedImage. width height BufferedImage/TYPE_INT_ARGB)
        graphics (.createGraphics image)
        font-size 30
        font (Font. "TimesRoman" Font/BOLD font-size)]
    (.setColor graphics Color/BLACK)
    (.setFont graphics font)
    (.drawString graphics string 10 25)
    (ImageIO/write image "png" file)))  
Community
  • 1
  • 1
Ricardo Acuna
  • 530
  • 2
  • 10
  • Thanks Ricardo for your comment I have something very similar already working. The problem is that this approach does not take into account Open Type Features if the font has them (even if you include the proper otf files). This means this approach will not work with esoteric fonts or custom fonts (with say arabic/persian/urdu custom chars) – Mackram Nov 17 '15 at 12:45
  • In that case falling back to XeLaTeX is always an option, I once made a whole book of 3000 recipes for my wife with a ruby program that generated and compiled XeLaTeX. It's still state of the art for typography, but watch out for [Clo](https://www.youtube.com/watch?v=824yVKUPFjU) we might have a native way to do typography in Clojure soon. – Ricardo Acuna Nov 17 '15 at 22:44
  • I am accepting this answer since @ricardo-acuna provided a correct point when it comes to xelatex. In conclusion the best way i found was to use selmer to generate tex files on the file and then use XeLaTeX to generate the pdf and finally ImageMagic for the actual image. Note fontspec package is required to use custom fons so XeLaTex is the only viable option I found. – Mackram Dec 28 '15 at 10:33
0

I know knothing about OTF but for a quick & dirty solution how about using phantomjs to generate a PNG? If your project can have it as a dependency, you can work on a native solution aftewards.

I also found this, maybe there's something there that rings a bell for you: https://github.com/jfacorro/clojure-lab

Edit: you can also use Processing: https://processing.org/reference/createFont_.html It is a Java library so you can use it in your project or if creating the image is the main purpose of your app, use Processing directly -- a great environment to quickly create prototypes/apps that work with images.

Marcin Bilski
  • 572
  • 6
  • 13
  • Marcin the phantomjs idea sounds good and I have been thinking along the linex of using LaTex as it is famous for exceptional font support however this is my last resort as it would require me to run "shell" commands making the flexibility wanted coming at a cost. as for processing there is nowhere in its records about its support for open type features – Mackram Nov 17 '15 at 12:46
  • From the above link: "Dynamically converts a font to the format used by Processing from a .ttf or .otf file". I assumed this would be enough for you. – Marcin Bilski Nov 17 '15 at 15:20
  • My experience is that processing .otf files is not directly correlated with supporting open type features. In the case of Java since Java 6 .otf files are supported but still not all open type features are supported. – Mackram Nov 17 '15 at 15:41
  • Oh, I see. After reading your comment below @RicardoAcuna's answer, I finally understand what is the issue. I guess that without trying out a particular Java library, it's impossible to tell if the features will work at all even if the library advertises as supporting OTF. Does Chrome (webkit) render them correctly? – Marcin Bilski Nov 17 '15 at 17:52
  • yes indeed Chrome(webkit) renders them correctly which is why i think the idea of phantomjs sounds promising, but hoping that is a last resort. – Mackram Nov 17 '15 at 20:37
  • Make sure to post an answer if you find another solution. This looks like a pretty tricky one. – Marcin Bilski Nov 17 '15 at 20:43