Adapt font size and center a text label widget

Hi,

I try to center a text label widget within a parent container. So far I achieved this goal provided the text label font size is a constant.
What I would like to do now is to adapt the font size of the text widget in case the text does not fit its parent container.

The function below takes as a parameter the maximum font size and decreases it until the text label is correctly printed into its container. However I have some flickering problems as my widgets are redrawn every second.
I tried to use PtHold and PtRelease functions with some improvements but flickering has not dissapeared for sure. I even tried PtContainerHold and PtContainerRelease… :unamused:

Besides, I would like to avoid to use an OS container !

Any ideas ?

void PrintCenteredTextToWidgetWithAdaptativeFontSize(PtWidget_t *widget,
    char *str, uint16_t fontSize, PtWidget_t *container) {
  PtHold();

  //PtContainerHold(widget);
  PtSetResource(widget, Pt_ARG_RESIZE_FLAGS , Pt_TRUE, Pt_RESIZE_XY_ALWAYS);
  do {
    PrintTextToWidgetWithFontSize(widget, str, fontSize);
    fontSize--;
  } while ((CenterWidgetToParentContainer(widget, container) == false)
      && (fontSize > 1));
  //PtContainerRelease(widget);
  PtRelease();
}
//----------------------------------------------------------------------------
bool CenterWidgetToParentContainer(PtWidget_t *pwidget, PtWidget_t *pcontainer) {
  PhArea_t *lWidgetArea, *lContainerArea, lWidgetCopyArea;
  bool lbalign = true;
  PhRect_t lcanvas;
  /** Calculate the container canvas (raw zone) */
  PtCalcCanvas(pcontainer, &lcanvas);
  if ((pwidget != NULL) && (pcontainer != NULL)) {
    PtGetResource(pwidget, Pt_ARG_AREA, &lWidgetArea,0);
    PtGetResource(pcontainer, Pt_ARG_AREA, &lContainerArea,0);

    lWidgetCopyArea = *lWidgetArea;
    /* Horizontal alignment */
    if (lWidgetArea->size.w < lContainerArea->size.w) {
      lWidgetCopyArea.pos.x = ((lcanvas.lr.x-lcanvas.ul.x) - lWidgetArea->size.w)
          / 2;
      PtSetResource(pwidget, Pt_ARG_AREA, &lWidgetCopyArea,0);

    } else {
      lbalign = false;
    }
    /* Vertical alignment */
    if (lWidgetArea->size.h < lContainerArea->size.h) {
      lWidgetCopyArea.pos.y = ((lcanvas.lr.y-lcanvas.ul.y) - lWidgetArea->size.h)
          / 2;
      PtSetResource(pwidget, Pt_ARG_AREA, &lWidgetCopyArea,0);
    } else {
      lbalign = false;
    }
  } else {
    lbalign = false;

  }
//----------------------------------------------------------------------------
void PrintTextToWidgetWithFontSize(PtWidget_t *widget, char *str, uint16_t fontSize) {
  if (widget != NULL) {
    ChangeFontSize(widget, fontSize);
    PtSetResource(widget, Pt_ARG_TEXT_STRING, str, 0);
  } else {
    fprintf(stderr, "PrintTextToWidget: unknown instance of widget\n");
  }
}
//----------------------------------------------------------------------------
void ChangeFontSize(PtWidget_t *pwidget, int fontSize) {
  char szTextFont[MAX_FONT_TAG];
  PtSetResource(pwidget, Pt_ARG_TEXT_FONT, (long)PfGenerateFontName("TextFont", PF_STYLE_BOLD, fontSize,
          szTextFont),
      0L);

}

Thanks !

KB.

In the meantime I bypassed the problem by recalculating the font size if the text to display changed.
Anyone got a better solution?

Thx.

The PfExtentText() function is interesting. It calculates the extent rectangle of a text string.
However I think I’m not using it properly.
I code this little function to evaluate the best font size to fit a container dimension. But the results are wrong. The font size is too big and the text is out of its container:

int DetermineOptFontSize(PtWidget_t *pwidget, int maxFontSize, char *str) {
    int lfontSize = maxFontSize;
  if (pwidget != NULL) {
    PhRect_t tsExtent, lwidgetRect;
    PhPoint_t tsPos = { 0, 0 }, tsPosOffset = { 0, 0 };
    char szFont[MAX_FONT_TAG];
    bool lexit = false;
    uint16_t lwidthCanvas, lwidthText;
    PtCalcCanvas(pwidget, &lwidgetRect);

    do {
      PfGenerateFontName("TextFont", PF_STYLE_BOLD, lfontSize, szFont);
      PfExtentText(&tsExtent, NULL, szFont, str, strlen(str));
      if (lfontSize > 0) {
        lfontSize--;
        lwidthText = (tsExtent.lr.y - tsExtent.ul.y);
        lwidthCanvas = (lwidgetRect.lr.y - lwidgetRect.ul.y);
        printf("\tlwidthText=%u\tlwidthCanvas=%u\n",lwidthText,lwidthCanvas);
        if (lwidthCanvas <= (lwidthText)) {
          lexit = false;
        } else {
          lexit = true;
        }
      } else {
        lexit = true;
      }
      printf(" \tchar = %s len = %i lfontSize = %u\n",str, strlen(str), lfontSize);
    } while (lexit == false);
  }
    return (lfontSize);
}

Any idea ?

Thanks.