diff --git a/cocos/2d/CCFontAtlas.cpp b/cocos/2d/CCFontAtlas.cpp index 3e40e41419..11f9998d6c 100644 --- a/cocos/2d/CCFontAtlas.cpp +++ b/cocos/2d/CCFontAtlas.cpp @@ -231,6 +231,8 @@ bool FontAtlas::prepareLetterDefinitions(unsigned short *utf16String) auto pixelFormat = fontTTf->getOutlineSize() > 0 ? Texture2D::PixelFormat::AI88 : Texture2D::PixelFormat::A8; bool existNewLetter = false; + int bottomHeight = _commonLineHeight - _fontAscender; + for (int i = 0; i < length; ++i) { auto outIterator = _fontLetterDefinitions.find(utf16String[i]); @@ -248,6 +250,7 @@ bool FontAtlas::prepareLetterDefinitions(unsigned short *utf16String) tempDef.height = tempRect.size.height + _letterPadding; tempDef.offsetX = tempRect.origin.x + offsetAdjust; tempDef.offsetY = _fontAscender + tempRect.origin.y - offsetAdjust; + tempDef.clipBottom = bottomHeight - (tempDef.height + tempRect.origin.y + offsetAdjust); if (_currentPageOrigX + tempDef.width > CacheTextureWidth) { @@ -290,6 +293,7 @@ bool FontAtlas::prepareLetterDefinitions(unsigned short *utf16String) tempDef.offsetX = 0; tempDef.offsetY = 0; tempDef.textureID = 0; + tempDef.clipBottom = 0; _currentPageOrigX += 1; } diff --git a/cocos/2d/CCFontAtlas.h b/cocos/2d/CCFontAtlas.h index 2d3eb615a3..a10fe9eb9f 100644 --- a/cocos/2d/CCFontAtlas.h +++ b/cocos/2d/CCFontAtlas.h @@ -50,6 +50,8 @@ struct FontLetterDefinition int textureID; bool validDefinition; int xAdvance; + + int clipBottom; }; class CC_DLL FontAtlas : public Ref diff --git a/cocos/2d/CCLabel.cpp b/cocos/2d/CCLabel.cpp index 55220b4df4..7314019dac 100644 --- a/cocos/2d/CCLabel.cpp +++ b/cocos/2d/CCLabel.cpp @@ -340,6 +340,8 @@ void Label::reset() _textColor = Color4B::WHITE; _textColorF = Color4F::WHITE; setColor(Color3B::WHITE); + + _clipEnabled = false; } void Label::updateShaderProgram() diff --git a/cocos/2d/CCLabel.h b/cocos/2d/CCLabel.h index 93130c4e10..c2e2be23b8 100644 --- a/cocos/2d/CCLabel.h +++ b/cocos/2d/CCLabel.h @@ -217,6 +217,10 @@ public: virtual Sprite * getLetter(int lettetIndex); + /** clip upper and lower margin for reduce height of label. + */ + void setClipMarginEnabled(bool clipEnabled) { _clipEnabled = clipEnabled; } + bool isClipMarginEnabled() const { return _clipEnabled; } // font related stuff int getCommonLineHeight() const; @@ -365,6 +369,8 @@ protected: Color4B _textColor; Color4F _textColorF; + bool _clipEnabled; + private: CC_DISALLOW_COPY_AND_ASSIGN(Label); diff --git a/cocos/2d/CCLabelTextFormatter.cpp b/cocos/2d/CCLabelTextFormatter.cpp index 9f0efe1eaa..119456caa6 100644 --- a/cocos/2d/CCLabelTextFormatter.cpp +++ b/cocos/2d/CCLabelTextFormatter.cpp @@ -321,6 +321,16 @@ bool LabelTextFormatter::createStringSprites(Label *theLabel) FontLetterDefinition tempDefinition; Point letterPosition; const auto& kernings = theLabel->_horizontalKernings; + + float clipTop = 0; + float clipBottom = 0; + int lineIndex = 0; + bool lineStart = true; + bool clip = false; + if (theLabel->_currentLabelType == Label::LabelType::TTF && theLabel->_clipEnabled) + { + clip = true; + } for (unsigned int i = 0; i < stringLen; i++) { @@ -337,9 +347,10 @@ bool LabelTextFormatter::createStringSprites(Label *theLabel) charYOffset = -1; charAdvance = -1; } - + if (c == '\n') { + lineIndex++; nextFontPositionX = 0; nextFontPositionY -= theLabel->_commonLineHeight; @@ -347,8 +358,30 @@ bool LabelTextFormatter::createStringSprites(Label *theLabel) if(nextFontPositionY < theLabel->_commonLineHeight) break; + lineStart = true; continue; } + else if (clip && tempDefinition.height > 0.0f) + { + if (lineStart) + { + if (lineIndex == 0) + { + clipTop = charYOffset; + } + lineStart = false; + clipBottom = tempDefinition.clipBottom; + } + else if(tempDefinition.clipBottom < clipBottom) + { + clipBottom = tempDefinition.clipBottom; + } + + if (lineIndex == 0 && charYOffset < clipTop) + { + clipTop = charYOffset; + } + } letterPosition.x = (nextFontPositionX + charXOffset + kernings[i]) / contentScaleFactor; letterPosition.y = (nextFontPositionY - charYOffset) / contentScaleFactor; @@ -382,11 +415,26 @@ bool LabelTextFormatter::createStringSprites(Label *theLabel) } tmpSize.height = totalHeight; + if (theLabel->_labelHeight > 0) { tmpSize.height = theLabel->_labelHeight * contentScaleFactor; } + + if (clip) + { + int clipTotal = (clipTop + clipBottom) / contentScaleFactor; + tmpSize.height -= clipTotal * contentScaleFactor; + clipBottom /= contentScaleFactor; + + for (int i = 0; i < theLabel->_limitShowCount; i++) + { + theLabel->_lettersInfo[i].position.y -= clipBottom; + } + } + theLabel->setContentSize(CC_SIZE_PIXELS_TO_POINTS(tmpSize)); + return true; }