# Using another text renderer

**URL:** <https://discourse.processing.org/t/using-another-text-renderer/13016>\
**Category:** Coding Questions\
**Created:** [July 27, 2019, 4:26pm UTC](https://discourse.processing.org/t/using-another-text-renderer/13016 "2019-07-27T16:26:34Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![clankill3r](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/clankill3r/32/1098_2.png) [@clankill3r](https://discourse.processing.org/u/clankill3r)\
**Post date:** [July 27, 2019, 4:26pm UTC](https://discourse.processing.org/t/using-another-text-renderer/13016/1 "2019-07-27T16:26:34Z")

</div>

I was looking if it was possible to render text a different way.  
For those who are interested:

 ![25](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/2X/4/42542ce634397a4ecb4ab495aae80da211c1a9fd.png)

Not made user friendly yet.

Unfortunately it needs `PJOGL.profile = 1;` so it’s kinda bad…

```auto
import java.awt.Font;
import com.jogamp.opengl.util.awt.TextRenderer;
import processing.core.PApplet;
import processing.opengl.PJOGL;

TextRenderer textRender;

public void settings() {
  PJOGL.profile = 1;
  size(800, 600, P2D);
  pixelDensity(2);
}

@Override
  public void setup() {

  boolean antialiased = true;
  boolean mipmap = true;
  textRender = new TextRenderer( new Font("SansSerif", Font.PLAIN, 20), antialiased, true, null, mipmap );

  createFont("SansSerif", 20);
}

public void draw() {

  background(255);

  textRender.beginRendering(width, height, true);
  textRender.setColor(0, 0, 0, 1);
  textRender.draw("The quick brown fox jumped over the lazy dog", 50, height-50);
  textRender.endRendering();
  textRender.flush();

  fill(0);
  textSize(20);
  text("The quick brown fox jumped over the lazy dog", 50, 70);
}

```

---

<div class="post-metadata">

**Author:** ![clankill3r](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/clankill3r/32/1098_2.png) [@clankill3r](https://discourse.processing.org/u/clankill3r)\
**Post date:** [July 27, 2019, 4:37pm UTC](https://discourse.processing.org/t/using-another-text-renderer/13016/2 "2019-07-27T16:37:26Z")

</div>

I guess this is how to do proper font rendering in P2D.  
(This will be slow)

 ![02](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/2X/d/d4e872675484c2cc4dc843bcd547c38b6d196ed7.png)

```auto

PGraphics pg;

void setup() {
  size(200, 200, P2D);
  pixelDensity(2);
  
  textSize(120);

  
  pg = createGraphics(1200, 200);
  pg.beginDraw();
  pg.clear();
  pg.fill(255);
  pg.textSize(60);
  pg.textAlign(LEFT, TOP);
  pg.text("The quick brown fox", 0, 0);
  pg.endDraw();
  
}

void draw() {
  background(0);  
  
  
  float s = 0.16;
  image(pg, 10, 10, pg.width * s, pg.height * s);
  
  fill(255);
  textSize(9);
  textAlign(LEFT, TOP);
  text("The quick brown fox", 10, 25);
}

```

---

<div class="post-metadata">

**Author:** ![quark](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/quark/32/26_2.png) [@quark](https://discourse.processing.org/u/quark)\
**Post date:** [July 27, 2019, 5:02pm UTC](https://discourse.processing.org/t/using-another-text-renderer/13016/3 "2019-07-27T17:02:27Z")

</div>

![test](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/2X/4/4c18ccd553e3a9b654b5491215a7758877900f65.png)  
Another way to do it

```auto
String s = "The quick brown fox";
PGraphics pg;

void setup() {
  size(200, 100, P2D);
  background(200, 255, 200);
  // P2D text
  textSize(12);
  fill(128, 0, 128);
  text(s, 0, 20);
  // Now for the alternative
  pg = createGraphics(200, 30, JAVA2D);
  pg.beginDraw();
  pg.clear();
  pg.textSize(12);
  pg.fill(128, 0, 128);
  pg.text(s, 0, 20);
  pg.endDraw();
  image(pg, 0, 24);
}

```

---

<div class="post-metadata">

**Author:** ![clankill3r](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/clankill3r/32/1098_2.png) [@clankill3r](https://discourse.processing.org/u/clankill3r)\
**Post date:** [July 27, 2019, 8:01pm UTC](https://discourse.processing.org/t/using-another-text-renderer/13016/4 "2019-07-27T20:01:58Z")

</div>

Nice, I used your JAVA2D trick. Look how insane good the size 5 font is (retina).  
Work in progress, but pretty far. I think I only have todo textAlignY and the text method where you define the width and height of the box.

 ![40](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/2X/4/4c01a69770cd9d39e72978d729f4c159142c4951.jpeg)

```auto

void setup() {
  size(200, 500, P2D);
  pixelDensity(2);
  font = create_font("SansSerif", 64);
}

void draw() {

  background(255);

  fill(0);
  textAlign(LEFT);

  for (int i = 14; i > 4; i--) {
    textSize(i);
    text("The quick brown fox", 20, 20);
    translate(0, g.textLeading);
    text2("The quick brown fox", 20, 20);
    translate(0, g.textLeading * 2);
  }
}

public void text2(String txt, float x, float y) {

  float sx = x;

  String remainder = null;

  int new_line = txt.indexOf("\n", 0);
  if (new_line != -1) {
    remainder = txt.substring(new_line+1, txt.length());  
    txt = txt.substring(0, new_line);
  }

  if (g.textAlign == RIGHT) {
    x -= textWidth(txt);
  } else if (g.textAlign == CENTER) {
    x -= textWidth(txt) / 2;
  }

  float size = g.textSize;

  // backup tint
  boolean tint = g.tint;
  //float tintR = g.tintR;
  //float tintG = g.tintG;
  //float tintB = g.tintB;
  //float tintA = g.tintA;
  //float tintRi = g.tintRi;
  //float tintGi = g.tintGi;
  //float tintBi = g.tintBi;
  //float tintAi = g.tintAi;
  int tintColor = g.tintColor;
  //boolean tintAlpha = g.tintAlpha;
  
  tint(g.fillColor);

  for (int i = 0; i < txt.length(); i++) {
    char c = txt.charAt(i);
    if (c == '\r') continue;

    Glyph glyph = font.glyphs[(int)c];

    float x_pos = x + -font.offset_x * size / font.creation_size;
    float y_pos = y - (font.text_ascent * size);
    float width = glyph.g.width * size / font.creation_size;
    float height = glyph.g.height * size / font.creation_size;

    image(glyph.g, x_pos, y_pos, width, height);
    x += glyph.w * size;
  }

  if (remainder != null) {
    text2(remainder, sx, y + g.textLeading);
  }
  
  
  // restore tint
  g.tint = tint;
  //g.tintR = tintR;
  //g.tintG = tintG;
  //g.tintB = tintB;
  //g.tintA = tintA;
  //g.tintRi = tintRi;
  //g.tintGi = tintGi;
  //g.tintBi = tintBi;
  //g.tintAi = tintAi;
  g.tintColor = tintColor;
  //g.tintAlpha = tintAlpha;
  
}

Font font;

class Glyph {
  PGraphics g;
  float w;
}

class Font {
  String name;
  float creation_size;
  float text_ascent;
  float text_descent;
  //float text_leading;
  float offset_x;
  Glyph[] glyphs;
}

Font create_font(String font_name, float size) {

  Font font = new Font();
  font.name = font_name;
  font.creation_size = size;

  PFont pfont = createFont(font_name, size);
  textFont(pfont);
  textSize(size);

  font.text_ascent = textAscent() / size;
  font.text_descent = textDescent() / size;
  //font.text_leading = (font.text_ascent + font.text_descent) * 1.275;

  float tw = textWidth("X"); 
  int w = (int) (tw * 1.9);
  int h = (int) (tw * 2.1);

  float offset_x = w * 0.1; // prevent capping the left side of 'j' for example
  font.offset_x = offset_x;

  font.glyphs = new Glyph[128];

  for (int i = 1; i < 128; i++) {
    char c = (char)i;

    PGraphics pg = createGraphics(w, h, JAVA2D);
    pg.beginDraw();
    pg.clear();
    //pg.background(0,255,0);
    pg.textFont(pfont);
    pg.textSize(size);
    pg.fill(255);
    //pg.fill(0);
    pg.textAlign(LEFT, TOP);
    pg.text(""+c, offset_x, 0); 
    pg.endDraw();

    Glyph glyph = new Glyph();
    glyph.g = pg;
    glyph.w = textWidth(c) / size;

    font.glyphs[i] = glyph;
  }

  return font;
}

```

---

<div class="post-metadata">

**Author:** ![clankill3r](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/clankill3r/32/1098_2.png) [@clankill3r](https://discourse.processing.org/u/clankill3r)\
**Post date:** [July 28, 2019, 2:05pm UTC](https://discourse.processing.org/t/using-another-text-renderer/13016/5 "2019-07-28T14:05:23Z")

</div>

textAlignY support:

```auto

public void text2(String txt, float x, float y) {

  float sx = x;
  float size = g.textSize;

  // backup tint
  boolean tint = g.tint;
  //float tintR = g.tintR;
  //float tintG = g.tintG;
  //float tintB = g.tintB;
  //float tintA = g.tintA;
  //float tintRi = g.tintRi;
  //float tintGi = g.tintGi;
  //float tintBi = g.tintBi;
  //float tintAi = g.tintAi;
  int tintColor = g.tintColor;
  //boolean tintAlpha = g.tintAlpha;

  tint(g.fillColor);

  // deal with textAlignY
  // ---
  {
    float height = 0;
    for (int i = 0; i < txt.length(); i++) {
      if (txt.charAt(i) == '\n') {
        height += g.textLeading;
      }
    }

    if (g.textAlignY == CENTER) {
      y += (textAscent() - height)/2;
    } else if (g.textAlignY == TOP) {
      y += textAscent();
    } else if (g.textAlignY == BOTTOM) {
      y -= textDescent() + height;
    }
    
  }
  // ---

  while (txt.length() > 0) {

    String line;

    int index_of_new_line = txt.indexOf("\n", 0);
    if (index_of_new_line != -1) {
      line = txt.substring(0, index_of_new_line);
      txt = txt.substring(index_of_new_line+1, txt.length());
    } else {
      line = txt;
      txt = "";
    }

    if (g.textAlign == RIGHT) {
      x -= textWidth(line);
    } else if (g.textAlign == CENTER) {
      x -= textWidth(line) / 2;
    }

    for (int i = 0; i < line.length(); i++) {
      char c = line.charAt(i);
      if (c == '\r') continue;

      Glyph glyph = font.glyphs[(int)c];

      float x_pos = x + -font.offset_x * size / font.creation_size;
      float y_pos = y - (font.text_ascent * size);
      float width = glyph.g.width * size / font.creation_size;
      float height = glyph.g.height * size / font.creation_size;

      image(glyph.g, x_pos, y_pos, width, height);
      x += glyph.w * size;
    }

    y += g.textLeading;
    x = sx;
  }

  // restore tint
  g.tint = tint;
  //g.tintR = tintR;
  //g.tintG = tintG;
  //g.tintB = tintB;
  //g.tintA = tintA;
  //g.tintRi = tintRi;
  //g.tintGi = tintGi;
  //g.tintBi = tintBi;
  //g.tintAi = tintAi;
  g.tintColor = tintColor;
  //g.tintAlpha = tintAlpha;
}

```
