+/// Draws the specified color to the pixel buffer
+void WriteColorToPixelBuffer(
+ GlyphData& glyphData,
+ uint32_t* bitmapBuffer,
+ const Vector4& color,
+ const unsigned int x,
+ const unsigned int y)
+{
+ // Always RGBA image for text with styles
+ uint32_t pixel = *(bitmapBuffer + y * glyphData.width + x);
+ uint8_t* pixelBuffer = reinterpret_cast<uint8_t*>(&pixel);
+
+ // Write the color to the pixel buffer
+ uint8_t colorAlpha = static_cast<uint8_t>(color.a * 255.f);
+ *(pixelBuffer + 3u) = colorAlpha;
+ *(pixelBuffer + 2u) = static_cast<uint8_t>(color.b * colorAlpha);
+ *(pixelBuffer + 1u) = static_cast<uint8_t>(color.g * colorAlpha);
+ *(pixelBuffer) = static_cast<uint8_t>(color.r * colorAlpha);
+
+ *(bitmapBuffer + y * glyphData.width + x) = pixel;
+}
+
+/// Draws the specified underline color to the buffer
+void DrawUnderline(
+ const unsigned int bufferWidth,
+ const unsigned int bufferHeight,
+ GlyphData& glyphData,
+ const float baseline,
+ const float currentUnderlinePosition,
+ const float maxUnderlineHeight,
+ const float lineExtentLeft,
+ const float lineExtentRight,
+ const UnderlineStyleProperties& commonUnderlineProperties,
+ const UnderlineStyleProperties& currentUnderlineProperties,
+ const LineRun& line)
+{
+ const Vector4& underlineColor = currentUnderlineProperties.colorDefined ? currentUnderlineProperties.color : commonUnderlineProperties.color;
+ const Text::Underline::Type underlineType = currentUnderlineProperties.typeDefined ? currentUnderlineProperties.type : commonUnderlineProperties.type;
+ const float dashedUnderlineWidth = currentUnderlineProperties.dashWidthDefined ? currentUnderlineProperties.dashWidth : commonUnderlineProperties.dashWidth;
+ const float dashedUnderlineGap = currentUnderlineProperties.dashGapDefined ? currentUnderlineProperties.dashGap : commonUnderlineProperties.dashGap;
+
+ int underlineYOffset = glyphData.verticalOffset + baseline + currentUnderlinePosition;
+ uint32_t* bitmapBuffer = reinterpret_cast<uint32_t*>(glyphData.bitmapBuffer.GetBuffer());
+
+ for(unsigned int y = underlineYOffset; y < underlineYOffset + maxUnderlineHeight; y++)
+ {
+ if(y > bufferHeight - 1)
+ {
+ // Do not write out of bounds.
+ break;
+ }
+ if(underlineType == Text::Underline::DASHED)
+ {
+ float dashWidth = dashedUnderlineWidth;
+ float dashGap = 0;
+
+ for(unsigned int x = glyphData.horizontalOffset + lineExtentLeft; x <= glyphData.horizontalOffset + lineExtentRight; x++)
+ {
+ if(x > bufferWidth - 1)
+ {
+ // Do not write out of bounds.
+ break;
+ }
+ if(dashGap == 0 && dashWidth > 0)
+ {
+ WriteColorToPixelBuffer(glyphData, bitmapBuffer, underlineColor, x, y);
+ dashWidth--;
+ }
+ else if(dashGap < dashedUnderlineGap)
+ {
+ dashGap++;
+ }
+ else
+ {
+ //reset
+ dashWidth = dashedUnderlineWidth;
+ dashGap = 0;
+ }
+ }
+ }
+ else
+ {
+ for(unsigned int x = glyphData.horizontalOffset + lineExtentLeft; x <= glyphData.horizontalOffset + lineExtentRight; x++)
+ {
+ if(x > bufferWidth - 1)
+ {
+ // Do not write out of bounds.
+ break;
+ }
+ WriteColorToPixelBuffer(glyphData, bitmapBuffer, underlineColor, x, y);
+ }
+ }
+ }
+ if(underlineType == Text::Underline::DOUBLE)
+ {
+ int secondUnderlineYOffset = underlineYOffset - ONE_AND_A_HALF * maxUnderlineHeight;
+ for(unsigned int y = secondUnderlineYOffset; y < secondUnderlineYOffset + maxUnderlineHeight; y++)
+ {
+ if(y > bufferHeight - 1)
+ {
+ // Do not write out of bounds.
+ break;
+ }
+ for(unsigned int x = glyphData.horizontalOffset + lineExtentLeft; x <= glyphData.horizontalOffset + lineExtentRight; x++)
+ {
+ if(x > bufferWidth - 1)
+ {
+ // Do not write out of bounds.
+ break;
+ }
+ WriteColorToPixelBuffer(glyphData, bitmapBuffer, underlineColor, x, y);
+ }
+ }
+ }
+}
+
+/// Draws the background color to the buffer
+void DrawBackgroundColor(
+ Vector4 backgroundColor,
+ const unsigned int bufferWidth,
+ const unsigned int bufferHeight,
+ GlyphData& glyphData,
+ const float baseline,
+ const LineRun& line,
+ const float lineExtentLeft,
+ const float lineExtentRight)
+{
+ uint32_t* bitmapBuffer = reinterpret_cast<uint32_t*>(glyphData.bitmapBuffer.GetBuffer());
+
+ for(int y = glyphData.verticalOffset + baseline - line.ascender; y < glyphData.verticalOffset + baseline - line.descender; y++)
+ {
+ if((y < 0) || (y > static_cast<int>(bufferHeight - 1)))
+ {
+ // Do not write out of bounds.
+ continue;
+ }
+
+ for(int x = glyphData.horizontalOffset + lineExtentLeft; x <= glyphData.horizontalOffset + lineExtentRight; x++)
+ {
+ if((x < 0) || (x > static_cast<int>(bufferWidth - 1)))
+ {
+ // Do not write out of bounds.
+ continue;
+ }
+
+ WriteColorToPixelBuffer(glyphData, bitmapBuffer, backgroundColor, x, y);
+ }
+ }
+}
+
+Devel::PixelBuffer DrawGlyphsBackground(const ViewModel* model, Devel::PixelBuffer& buffer, const unsigned int bufferWidth, const unsigned int bufferHeight, bool ignoreHorizontalAlignment, int horizontalOffset, int verticalOffset)