cocos2dx實現RichText中英文不被強行截斷


  這幾天需要使用RichText實現富文本的需要,看了下cocos2dx3.3中已實現的RichText,發現寫的還是比較粗糙的。如果在富文本中使用英文的話,分段時會把單詞強行截斷,這是個煩惱的問題,一般英文的換行都是根據“ ”來分段。

  查看問題所在,發現在RichText中的handleTextRenderer(const std::string& text, const std::string& fontName, float fontSize, const Color3B &color, GLubyte opacity)函數中,該函數的作用就是判斷傳入的text是否在改行已超過指定寬度,如果否繼續放該行,否則就打斷text,前部分放該行,后部分放在新的一行中,而他截斷方式竟然是使用平均長度來分,這方式讓人有點。。。於是參考label類的自動換行,自己重寫了handleTextRenderer方法。

  代碼如下:

  

  auto fileExist = FileUtils::getInstance()->isFileExist(fontName);
  Label* textRenderer = nullptr;
  if (fileExist)
  {
    textRenderer = Label::createWithTTF(text, fontName, fontSize);
  }
  else
  {
    textRenderer = Label::createWithSystemFont(text, fontName, fontSize);
  }

  if (!textRenderer){

  return;
  }

  float textRendererWidth = textRenderer->getContentSize().width;
  float leftSpaceWidth = _leftSpaceWidth;
  leftSpaceWidth -= textRendererWidth;
  if (leftSpaceWidth < 0.0f)
  {
  std::string curText = text;
  //尋找空格位置
  int found = text.find_last_of(" ");

  int stringLength = text.length();
  //判斷text是否有空格
  if (found >= stringLength - 1 || found == -1)
  {
    addNewLine();
    handleTextRenderer(curText.c_str(), fontName, fontSize, color, opacity);
  }
  else
  {
    std::string leftWords = Helper::getSubStringOfUTF8String(curText,0,found);
    std::string cutWords = Helper::getSubStringOfUTF8String(curText, found, stringLength - found);

    while (true)
    {
      if (leftWords.length() > 0)
      {
        textRenderer->setString(leftWords);

        float leftRendererWidth = textRenderer->getContentSize().width;
        float tmpLeftSpaceWidth = _leftSpaceWidth;
        tmpLeftSpaceWidth -= leftRendererWidth;

        if (tmpLeftSpaceWidth < 0.0f)
        {
          int leftWordsLen = (int)leftWords.length();
          if (leftWordsLen <= 0)
          {
            break;
          }
          else
          {
            //cut char one by one to get the fit length
            int foundPos = leftWords.find_last_of(" ");

            if (foundPos >= leftWords.length() - 1 || foundPos == -1)
            {
              //剩余字符串已沒有“ ”
              break;
            }
            leftWords = Helper::getSubStringOfUTF8String(text, 0, foundPos);
            cutWords = Helper::getSubStringOfUTF8String(text, foundPos, stringLength - foundPos);
          }
        }
        else {
          //if _leftSpaceWidth > 0 break
          break;
        }
      }
      else {
        //if leftWords is empty, break
        break;
      }
    }

    if (textRenderer)
    {
      textRenderer->setString(leftWords);
      float leftRendererWidth = textRenderer->getContentSize().width;
      float leftSpaceWidth = _leftSpaceWidth;
      leftSpaceWidth -= leftRendererWidth;
      if (leftSpaceWidth < 0)
      {
        addNewLine();
        handleTextRenderer(cutWords.c_str(), fontName, fontSize, color, opacity);

        return;
      }
      else
      {
        _leftSpaceWidth = leftSpaceWidth;

        textRenderer->setColor(color);
        textRenderer->setOpacity(opacity);
        pushToContainer(textRenderer);
      }
    }
    addNewLine();
    handleTextRenderer(cutWords.c_str(), fontName, fontSize, color, opacity);
   }
  }
  else
  {
    _leftSpaceWidth = leftSpaceWidth;

    textRenderer->setColor(color);
    textRenderer->setOpacity(opacity);
    pushToContainer(textRenderer);
  }

  我的思路就是判斷該text是否超框,不是就繼續放這行,是的話就判斷text是否有“ ”,無則新增一行,有“ ”的話逐個判斷“ ”位置前的text內容是否超框,直到找到一個不超框的放在這一行,“ ”后的內容放下一行。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM