C API Rotate Text

What’s the idiomatic way to rotate text on the pebble watch using the C API?

My use case is that I want to show a graph using dynamic data in my watch app, so I would like vertical text to label the Y axis.

I see a plenty of documentation on how to rotate a bitmap using RotBitmapLayer and DEG_TO_TRIANGLE(angle), but this would require me to create a png of the text that I want to rotate. I would like to be able to rotate any text, so this is not a workable solution for me.

I basically want to do this to my text layer

static TextLayer* yAxis_textLayer;
rot_bitmap_layer_set_angle(text_layer_get_layer(yAxis_textLayer), DEG_TO_TRIGANGLE(90));
1 Like

I can’t recall if EffectsLayer supports this. GitHub - jrmobley/pebble-fctx for sure does, with vector fonts (rather than bitmaps).

2 Likes

EffectsLayer looks abandoned, the link from the docs 404s and the repo I found hasn’t been touched in 11 years. It also looks more like it applies an effect on an area of the screen, rather than on a layer.

pebble-fctx is still actively maintained, so I will give that a shot and post some working code once I get it running

1 Like

I got it working! (At least an MVP)

static void draw(Layer *layer, GContext *ctx) {
  FContext fctx;
  fctx_init_context(&fctx, ctx);

  fctx_set_fill_color(&fctx, GColorElectricUltramarine);
  fctx_set_color_bias(&fctx, 0);

  // Begin accepting drawing procedures
  fctx_begin_fill(&fctx);

  fctx_set_offset(&fctx, FPointI(30, 30));
  fctx_set_scale(&fctx, FPointI(180,180), FPointI(168,168));

  FFont* font = ffont_create_from_resource(RESOURCE_ID_DIN_LATIN_FFONT);
  fctx_set_text_em_height(&fctx, font, 10);
  fctx_set_text_cap_height(&fctx, font, 10);

  fctx_set_rotation(&fctx, DEG_TO_TRIGANGLE(270));
  fctx_draw_string(&fctx, "Text", font, GTextAlignmentCenter, FTextAnchorMiddle);

  // Draw
  fctx_end_fill(&fctx);

  // Cleanup
  fctx_deinit_context(&fctx);
  ffont_destroy(font);
}

static void load_window(Window *window) {
  Layer *window_layer = window_get_root_layer(window);
  const GRect bounds = layer_get_bounds(window_layer);

  draw_layer = layer_create(bounds);

  layer_set_update_proc(draw_layer, draw);
  layer_add_child(window_get_root_layer(window_layer), draw_layer);

  // Force redraw
  layer_mark_dirty(draw_layer);
}

This library was a pain to work with though. The README is not very helpful, and the code is spread out throughout 3 different repos - pebble-fctx, pebble-utf8, and the npm package fctx-compiler. You will also likely want to know about the repo pebble-laughing-demo since this is the example repo from the author, and it is not linked in the README.

You need the headers and sources from pebble-utf8 to build pebble-fctx which makes me wonder why it is not included as a git submodule of pebble-fctx.

I think you can ignore fctx-compiler, you should be able to supply your own ffont file. However, the docs lead you to installing the npm package fctx-compiler. This will add the npm install command to pebble build if you do not clean up after. The fctx-compiler expects you to supply your own svg definition of a font which it reformats to ffont which you can then add to your package.json resources.

I will probably not end up using pebble-fctx since I hope to turn my graphing code into a library, and using pebble-fctx will make it much less portable. The library also added about a 3.5k increase in ram usage, which is not ideal.

I figured I would leave this code snippet here in case anyone else needs to rotate text. For me, I may look for other ways to display the information that I otherwise would on the Y axis.

2 Likes

They are all NPM packages — just run npm install pebble-fctx and it’ll install all dependencies too, like any other Pebble package

1 Like

If you’re fine with the letters being upright then you can just use a narrow TextLayer and set it to wrap the text

2 Likes

FWIW, I took a look at how other watches display information and found that labeling the Y-Axis is not necessary if the title has enough information

2 Likes