justifyElements method

void justifyElements(
  1. ChantContext ctxt,
  2. bool doJustify,
  3. List<CondensableSpace> condensableSpaces
)

Implementation

void justifyElements(
  ChantContext ctxt,
  bool doJustify,
  List<CondensableSpace> condensableSpaces,
) {
  int i;
  var toJustify = this.toJustify;
  final notations = score.notations;
  final lastIndex = notationsStartIndex + numNotationsOnLine;

  final lastNotation =
      (notationsStartIndex + numNotationsOnLine - 1 >= 0 &&
          notationsStartIndex + numNotationsOnLine - 1 < notations.length)
      ? notations[notationsStartIndex + numNotationsOnLine - 1]
      : null;
  double extraSpaceBeforeCustos = 0;
  if (staffRight < double.infinity &&
      custos != null &&
      (lastNotation?.keepWithNext ?? false) &&
      custos!.bounds.x -
              lastNotation!.bounds.right -
              lastNotation.calculatedTrailingSpace >
          0) {
    extraSpaceBeforeCustos =
        custos!.bounds.x -
        lastNotation.bounds.right -
        lastNotation.calculatedTrailingSpace;
  }
  if (extraSpaceBeforeCustos > 0) {
    i = 0;
    while (lastLyrics.isNotEmpty && i < lastLyrics.length) {
      final lyrics = lastLyrics[i];
      if (lyrics.allowsConnector) {
        final connectorWidth = lyrics.getConnectorWidth();
        if (ctxt.minLyricWordSpacing < connectorWidth) {
          double minHyphenWidth = (lastLyrics.length > 1)
              ? ctxt.intraNeumeSpacing
              : ctxt.minLyricWordSpacing;
          lyrics.setConnectorWidth(
            (connectorWidth - extraSpaceBeforeCustos > minHyphenWidth)
                ? connectorWidth - extraSpaceBeforeCustos
                : minHyphenWidth,
          );
        }
      }
      i++;
    }
    custos!.bounds = custos!.bounds.copyWith(
      x: lastNotation!.bounds.right + lastNotation.calculatedTrailingSpace,
    );
  }

  final extraSpace = getWhitespaceOnRight(ctxt);

  if (extraSpace.abs() < 0.5 ||
      (extraSpace > 0 && ((doJustify && toJustify.isEmpty) || !doJustify))) {
    return;
  }

  this.condensableSpaces = condensableSpaces;

  ChantNotationElement? curr;
  ChantNotationElement? prev;
  double offset = 0;
  double increment = extraSpace / toJustify.length;
  double multiplier = 0;
  int toJustifyIndex = 0;
  if (extraSpace < 0) {
    toJustify = condensableSpaces.where((s) => s.condensable > 0).toList();
    multiplier =
        extraSpace /
        (condensableSpaces.fold(0.0, (sum, s) => sum + s.condensable));
    increment = 0;
  }
  dynamic nextToJustify = (toJustifyIndex < toJustify.length)
      ? toJustify[toJustifyIndex++]
      : null;
  bool incrementOffsetAtNextChance = false;
  for (i = notationsStartIndex; i < lastIndex; i++) {
    prev = curr;
    curr = notations[i];

    if (extraTextOnlyIndex != null &&
        i >= extraTextOnlyIndex! &&
        curr is TextOnly) {
      continue;
    }

    if (multiplier == 0 && curr == custos) {
      if (curr.hasLyrics) {
        curr.bounds = curr.bounds.copyWith(
          x:
              (curr.bounds.x +
                      (staffRight - LyricArray.getRight(curr.lyrics)) <
                  staffRight - curr.bounds.width)
              ? curr.bounds.x +
                    (staffRight - LyricArray.getRight(curr.lyrics))
              : staffRight - curr.bounds.width,
        );
        offset += increment;
      } else {
        curr.bounds = curr.bounds.copyWith(
          x: (curr.bounds.x + offset < staffRight - curr.bounds.width)
              ? curr.bounds.x + offset
              : staffRight - curr.bounds.width,
        );
      }
      continue;
    }

    if (multiplier != 0) {
      if (nextToJustify != null && nextToJustify.notation == curr) {
        offset += multiplier * nextToJustify.condensable;
        nextToJustify = (toJustifyIndex < toJustify.length)
            ? toJustify[toJustifyIndex++]
            : null;
      }
    } else if (nextToJustify == curr) {
      if (prev!.hasNoWidth) {
        incrementOffsetAtNextChance = true;
      } else {
        offset += increment;
      }
      nextToJustify = (toJustifyIndex < toJustify.length)
          ? toJustify[toJustifyIndex++]
          : null;
    } else if (incrementOffsetAtNextChance && !prev!.hasNoWidth) {
      incrementOffsetAtNextChance = false;
      offset += increment;
    }

    curr.bounds = curr.bounds.copyWith(x: curr.bounds.x + offset);
  }

  if (extraSpaceBeforeCustos > 0) {
    custos!.bounds = custos!.bounds.copyWith(
      x: lastNotation!.bounds.right + lastNotation.calculatedTrailingSpace,
    );
  }
}