removeEmptyBlocks() {
    const tmpLines = [];
    for (let k = 0; k < this.lines.length; k++) {
      const line = this.lines[k];

      // Note: an empty line in between text has width zero but is still relevant to layout.
      // So we can't use width for testing empty line here
      if (line.blocks.length === 0) continue;

      // Discard final empty line always
      if (k === this.lines.length - 1) {
        if (line.width === 0) continue;
      }

      const tmpLine = {};
      Object.assign(tmpLine, line);
      tmpLine.blocks = [];

      let firstEmptyBlock;
      const tmpBlocks = [];
      for (let l = 0; l < line.blocks.length; l++) {
        const block = line.blocks[l];
        if (block.width !== 0) {
          tmpBlocks.push(block);
        } else {
          if (firstEmptyBlock === undefined) {
            firstEmptyBlock = block;
          }
        }
      }

      // Ensure that there is *some* text present
      if (tmpBlocks.length === 0 && firstEmptyBlock !== undefined) {
        tmpBlocks.push(firstEmptyBlock);
      }

      tmpLine.blocks = tmpBlocks;

      tmpLines.push(tmpLine);
    }

    return tmpLines;
  }
Remove all empty blocks and empty lines we don't need

This must be done after the width/height determination,
so that these are set properly for processing here.
@returns {Array<Line>} Lines with empty blocks (and some empty lines) removed
@private