X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git;a=blobdiff_plain;f=dali-toolkit%2Finternal%2Ftext%2Frendering%2Fatlas%2Ftext-atlas-renderer.cpp;h=1d8731dcf80ef8949895ca4a6fd45ccaac5101c2;hp=291c187cf97df90713337a0f3f8beb3a65b0baf6;hb=c93f6281a8bafc5b7ba5f0dcdad0eb675b8e3436;hpb=c398078ee3fe4d2edb6e410a33d9e03106d059d0 diff --git a/dali-toolkit/internal/text/rendering/atlas/text-atlas-renderer.cpp b/dali-toolkit/internal/text/rendering/atlas/text-atlas-renderer.cpp index 291c187..1d8731d 100644 --- a/dali-toolkit/internal/text/rendering/atlas/text-atlas-renderer.cpp +++ b/dali-toolkit/internal/text/rendering/atlas/text-atlas-renderer.cpp @@ -161,31 +161,6 @@ struct AtlasRenderer::Impl mQuadVertexFormat["aColor"] = Property::VECTOR4; } - bool - doGlyphHaveStrikethrough(GlyphIndex index, - const Vector& strikethroughRuns, - Vector4& strikethroughColor) - { - for(Vector::ConstIterator it = strikethroughRuns.Begin(), - endIt = strikethroughRuns.End(); - it != endIt; - ++it) - { - const StrikethroughGlyphRun& run = *it; - - if((run.glyphRun.glyphIndex <= index) && (index < run.glyphRun.glyphIndex + run.glyphRun.numberOfGlyphs)) - { - if(run.isColorSet) - { - strikethroughColor = run.color; - } - - return true; - } - } - - return false; - } void CacheGlyph(const GlyphInfo& glyph, FontId lastFontId, const AtlasGlyphManager::GlyphStyle& style, AtlasManager::AtlasSlot& slot) { const Size& defaultTextAtlasSize = mFontClient.GetDefaultTextAtlasSize(); //Retrieve default size of text-atlas-block from font-client. @@ -240,13 +215,35 @@ struct AtlasRenderer::Impl glyphBufferData, style.outline); + uint32_t glyphBufferSize = glyphBufferData.width * glyphBufferData.height * Pixel::GetBytesPerPixel(glyphBufferData.format); + // If glyph buffer data don't have ownership, Or if we need to decompress, create new memory and replace ownership. + if(!glyphBufferData.isBufferOwned || glyphBufferData.compressionType != TextAbstraction::FontClient::GlyphBufferData::CompressionType::NO_COMPRESSION) + { + uint8_t* newBuffer = (uint8_t*)malloc(glyphBufferSize); + if(DALI_LIKELY(newBuffer != nullptr)) + { + TextAbstraction::FontClient::GlyphBufferData::Decompress(glyphBufferData, newBuffer); + if(glyphBufferData.isBufferOwned) + { + // Release previous buffer + free(glyphBufferData.buffer); + } + glyphBufferData.isBufferOwned = true; + glyphBufferData.buffer = newBuffer; + glyphBufferData.compressionType = TextAbstraction::FontClient::GlyphBufferData::CompressionType::NO_COMPRESSION; + } + } + // Create the pixel data. bitmap = PixelData::New(glyphBufferData.buffer, - glyphBufferData.width * glyphBufferData.height * GetBytesPerPixel(glyphBufferData.format), + glyphBufferSize, glyphBufferData.width, glyphBufferData.height, glyphBufferData.format, - PixelData::DELETE_ARRAY); + PixelData::FREE); + + // Change buffer ownership. + glyphBufferData.isBufferOwned = false; if(bitmap) { @@ -337,6 +334,10 @@ struct AtlasRenderer::Impl vertex.mColor = color; } + // Since Free Type font doesn't contain the strikethrough-position property, + // strikethrough position will be calculated by moving the underline position upwards by half the value of the line height. + float strikethroughStartingYPosition = (position.y + glyph.yBearing + currentUnderlinePosition) - ((glyph.height) * HALF); + // Find an existing mesh data object to attach to ( or create a new one, if we can't find one using the same atlas) StitchTextMesh(meshContainer, newMesh, @@ -347,7 +348,7 @@ struct AtlasRenderer::Impl currentlineThickness, slot, underlineChunkId, - position.y + (glyph.height * HALF), + strikethroughStartingYPosition, strikethroughChunkId); } @@ -453,9 +454,6 @@ struct AtlasRenderer::Impl const Length* hyphenIndices = view.GetHyphenIndices(); const Length hyphensCount = view.GetHyphensCount(); const bool strikethroughEnabled = view.IsStrikethroughEnabled(); - const Vector4& strikethroughColor(view.GetStrikethroughColor()); - const float strikethroughHeight = view.GetStrikethroughHeight(); - Vector4 currentStrikethroughColor; const float characterSpacing(view.GetCharacterSpacing()); // Elided text info. Indices according to elided text. @@ -496,14 +494,18 @@ struct AtlasRenderer::Impl strikethroughRuns.Resize(numberOfStrikethroughRuns); view.GetStrikethroughRuns(strikethroughRuns.Begin(), 0u, numberOfStrikethroughRuns); - bool thereAreUnderlinedGlyphs = false; - bool strikethroughGlyphsExist = false; + const StrikethroughStyleProperties viewStrikethroughProperties{view.GetStrikethroughColor(), + view.GetStrikethroughHeight(), + true, + true}; + + float maxStrikethroughHeight = viewStrikethroughProperties.height; - float currentUnderlinePosition = ZERO; - float currentStrikethroughHeight = strikethroughHeight; - float maxStrikethroughHeight = currentStrikethroughHeight; - FontId lastFontId = 0; - Style style = STYLE_NORMAL; + FontId lastFontId = 0; + Style style = STYLE_NORMAL; + float currentUnderlinePosition = ZERO; + bool thereAreUnderlinedGlyphs = false; + bool thereAreStrikethroughGlyphs = false; if(fabsf(shadowOffset.x) > Math::MACHINE_EPSILON_1 || fabsf(shadowOffset.y) > Math::MACHINE_EPSILON_1) { @@ -525,8 +527,12 @@ struct AtlasRenderer::Impl std::map mapUnderlineChunkIdWithProperties; // mapping underlineChunkId with UnderlineStyleProperties to get properties of underlined chunk UnderlineStyleProperties preUnderlineProperties = viewUnderlineProperties; // the previous UnderlineStyleProperties - uint32_t strikethroughChunkId = 0u; // give id for each chunk. - bool isPrevGlyphStrikethrough = false; // status of strikethrough for previous glyph. + //For septated strikethrough chunks. (this is for Markup case) + uint32_t strikethroughChunkId = 0u; // give id for each chunk. + bool isPreStrikethrough = false; // status of strikethrough for previous glyph. + std::map mapStrikethroughChunkIdWithProperties; // mapping strikethroughChunkId with StrikethroughStyleProperties to get properties of strikethrough chunk + StrikethroughStyleProperties preStrikethroughProperties = viewStrikethroughProperties; // the previous StrikethroughStyleProperties + const Character* textBuffer = view.GetTextBuffer(); float calculatedAdvance = 0.f; const Vector& glyphToCharacterMap = view.GetGlyphsToCharacters(); @@ -568,16 +574,17 @@ struct AtlasRenderer::Impl float currentUnderlineHeight = currentUnderlineProperties.height; thereAreUnderlinedGlyphs = thereAreUnderlinedGlyphs || isGlyphUnderlined; - currentStrikethroughColor = strikethroughColor; - const bool isStrikethroughGlyph = strikethroughEnabled || doGlyphHaveStrikethrough(i, strikethroughRuns, currentStrikethroughColor); - strikethroughGlyphsExist = strikethroughGlyphsExist || isStrikethroughGlyph; + Vector::ConstIterator currentStrikethroughGlyphRunIt = strikethroughRuns.End(); + const bool isGlyphStrikethrough = strikethroughEnabled || IsGlyphStrikethrough(i, strikethroughRuns, currentStrikethroughGlyphRunIt); + const StrikethroughStyleProperties currentStrikethroughProperties = GetCurrentStrikethroughProperties(i, isGlyphStrikethrough, strikethroughRuns, currentStrikethroughGlyphRunIt, viewStrikethroughProperties); + float currentStrikethroughHeight = currentStrikethroughProperties.height; + thereAreStrikethroughGlyphs = thereAreStrikethroughGlyphs || isGlyphStrikethrough; // No operation for white space if(glyph.width && glyph.height) { // Check and update decorative-lines informations - if((isGlyphUnderlined || isStrikethroughGlyph) && - ((glyph.fontId != lastDecorativeLinesFontId) || !(currentUnderlineProperties.IsHeightEqualTo(preUnderlineProperties)))) + if(isGlyphUnderlined || isGlyphStrikethrough) { bool isDecorativeLinesFontIdUpdated = false; // Are we still using the same fontId as previous @@ -588,7 +595,7 @@ struct AtlasRenderer::Impl isDecorativeLinesFontIdUpdated = true; fontClient.GetFontMetrics(lastDecorativeLinesFontId, lastDecorativeLinesFontMetrics); - if(isStrikethroughGlyph || isGlyphUnderlined) + if(isGlyphStrikethrough || isGlyphUnderlined) { //The currentUnderlinePosition will be used for both Underline and/or Strikethrough currentUnderlinePosition = FetchUnderlinePositionFromFontMetrics(lastDecorativeLinesFontMetrics); @@ -606,8 +613,14 @@ struct AtlasRenderer::Impl CalcualteUnderlineHeight(lastDecorativeLinesFontMetrics, currentUnderlineHeight, maxUnderlineHeight); } - if(isDecorativeLinesFontIdUpdated && isStrikethroughGlyph) + if(isGlyphStrikethrough && (isDecorativeLinesFontIdUpdated || !(currentStrikethroughProperties.IsHeightEqualTo(preStrikethroughProperties)))) { + //If the Strikethrough Height is changed then we need to recalculate height. + if(!(currentStrikethroughProperties.IsHeightEqualTo(preStrikethroughProperties))) + { + maxStrikethroughHeight = currentStrikethroughHeight; + } + CalcualteStrikethroughHeight(currentStrikethroughHeight, maxStrikethroughHeight); } } // decorative-lines @@ -680,14 +693,22 @@ struct AtlasRenderer::Impl false, 0u); - if(isStrikethroughGlyph) + if(isGlyphStrikethrough) { + //The new strikethrough chunk. Add new id if they are not consecutive indices (this is for Markup case) + // Examples: "Hello World Hello World", "World Hello World", " World Hello World" + if((!isPreStrikethrough) || (preStrikethroughProperties != currentStrikethroughProperties)) + { + strikethroughChunkId++; + mapStrikethroughChunkIdWithProperties.insert(std::pair(strikethroughChunkId, currentStrikethroughProperties)); + } + GenerateMesh(glyph, positionPlusOutlineOffset, color, NO_OUTLINE, slot, - strikethroughGlyphsExist, + isGlyphStrikethrough, 0.0f, maxStrikethroughHeight, meshContainer, @@ -698,6 +719,10 @@ struct AtlasRenderer::Impl strikethroughChunkId); } + //Keep status of Strikethrough for previous glyph to check consecutive indices + isPreStrikethrough = isGlyphStrikethrough; + preStrikethroughProperties = currentStrikethroughProperties; + lastFontId = glyph.fontId; // Prevents searching for existing blocksizes when string of the same fontId. } @@ -718,13 +743,6 @@ struct AtlasRenderer::Impl false, 0u); } - - if(isPrevGlyphStrikethrough && !isStrikethroughGlyph) - { - strikethroughChunkId++; - } - - isPrevGlyphStrikethrough = isStrikethroughGlyph; } if(addHyphen) @@ -743,10 +761,10 @@ struct AtlasRenderer::Impl GenerateUnderlines(meshContainer, extents, viewUnderlineProperties, mapUnderlineChunkIdWithProperties); } - if(strikethroughGlyphsExist) + if(thereAreStrikethroughGlyphs) { // Check to see if any of the text needs a strikethrough - GenerateStrikethrough(meshContainer, strikethroughExtents, currentStrikethroughColor); + GenerateStrikethrough(meshContainer, strikethroughExtents, viewStrikethroughProperties, mapStrikethroughChunkIdWithProperties); } // For each MeshData object, create a mesh actor and add to the renderable actor @@ -784,11 +802,14 @@ struct AtlasRenderer::Impl Toolkit::AtlasGlyphManager::Metrics metrics = mGlyphManager.GetMetrics(); DALI_LOG_INFO(gLogFilter, Debug::General, "TextAtlasRenderer::GlyphManager::GlyphCount: %i, AtlasCount: %i, TextureMemoryUse: %iK\n", metrics.mGlyphCount, metrics.mAtlasMetrics.mAtlasCount, metrics.mAtlasMetrics.mTextureMemoryUsed / 1024); - DALI_LOG_INFO(gLogFilter, Debug::Verbose, "%s\n", metrics.mVerboseGlyphCounts.c_str()); - - for(uint32_t i = 0; i < metrics.mAtlasMetrics.mAtlasCount; ++i) + if(gLogFilter->IsEnabledFor(Debug::Verbose)) { - DALI_LOG_INFO(gLogFilter, Debug::Verbose, " Atlas [%i] %sPixels: %s Size: %ix%i, BlockSize: %ix%i, BlocksUsed: %i/%i\n", i + 1, i > 8 ? "" : " ", metrics.mAtlasMetrics.mAtlasMetrics[i].mPixelFormat == Pixel::L8 ? "L8 " : "BGRA", metrics.mAtlasMetrics.mAtlasMetrics[i].mSize.mWidth, metrics.mAtlasMetrics.mAtlasMetrics[i].mSize.mHeight, metrics.mAtlasMetrics.mAtlasMetrics[i].mSize.mBlockWidth, metrics.mAtlasMetrics.mAtlasMetrics[i].mSize.mBlockHeight, metrics.mAtlasMetrics.mAtlasMetrics[i].mBlocksUsed, metrics.mAtlasMetrics.mAtlasMetrics[i].mTotalBlocks); + DALI_LOG_INFO(gLogFilter, Debug::Verbose, "%s\n", metrics.mVerboseGlyphCounts.c_str()); + + for(uint32_t i = 0; i < metrics.mAtlasMetrics.mAtlasCount; ++i) + { + DALI_LOG_INFO(gLogFilter, Debug::Verbose, " Atlas [%i] %sPixels: %s Size: %ix%i, BlockSize: %ix%i, BlocksUsed: %i/%i\n", i + 1, i > 8 ? "" : " ", metrics.mAtlasMetrics.mAtlasMetrics[i].mPixelFormat == Pixel::L8 ? "L8 " : "BGRA", metrics.mAtlasMetrics.mAtlasMetrics[i].mSize.mWidth, metrics.mAtlasMetrics.mAtlasMetrics[i].mSize.mHeight, metrics.mAtlasMetrics.mAtlasMetrics[i].mSize.mBlockWidth, metrics.mAtlasMetrics.mAtlasMetrics[i].mSize.mBlockHeight, metrics.mAtlasMetrics.mAtlasMetrics[i].mBlocksUsed, metrics.mAtlasMetrics.mAtlasMetrics[i].mTotalBlocks); + } } #endif } @@ -1226,9 +1247,10 @@ struct AtlasRenderer::Impl } } - void GenerateStrikethrough(std::vector& meshRecords, - Vector& extents, - const Vector4& strikethroughColor) + void GenerateStrikethrough(std::vector& meshRecords, + Vector& extents, + const StrikethroughStyleProperties& viewStrikethroughProperties, + const std::map& mapStrikethroughChunkIdWithProperties) { AtlasManager::Mesh2D newMesh; unsigned short faceIndex = 0; @@ -1241,6 +1263,14 @@ struct AtlasRenderer::Impl uint32_t index = eIt->mMeshRecordIndex; Vector2 uv = mGlyphManager.GetAtlasSize(meshRecords[index].mAtlasId); + auto pairStrikethroughChunkIdWithProperties = mapStrikethroughChunkIdWithProperties.find(eIt->mStrikethroughChunkId); + + const StrikethroughStyleProperties strikethroughProperties = (pairStrikethroughChunkIdWithProperties == mapStrikethroughChunkIdWithProperties.end()) + ? viewStrikethroughProperties + : pairStrikethroughChunkIdWithProperties->second; + + const Vector4& strikethroughColor = strikethroughProperties.colorDefined ? strikethroughProperties.color : viewStrikethroughProperties.color; + // Make sure we don't hit texture edge for single pixel texture ( filled pixel is in top left of every atlas ) float u = HALF / uv.x; float v = HALF / uv.y;