X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git;a=blobdiff_plain;f=dali-toolkit%2Finternal%2Ftext%2Frendering%2Ftext-typesetter.cpp;h=2689ffbec17c0483f11d60a649d251486bc0ecfb;hp=826e8941d305a4f874108a175635ad2f32af6bec;hb=e35ca21bd433d168db25fb82306c62f39b69954c;hpb=4764ce1dc9edc7c08766e356c839278204369d73 diff --git a/dali-toolkit/internal/text/rendering/text-typesetter.cpp b/dali-toolkit/internal/text/rendering/text-typesetter.cpp index 826e894..2689ffb 100644 --- a/dali-toolkit/internal/text/rendering/text-typesetter.cpp +++ b/dali-toolkit/internal/text/rendering/text-typesetter.cpp @@ -26,6 +26,7 @@ // INTERNAL INCLUDES #include #include +#include #include #include #include @@ -95,9 +96,9 @@ void TypesetGlyph(GlyphData& data, const int32_t xOffset = data.horizontalOffset + position->x; // Whether the given glyph is a color one. - const bool isColorGlyph = data.glyphBitmap.isColorEmoji || data.glyphBitmap.isColorBitmap; - const uint32_t glyphPixelSize = Pixel::GetBytesPerPixel(data.glyphBitmap.format); - const uint32_t alphaIndex = glyphPixelSize - 1u; + const bool isColorGlyph = data.glyphBitmap.isColorEmoji || data.glyphBitmap.isColorBitmap; + const uint32_t glyphPixelSize = Pixel::GetBytesPerPixel(data.glyphBitmap.format); + const uint32_t glyphAlphaIndex = glyphPixelSize - 1u; // Determinate iterator range. const int32_t lineIndexRangeMin = std::max(0, -yOffset); @@ -113,9 +114,9 @@ void TypesetGlyph(GlyphData& data, if(Pixel::RGBA8888 == pixelFormat) { - const bool swapChannelsBR = Pixel::BGRA8888 == data.glyphBitmap.format; - uint32_t* bitmapBuffer = reinterpret_cast(data.bitmapBuffer.GetBuffer()); + // Skip basic line. + bitmapBuffer += (lineIndexRangeMin + yOffset) * static_cast(data.width); // Fast-cut if style is MASK or OUTLINE. Outline not shown for color glyph. // Just overwrite transparent color and return. @@ -123,17 +124,17 @@ void TypesetGlyph(GlyphData& data, { for(int32_t lineIndex = lineIndexRangeMin; lineIndex < lineIndexRangeMax; ++lineIndex) { - const int32_t yOffsetIndex = yOffset + lineIndex; - const int32_t verticalOffset = yOffsetIndex * data.width; - // We can use memset here. - memset(bitmapBuffer + verticalOffset + xOffset + indexRangeMin, 0, (indexRangeMax - indexRangeMin) * sizeof(uint32_t)); + memset(bitmapBuffer + xOffset + indexRangeMin, 0, (indexRangeMax - indexRangeMin) * sizeof(uint32_t)); + bitmapBuffer += data.width; } return; } + const bool swapChannelsBR = Pixel::BGRA8888 == data.glyphBitmap.format; + // Pointer to the color glyph if there is one. - const uint32_t* const colorGlyphBuffer = isColorGlyph ? reinterpret_cast(data.glyphBitmap.buffer) : NULL; + const uint8_t* glyphBuffer = data.glyphBitmap.buffer; // Precalculate input color's packed result. uint32_t packedInputColor = 0u; @@ -144,21 +145,20 @@ void TypesetGlyph(GlyphData& data, *(packedInputColorBuffer + 1u) = static_cast(color->g * 255); *(packedInputColorBuffer) = static_cast(color->r * 255); + // Skip basic line of glyph. + glyphBuffer += (lineIndexRangeMin) * static_cast(data.glyphBitmap.width) * glyphPixelSize; + // Traverse the pixels of the glyph line per line. - for(int32_t lineIndex = lineIndexRangeMin; lineIndex < lineIndexRangeMax; ++lineIndex) + if(isColorGlyph) { - const int32_t yOffsetIndex = yOffset + lineIndex; - - const int32_t verticalOffset = yOffsetIndex * data.width; - const int32_t glyphBufferOffset = lineIndex * static_cast(data.glyphBitmap.width); - for(int32_t index = indexRangeMin; index < indexRangeMax; ++index) + for(int32_t lineIndex = lineIndexRangeMin; lineIndex < lineIndexRangeMax; ++lineIndex) { - const int32_t xOffsetIndex = xOffset + index; - - if(isColorGlyph) + for(int32_t index = indexRangeMin; index < indexRangeMax; ++index) { + const int32_t xOffsetIndex = xOffset + index; + // Retrieves the color from the color glyph. - uint32_t packedColorGlyph = *(colorGlyphBuffer + glyphBufferOffset + index); + uint32_t packedColorGlyph = *(reinterpret_cast(glyphBuffer + (index << 2))); uint8_t* packedColorGlyphBuffer = reinterpret_cast(&packedColorGlyph); // Update the alpha channel. @@ -192,23 +192,28 @@ void TypesetGlyph(GlyphData& data, } // Set the color into the final pixel buffer. - *(bitmapBuffer + verticalOffset + xOffsetIndex) = packedColorGlyph; + *(bitmapBuffer + xOffsetIndex) = packedColorGlyph; } - else + bitmapBuffer += data.width; + glyphBuffer += data.glyphBitmap.width * glyphPixelSize; + } + } + else + { + for(int32_t lineIndex = lineIndexRangeMin; lineIndex < lineIndexRangeMax; ++lineIndex) + { + for(int32_t index = indexRangeMin; index < indexRangeMax; ++index) { - // Pack the given color into a 32bit buffer. The alpha channel will be updated later for each pixel. - // The format is RGBA8888. - uint32_t packedColor = 0u; - uint8_t* packedColorBuffer = reinterpret_cast(&packedColor); - // Update the alpha channel. - const uint8_t alpha = *(data.glyphBitmap.buffer + glyphPixelSize * (glyphBufferOffset + index) + alphaIndex); + const uint8_t alpha = *(glyphBuffer + index * glyphPixelSize + glyphAlphaIndex); // Copy non-transparent pixels only if(alpha > 0u) { + const int32_t xOffsetIndex = xOffset + index; + // Check alpha of overlapped pixels - uint32_t& currentColor = *(bitmapBuffer + verticalOffset + xOffsetIndex); + uint32_t& currentColor = *(bitmapBuffer + xOffsetIndex); uint8_t* packedCurrentColorBuffer = reinterpret_cast(¤tColor); // For any pixel overlapped with the pixel in previous glyphs, make sure we don't @@ -224,6 +229,11 @@ void TypesetGlyph(GlyphData& data, } else { + // Pack the given color into a 32bit buffer. The alpha channel will be updated later for each pixel. + // The format is RGBA8888. + uint32_t packedColor = 0u; + uint8_t* packedColorBuffer = reinterpret_cast(&packedColor); + // Color is pre-muliplied with its alpha. *(packedColorBuffer + 3u) = MultiplyAndNormalizeColor(*(packedInputColorBuffer + 3u), currentAlpha); *(packedColorBuffer + 2u) = MultiplyAndNormalizeColor(*(packedInputColorBuffer + 2u), currentAlpha); @@ -235,35 +245,38 @@ void TypesetGlyph(GlyphData& data, } } } + bitmapBuffer += data.width; + glyphBuffer += data.glyphBitmap.width * glyphPixelSize; } } } - else + else // Pixel::L8 { // Below codes required only if not color glyph. if(!isColorGlyph) { - uint8_t* bitmapBuffer = reinterpret_cast(data.bitmapBuffer.GetBuffer()); + uint8_t* bitmapBuffer = data.bitmapBuffer.GetBuffer(); + const uint8_t* glyphBuffer = data.glyphBitmap.buffer; + + // Skip basic line. + bitmapBuffer += (lineIndexRangeMin + yOffset) * static_cast(data.width); + glyphBuffer += (lineIndexRangeMin) * static_cast(data.glyphBitmap.width) * glyphPixelSize; // Traverse the pixels of the glyph line per line. for(int32_t lineIndex = lineIndexRangeMin; lineIndex < lineIndexRangeMax; ++lineIndex) { - const int32_t yOffsetIndex = yOffset + lineIndex; - - const int32_t verticalOffset = yOffsetIndex * data.width; - const int32_t glyphBufferOffset = lineIndex * static_cast(data.glyphBitmap.width); for(int32_t index = indexRangeMin; index < indexRangeMax; ++index) { const int32_t xOffsetIndex = xOffset + index; // Update the alpha channel. - const uint8_t alpha = *(data.glyphBitmap.buffer + glyphPixelSize * (glyphBufferOffset + index) + alphaIndex); + const uint8_t alpha = *(glyphBuffer + index * glyphPixelSize + glyphAlphaIndex); // Copy non-transparent pixels only if(alpha > 0u) { // Check alpha of overlapped pixels - uint8_t& currentAlpha = *(bitmapBuffer + verticalOffset + xOffsetIndex); + uint8_t& currentAlpha = *(bitmapBuffer + xOffsetIndex); // For any pixel overlapped with the pixel in previous glyphs, make sure we don't // overwrite a previous bigger alpha with a smaller alpha (in order to avoid @@ -272,6 +285,9 @@ void TypesetGlyph(GlyphData& data, currentAlpha = std::max(currentAlpha, alpha); } } + + bitmapBuffer += data.width; + glyphBuffer += data.glyphBitmap.width * glyphPixelSize; } } } @@ -486,6 +502,8 @@ Devel::PixelBuffer DrawGlyphsBackground(const ViewModel* model, Devel::PixelBuff const Vector4* const backgroundColorsBuffer = model->GetBackgroundColors(); const ColorIndex* const backgroundColorIndicesBuffer = model->GetBackgroundColorIndices(); + const DevelText::VerticalLineAlignment::Type verLineAlign = model->GetVerticalLineAlignment(); + // Create and initialize the pixel buffer. GlyphData glyphData; glyphData.verticalOffset = verticalOffset; @@ -507,13 +525,7 @@ Devel::PixelBuffer DrawGlyphsBackground(const ViewModel* model, Devel::PixelBuff glyphData.horizontalOffset += horizontalOffset; // Increases the vertical offset with the line's ascender. - glyphData.verticalOffset += static_cast(line.ascender); - - // Include line spacing after first line - if(lineIndex > 0u) - { - glyphData.verticalOffset += static_cast(line.lineSpacing); - } + glyphData.verticalOffset += static_cast(line.ascender + GetPreOffsetVerticalLineAlignment(line, verLineAlign)); float left = bufferWidth; float right = 0.0f; @@ -579,7 +591,7 @@ Devel::PixelBuffer DrawGlyphsBackground(const ViewModel* model, Devel::PixelBuff } // Increases the vertical offset with the line's descender. - glyphData.verticalOffset += static_cast(-line.descender); + glyphData.verticalOffset += static_cast(-line.descender + GetPostOffsetVerticalLineAlignment(line, verLineAlign)); } return glyphData.bitmapBuffer; @@ -856,29 +868,6 @@ PixelData Typesetter::Render(const Vector2& size, Toolkit::DevelText::TextDirect } } - // Calculate vertical line alignment - switch(mModel->GetVerticalLineAlignment()) - { - case DevelText::VerticalLineAlignment::TOP: - { - break; - } - case DevelText::VerticalLineAlignment::MIDDLE: - { - const auto& line = *mModel->GetLines(); - penY -= line.descender; - penY += static_cast(line.lineSpacing * 0.5f + line.descender); - break; - } - case DevelText::VerticalLineAlignment::BOTTOM: - { - const auto& line = *mModel->GetLines(); - const auto lineHeight = line.ascender + (-line.descender) + line.lineSpacing; - penY += static_cast(lineHeight - (line.ascender - line.descender)); - break; - } - } - // Generate the image buffers of the text for each different style first, // then combine all of them together as one final image buffer. We try to // do all of these in CPU only, so that once the final texture is generated, @@ -1046,6 +1035,8 @@ Devel::PixelBuffer Typesetter::CreateImageBuffer(const uint32_t& bufferWidth, co const Vector& glyphToCharacterMap = mModel->GetGlyphsToCharacters(); const CharacterIndex* glyphToCharacterMapBuffer = glyphToCharacterMap.Begin(); + const DevelText::VerticalLineAlignment::Type verLineAlign = mModel->GetVerticalLineAlignment(); + // Traverses the lines of the text. for(LineIndex lineIndex = 0u; lineIndex < modelNumberOfLines; ++lineIndex) { @@ -1056,7 +1047,7 @@ Devel::PixelBuffer Typesetter::CreateImageBuffer(const uint32_t& bufferWidth, co glyphData.horizontalOffset += horizontalOffset; // Increases the vertical offset with the line's ascender. - glyphData.verticalOffset += static_cast(line.ascender); + glyphData.verticalOffset += static_cast(line.ascender + GetPreOffsetVerticalLineAlignment(line, verLineAlign)); // Retrieves the glyph's outline width float outlineWidth = static_cast(mModel->GetOutlineWidth()); @@ -1357,7 +1348,7 @@ Devel::PixelBuffer Typesetter::CreateImageBuffer(const uint32_t& bufferWidth, co } // Increases the vertical offset with the line's descender & line spacing. - glyphData.verticalOffset += static_cast(-line.descender + line.lineSpacing); + glyphData.verticalOffset += static_cast(-line.descender + GetPostOffsetVerticalLineAlignment(line, verLineAlign)); } return glyphData.bitmapBuffer;