Author Topic: Issue with PrintExactCharacterPositions and multi line labels?  (Read 5067 times)

sburgoon

  • Newbie
  • *
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 19
    • View Profile
So I'm working on a relatively complex label hack to allow me to encode input data, then hide it and display a rendered sprite of the input in question over top. I have it working (finally), but I ran into a really weird bug, or at least what seems like a bug. While using PrintExactCharacterPositions I got great results so long as the label was a single line. As soon as wrapping occurs however I'm finding my verts are off in their X position by some multiple of how many lines from the top of the label they are. To put another way, the verts array for the first line is perfect, second line is off in X by 1*n, 3rd is off by 2*n, and on like that.

Its a pretty hard to show what's going on, hence the lack of images. Here is a section of the code that may be relevant (I've stripped a bunch of stuff out of the actual function that isn't relevant to the NGUI side, so if it looks a bit out of context that's why):

  1. targetLabel.UpdateNGUIText();
  2.         lastText = NGUIText.StripSymbols(targetLabel.processedText);
  3.  
  4.         string textSoFar = "";
  5.         Vector2 offset = targetLabel.pivotOffset;
  6.  
  7.         BetterList<Vector3> verts = new BetterList<Vector3>();
  8.         BetterList<int> indicies = new BetterList<int>();
  9.  
  10.         NGUIText.Update();
  11.         NGUIText.PrintApproximateCharacterPositions(targetLabel.processedText, verts, indicies);
  12.  
  13.         Vector2 characterSize = NGUIText.CalculatePrintedSize("O");
  14.         Bounds b = targetLabel.CalculateBounds();
  15.  
  16.         string[] tokens = lastText.Split(new char[] {' ', '\n'}, System.StringSplitOptions.None);
  17.         int idx = 0;
  18.         foreach(string tok in tokens) {
  19.                 if (tok.StartsWith("$i:")) {
  20.  
  21.                         Vector3 vertA = verts[(textSoFar.Length) * 2];
  22.                         Vector3 vertB = verts[(textSoFar.Length + tok.Length) * 2 - 1];
  23.  
  24.                         int defIdx = int.Parse(tok.Substring(3).Replace("@", ""));
  25.                         UiManager.InputSpriteEntry ie = GameManager.uiManager.inputSpriteDefs[defIdx];
  26.  
  27.                         UISprite sprite = NGUITools.AddSprite(targetLabel.gameObject, GameManager.uiManager.defaultAtlas, ie.sprite);
  28.  
  29.                         sprite.depth = 200;
  30.                         sprite.MakePixelPerfect();
  31.                         sprite.keepAspectRatio = UIWidget.AspectRatioSource.BasedOnHeight;
  32.                         sprite.height = fixedSize ? (int)scaleFactor : (int)(characterSize.y * scaleFactor);
  33.                         if (forceCenter) {
  34.                                 sprite.transform.localPosition = Vector3.zero;
  35.                         } else {
  36.                                 Vector3 pos = (vertA + vertB) * 0.5f;
  37.                                 pos.x -= offset.x * b.size.x ;
  38.                                 pos.y += (1f - offset.y) * b.size.y;
  39.                                 sprite.transform.localPosition = pos;
  40.                         }
  41.                 }
  42.                 if (idx == tokens.Length - 1) {
  43.                         textSoFar = string.Format("{0}{1}", textSoFar, tok);
  44.                 } else {
  45.                         textSoFar = string.Format("{0}{1}{2}", textSoFar, tok, lastText[textSoFar.Length + tok.Length]);
  46.                 }
  47.                 idx++;         
  48.         }
  49. }
  50.  

Oddly, PrintApproximateCharacterPositions seems more accurate for multiline labels, so I'm using that for now as the overall error is lower, but would be awesome to get Exact working. Any ideas  more than welcome.

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: Issue with PrintExactCharacterPositions and multi line labels?
« Reply #1 on: June 24, 2016, 01:11:46 AM »
You need to call UILabel's UpdateNGUIText() function before doing any NGUIText calls. Also check what pivot you have it set to.

sburgoon

  • Newbie
  • *
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 19
    • View Profile
Re: Issue with PrintExactCharacterPositions and multi line labels?
« Reply #2 on: June 25, 2016, 03:52:34 PM »
I'm calling UpdateNGUIText in the first line of what I pasted (though it looks like the indenting is wrong on the first line so I can see how you missed that).

Also, I believe I am correctly accounting for alignment by how I am using targetLabel.pivotOffset (I assign that to my "offset" var and use that in my positioning later in the pasted code).

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: Issue with PrintExactCharacterPositions and multi line labels?
« Reply #3 on: June 27, 2016, 06:25:58 AM »
Ah, yes I missed that. It looked like a function name to me at a brief glance. So changing the actual pivot point of the label has no effect on the result? Top-left would be my choice. Just a note btw, when you strip symbols from text, it returns the text without them entirely. So if you had something like "[ff0000]red text[/c]" you will end up with "red text". I'm not sure stripping symbols would be the way to go in your case. If I was doing this, I would take the NGUIText.Print function and just replace it with a custom one that would do something in the GetSymbol part on line 1470 -- perhaps store the symbol entries in a list that can then be accessed outside the function. Unfortunately I don't have a more concrete suggestion.

sburgoon

  • Newbie
  • *
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 19
    • View Profile
Re: Issue with PrintExactCharacterPositions and multi line labels?
« Reply #4 on: June 30, 2016, 01:43:25 AM »
Actually, looking into making a custom NGUIText.Print might be a good way to go. Thanks for the suggestion. I'll look into that this weekend.

sburgoon

  • Newbie
  • *
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 19
    • View Profile
Re: Issue with PrintExactCharacterPositions and multi line labels?
« Reply #5 on: June 30, 2016, 01:54:18 AM »
Oh, and to answer your other question, no, changing pivot or alignment has no effect on the offset. No matter what combination of the two the sprite always renders in the same (slightly wrong) position based on which line of the multiline label it is.

sburgoon

  • Newbie
  • *
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 19
    • View Profile
Re: Issue with PrintExactCharacterPositions and multi line labels?
« Reply #6 on: June 30, 2016, 02:33:05 AM »
Welp, figured it out. Now I feel dumb. In case anyone stumbles on this, the issue is that PrintExactCharacterPositions needs the processedText (so that it has the newline characters), which makes sense. However, the vertex buffers it outputs don't include entries for the newline character, which also makes sense in retrospect. So, if you're crawling a string/tokens like I am and tracking your current index, you need to ignore any newlines when calculating your vertex buffer idx. Everything now lines up perfectly regardless of alignment/pivot/line number.

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: Issue with PrintExactCharacterPositions and multi line labels?
« Reply #7 on: July 01, 2016, 10:48:29 PM »
I'm glad you figured it out!