function tryFontSize()

in packages/charts/src/chart_types/partition_chart/layout/viewmodel/fill_text_layout.ts [296:417]


function tryFontSize<C>(
  measure: TextMeasure,
  rotation: Radian,
  verticalAlignment: VerticalAlignments,
  horizontalAlignment: HorizontalAlignment,
  container: C,
  getShapeRowGeometry: GetShapeRowGeometry<C>,
  cx: Coordinate,
  cy: Coordinate,
  padding: Padding,
  node: ShapeTreeNode,
  boxes: Box[],
  maxRowCount: number,
  clipText: boolean,
  isRTL: boolean,
) {
  const adjustedHorizontalAlignment = isRTL ? getOppositeAlignment(horizontalAlignment) : horizontalAlignment;
  return function tryFontSizeFn(initialRowSet: RowSet, fontSize: Pixels): { rowSet: RowSet; completed: boolean } {
    let rowSet: RowSet = initialRowSet;

    const wordSpacing = getWordSpacing(fontSize);

    // model text pieces, obtaining their width at the current font size
    const allMeasuredBoxes = boxes.map<RowBox>((box) => {
      const { width } = measure(box.text, box, fontSize);
      return {
        width,
        wordBeginning: NaN,
        ...box,
        fontSize, // iterated fontSize overrides a possible more global fontSize
      };
    });
    const linePitch = fontSize;

    // rowSet building starts
    let targetRowCount = 0;
    let measuredBoxes = allMeasuredBoxes.slice();
    let innerCompleted = false;

    // iterate through possible target row counts
    while (++targetRowCount <= maxRowCount && !innerCompleted) {
      measuredBoxes = allMeasuredBoxes.slice();
      rowSet = {
        id: nodeId(node),
        fontSize,
        fillTextColor: '',
        rotation,
        verticalAlignment,
        horizontalAlignment: adjustedHorizontalAlignment,
        clipText,
        isRTL,
        rows: [...new Array(targetRowCount)].map(() => ({
          rowWords: [],
          rowAnchorX: NaN,
          rowAnchorY: NaN,
          maximumLength: NaN,
          length: NaN,
        })),
        container,
      };

      let currentRowIndex = 0;

      // iterate through rows
      while (currentRowIndex < targetRowCount) {
        const currentRow = rowSet.rows[currentRowIndex];

        if (!currentRow) {
          currentRowIndex++;
          continue;
        }

        const currentRowWords = currentRow.rowWords;

        // current row geometries
        const { maximumRowLength, rowAnchorX, rowAnchorY } = getShapeRowGeometry(
          container,
          cx,
          cy,
          targetRowCount,
          linePitch,
          currentRowIndex,
          fontSize,
          rotation,
          verticalAlignment,
          padding,
        );

        currentRow.rowAnchorX = rowAnchorX;
        currentRow.rowAnchorY = rowAnchorY;
        currentRow.maximumLength = maximumRowLength;

        // row building starts
        let currentRowLength = 0;
        let rowHasRoom = true;

        // iterate through words: keep adding words while there's room
        while (measuredBoxes.length > 0 && rowHasRoom) {
          // adding box to row
          const [currentBox] = measuredBoxes;
          if (!currentBox) continue;
          const wordBeginning = currentRowLength;
          currentRowLength += currentBox.width + wordSpacing;

          if (clipText || currentRowLength <= currentRow.maximumLength) {
            currentRowWords.push({ ...currentBox, wordBeginning });
            currentRow.length = currentRowLength;
            measuredBoxes.shift();
          } else {
            rowHasRoom = false;
          }
        }

        currentRowIndex++;
      }

      innerCompleted = rowSetComplete(rowSet, measuredBoxes);
    }
    const completed = measuredBoxes.length === 0;
    return { rowSet, completed };
  };
}