TextNote Leader Alignment

Let us explore TextNote leader alignment.

Before getting to that, I'll just briefly mention that I still have unused vacation days from last year to use up, so I am going away again, this time on a desert hike near Zagora in Morocco.

Desert dune

No computer, no Internet, no blog...

TextNote Leader Alignment

Here is one last topic before I leave, contributed by my colleague Katsuaki Takamizawa, with help from Jim Jia and Pawel Madej of the Revit development team:

Question: I am calling the NewTextNote method and specifying the leader elbow and text origin at the same height in an attempt to make the second leader segment horizontal.

However, the text is always shifted down a bit like this:

TextNote leader shifted downwards

As you can see, the text is shifted downward in comparison to the horizontal detail line segment.

I produced this test by drawing a detail line vertically and then horizontally, running my add-in and picking the points for the leader end, leader elbow, and text position along this detail line.

How can I make the second leader segment horizontal?

Answer 1: A workaround to make the second segment horizontal is provided by this code snippet:

  // Create text note without leader first
 
  TextNote text = doc.Create.NewTextNote(
    view, ptTextOrigin, baseVec, ptVec,
    lineWidth, textAlign, strText);
 
  // Create leader for the new text: 
  // change the leader elbow and end;
  // note that the elbow's Y should not be 
  // changed to keep horizontal!
 
  if (bLeader)
  {
    Leader noteLeader = text.AddLeader(
      TextNoteLeaderTypes.TNLT_STRAIGHT_R);
 
    // Use default Y!
 
    noteLeader.Elbow = new XYZ (point1.X,
      noteLeader.Elbow.Y, point1.Z );
 
    noteLeader.End = point1;
  }

Note that the workaround unfortunately introduces another issue: the specified elbow end Y doesn’t take effect anymore.

Answer 2: You can combine the desired text alignment flags using bit-wise Boolean operations.

In your original code, you are using

  TextAlignFlags textAlign
    = TextAlignFlags.TEF_ALIGN_CENTER;

Try using this instead:

  TextAlignFlags textAlign
    = TextAlignFlags.TEF_ALIGN_MIDDLE
    | TextAlignFlags.TEF_ALIGN_CENTER;

The result is close to horizontal:

TextNote leader almost horizontal

Response: I combined the two suggested approaches to obtain a very good result.

Here are some resulting samples using different TextAlignFlags values:

TextNote leader alignment

Here is the code that I used to generate these:

  XYZ leaderOrigin = uidoc.Selection.PickPoint(
    "Pick Leader End" );
 
  //XYZ leaderElbow = uidoc.Selection.PickPoint(
  //  "Pick Leader Elbow");
 
  XYZ ptTextOrigin = uidoc.Selection.PickPoint(
    "Pick Text Origin" );
 
  using( Transaction tr = new Transaction( doc ) )
  {
    tr.Start( "NewTextNote" );
 
    XYZ baseVec = XYZ.BasisX;
    XYZ upVec = XYZ.BasisY;
 
    double lineWidth = 0.06;
 
    //TextAlignFlags textAlign 
    //  = TextAlignFlags.TEF_ALIGN_CENTER;
 
    //TextAlignFlags textAlign 
    //  = TextAlignFlags.TEF_ALIGN_MIDDLE 
    //  | TextAlignFlags.TEF_ALIGN_CENTER;
 
    TextAlignFlags textAlign
      = TextAlignFlags.TEF_ALIGN_MIDDLE
      | TextAlignFlags.TEF_ALIGN_RIGHT;
 
    string strText = "ABCDEFGH";
 
    // Create text note without leader first
 
    TextNote text = doc.Create.NewTextNote(
      view, ptTextOrigin, baseVec, baseVec,
      lineWidth, textAlign, strText );
 
    // Create leader for the new text: 
    // change the leader elbow and end;
    // note that the elbow's Y should not be 
    // changed to keep horizontal!
 
    Leader noteLeader = text.AddLeader(
      TextNoteLeaderTypes.TNLT_STRAIGHT_R );
 
    // Use default Y!
 
    noteLeader.Elbow = new XYZ( leaderOrigin.X,
      noteLeader.Elbow.Y, leaderOrigin.Z );
 
    noteLeader.End = leaderOrigin;
 
    tr.Commit();
  }

Many thanks to Katsu-san, Jim and Pawel for this useful research and solution!