I have an add-in which inserts images between lines of text. To make space for the images I increase the line spacing in the text. The problem is I haven't found a way which can consistently and accurately work out where the top and bottom of the text ends up after changing the line spacing.

For example, if you increase the space using SpaceWithin (or manually), space is actually added above and below the lines of text (more above than below), except for the last line where space is only added above. Any BoundTop and BoundHeight values that I can find refer to the line and not to the characters within it.

How can I find the top and height measurements for characters within the lines?

This demonstrates the issue:

Public Sub PositionTest()
  Dim shTextBox As Shape
  Dim i As Long
  
  With ActivePresentation.Slides(1)
    Set shTextBox = .Shapes.AddTextbox(Orientation:=msoTextOrientationHorizontal, _
                         Left:=300, Top:=100, Width:=300, Height:=100)
  End With
    
  With shTextBox.TextFrame.TextRange
      .Text = "Line number: 1" & vbCrLf & "Line number: 2" & vbCrLf & "Line number: 3"
  End With
  
  With shTextBox.TextFrame.TextRange
  For i = 1 To .Lines.Count
    With .Lines(i, 1)
      Debug.Print .Text & " Top: " & .BoundTop & " Height: " & .BoundHeight
    End With
  Next i
  End With
      
  Debug.Print "New spacing"
  With shTextBox.TextFrame.TextRange
    .Lines.ParagraphFormat.LineRuleWithin = msoTrue
    .Lines.ParagraphFormat.SpaceWithin = 3
  End With
     
  With shTextBox.TextFrame.TextRange
  For i = 1 To .Lines.Count
    With .Lines(i, 1)
      Debug.Print .Text & " Top: " & .BoundTop & " Height: " & .BoundHeight
    End With
  Next i
  End With

End Sub
And this is the output that that produces:

Line number: 1
 Top: 103.6 Height: 21.6
Line number: 2
 Top: 125.2 Height: 21.6
Line number: 3 Top: 146.8 Height: 21.6
New spacing
Line number: 1
 Top: 103.6 Height: 64.8
Line number: 2
 Top: 168.4 Height: 64.8
Line number: 3 Top: 233.2 Height: 53.35
If I try to refer to any individual characters - e.g. .Characters(n).BoundTop - the output is the same as for the line in which that character is in.