@@ -131,7 +131,7 @@ void PNGPlotter::drawYGrid() {
131131 std::string numberY = oss.str ();
132132 if (i != 0 )
133133 {
134- GraphLabel (width - margin_right, y, numberY, 300 , 100 , 300 / 4 );
134+ GraphLabel (width - margin_right, y, numberY, 600 , 100 , 100 );
135135 }
136136
137137 }
@@ -243,7 +243,7 @@ void PNGPlotter::drawXGrid(int64_t start, int64_t end)
243243 int x = margin_left + i * step;
244244 drawLine (x, 0 , x, height - margin_top - margin_bottom, gridColor);
245245
246- GraphLabel (x, height - margin_top - margin_bottom, verticalLines[i], 300 , -(300 /4 ), 300 / 2 );
246+ GraphLabel (x, height - margin_top - margin_bottom, verticalLines[i], 600 , -(600 /4 ), 600 / 8 );
247247 }
248248}
249249
@@ -337,7 +337,7 @@ void PNGPlotter::addDataPointWithIndicator(double newPrice, int portIndex, std::
337337 std::ostringstream oss;
338338 oss << newPrice;
339339 std::string numberY = oss.str ();
340- GraphLabel (width - margin_right, y, numberY, 300 , 100 , 300 / 4 , true , indicatorColors[indicator]);
340+ GraphLabel (width - margin_right, y, numberY, 600 , 100 , 100 , true , indicatorColors[indicator]);
341341 }
342342
343343
@@ -733,40 +733,53 @@ void PNGPlotter::GraphLabel(unsigned int penX, unsigned int penY, const std::str
733733 return ;
734734 }
735735 penX += xOffset;
736- penY += yOffset;
737-
736+ penY -= yOffset;
737+
738+ // Compute baseline using font metrics
739+ int ascender = face->size ->metrics .ascender / 64 ; // Convert from 26.6 fixed-point to pixels
740+ int descender = face->size ->metrics .descender / 64 ; // Convert to pixels
741+ float heightScale = 0.3 ;
742+ // Compute a common baseline using font metrics
743+ int baseline = face->size ->metrics .ascender / 64 ; // Convert from 26.6 fixed-point to pixels
738744 unsigned int extraSpacing = fontSize / 3 ;
739745
740746 // Calculate the bounding box for the text
741747 unsigned int boxWidth = 0 ;
742- unsigned int boxHeight = fontSize ; // Use font size for height as a baseline
748+ unsigned int boxHeight = static_cast < unsigned int >((ascender - descender) * heightScale) ; // Total scaled height of the text block
743749
744750 // Measure the total width of the text
745- for (char c : text) {
746- if (FT_Load_Char (face, c, FT_LOAD_RENDER)) {
751+ for (char c : text)
752+ {
753+ if (FT_Load_Char (face, c, FT_LOAD_RENDER))
754+ {
747755 printf (" Warning: Could not load character %c\n " , c);
748756 continue ;
749757 }
750758
751759 FT_GlyphSlot glyph = face->glyph ;
760+
761+ // Add glyph width and extra spacing
752762 boxWidth += (glyph->advance .x >> 6 ) + extraSpacing;
753- if (glyph->bitmap .rows > boxHeight) {
754- boxHeight = glyph->bitmap .rows ; // Adjust height if necessary
763+
764+ // Adjust boxHeight if a taller glyph is found (scaled height)
765+ unsigned int glyphHeight = static_cast <unsigned int >(glyph->bitmap .rows * heightScale);
766+ if (glyphHeight > boxHeight)
767+ {
768+ boxHeight = glyphHeight;
755769 }
756770 }
757771
758772 // Add padding to the box
759- unsigned int padding = fontSize / 4 ;
760- boxWidth += padding;
773+ unsigned int padding = fontSize / 6 ;
761774
762775 // Draw the box if necessary
763776 if (hasBox) {
764- unsigned int boxX = penX - padding ; // Adjust box start position
765- unsigned int boxY = penY - boxHeight + padding ; // Adjust for baseline alignment
777+ unsigned int boxX = penX; // Adjust box start position
778+ unsigned int boxY = penY - boxHeight; // Adjust for baseline alignment
766779 for (unsigned int y = 0 ; y < boxHeight; ++y) {
767780 for (unsigned int x = 0 ; x < boxWidth; ++x) {
768781 unsigned imgX = boxX + x;
769- unsigned imgY = boxY + y;
782+ unsigned imgY = boxY + y + (yOffset * 2 ) ;
770783
771784 if (imgX < width && imgY < height) {
772785 image.SetPixel (imgX, imgY, labelColor); // Draw the background box
@@ -775,6 +788,7 @@ void PNGPlotter::GraphLabel(unsigned int penX, unsigned int penY, const std::str
775788 }
776789 }
777790
791+
778792 for (char c : text)
779793 {
780794 if (FT_Load_Char (face, c, FT_LOAD_RENDER))
@@ -789,9 +803,8 @@ void PNGPlotter::GraphLabel(unsigned int penX, unsigned int penY, const std::str
789803 unsigned glyphHeight = glyph->bitmap .rows ;
790804
791805 unsigned int x0 = penX + glyph->bitmap_left ;
792- unsigned int y0 = penY - glyph->bitmap_top ;
806+ unsigned int y0 = penY + static_cast < unsigned int >(baseline * heightScale) - static_cast < unsigned int >( glyph->bitmap_top * heightScale) ;
793807
794- float heightScale = 0.9 ;
795808
796809 // Draw the glyph bitmap as solid black
797810 for (unsigned int y = 0 ; y < glyphHeight; ++y)
@@ -806,7 +819,14 @@ void PNGPlotter::GraphLabel(unsigned int penX, unsigned int penY, const std::str
806819 unsigned char value = glyph->bitmap .buffer [y * glyphWidth + x];
807820 if (value > 0 )
808821 { // Only draw if the glyph pixel is not empty
809- image.SetPixel (imgX, imgY, RGBA (255 ,255 ,255 ,255 )); // Solid black
822+ if (hasBox)
823+ {
824+ image.SetPixel (imgX, imgY, RGBA (0 , 0 , 0 , 255 )); // Solid Black
825+ }
826+ else
827+ {
828+ image.SetPixel (imgX, imgY, RGBA (255 ,255 ,255 ,255 )); // Solid White
829+ }
810830 }
811831 }
812832 }
@@ -823,56 +843,53 @@ void PNGPlotter::HeaderPNG(const std::string& text, unsigned int fontSize)
823843 FT_Set_Pixel_Sizes (face, 0 , fontSize);
824844
825845 // Baseline position for text
826- unsigned int penX = 200 ;
827- unsigned int penY = 300 ;
846+ unsigned int penX = 500 ;
847+ unsigned int penY = 100 ;
828848
829- unsigned int extraSpacing = fontSize / 3 ;
849+ unsigned int extraSpacing = fontSize / 4 ;
850+
851+ float heightScale = 0.3 ;
852+ // Compute a common baseline using font metrics
853+ int baseline = face->size ->metrics .ascender / 64 ; // Convert from 26.6 fixed-point to pixels
830854
831- // Iterate over each character in the text
832- for (char c : text)
855+ for (char c : text)
833856 {
834- // Load character glyph
835- if (FT_Load_Char (face, c, FT_LOAD_RENDER))
857+ if (FT_Load_Char (face, c, FT_LOAD_RENDER))
836858 {
837- printf (" Warning: Could not load character %c\n " , c);
838- continue ;
839- }
859+ printf (" Warning: Could not load character %c\n " , c);
860+ continue ;
861+ }
840862
841- FT_GlyphSlot glyph = face->glyph ;
842-
843- // Get Glyph Dimensions
844- unsigned glyphWidth = glyph->bitmap .width ;
845- unsigned glyphHeight = glyph->bitmap .rows ;
863+ FT_GlyphSlot glyph = face->glyph ;
864+
865+ unsigned glyphWidth = glyph->bitmap .width ;
866+ unsigned glyphHeight = glyph->bitmap .rows ;
846867
847- // Calculate top-left position of the glyph
848- unsigned int x0 = penX + glyph->bitmap_left ;
849- unsigned int y0 = penY - glyph-> bitmap_top ;
868+ unsigned int x0 = penX + glyph-> bitmap_left ;
869+ unsigned int y0 = penY + static_cast < unsigned int >(baseline * heightScale) - static_cast < unsigned int >( glyph->bitmap_top * heightScale) ;
870+
850871
851- float heightScale = 0.9 ;
852- // Draw the glyph bitmap to the image
853- for (unsigned int y = 0 ; y < glyphHeight; ++y)
872+ // Draw the glyph bitmap as solid black
873+ for (unsigned int y = 0 ; y < glyphHeight; ++y)
854874 {
855- for (unsigned int x = 0 ; x < glyphWidth; ++x)
875+ for (unsigned int x = 0 ; x < glyphWidth; ++x)
856876 {
857- unsigned imgX = x0 + x;
877+ unsigned imgX = x0 + x;
858878 unsigned imgY = y0 + static_cast <unsigned int >(y * heightScale);
859879
860- if (imgX < width && imgY < height)
880+ if (imgX < width && imgY < height)
861881 {
862- // Compute the buffer index
863- unsigned char value = glyph->bitmap .buffer [y * glyphWidth + x];
864-
882+ unsigned char value = glyph->bitmap .buffer [y * glyphWidth + x];
865883 if (value > 0 )
866884 { // Only draw if the glyph pixel is not empty
867- image.SetPixel (imgX, imgY, RGBA (255 , 255 , 255 , 255 )); // Solid black
885+ image.SetPixel (imgX, imgY, RGBA (255 ,255 ,255 ,255 )); // Solid black
868886 }
869- }
870- }
871- }
872-
873- // Advance Cursor Position
874- penX += (glyph->advance .x >> 6 ) + extraSpacing;
887+ }
888+ }
889+ }
875890
891+ // Advance cursor position
892+ penX += (glyph->advance .x >> 6 ) + extraSpacing;
876893 }
877894}
878895
0 commit comments