Lately i have been working on a small project that reads information from SVG file and then using GDI+ to draw, but im having trouble with text drawing position, because what i draw is not the same as what SVG draw, im pretty sure that i read the information correctly. I guess there is a difference between the coordinate system of GDI+ and SVG, below is the code i use to draw text. can anyone suggest me a way to fix this ? Thanks a lot!
<svg xmlns="http://www.w3.org/2000/svg">
<g transform="translate(100, 100) rotate(45)">
<line x1="10" y1="10" x2="85" y2="10" stroke="rgb(255,0,0)"/>
<rect x="10" y="20" height="50" width="75"
stroke="rgb(0,255,0)" fill="rgb(0,255,0)"/>
<text x="10" y="120" stroke="rgb(255,0,0)" fill="rgb(0,0,255)" font-size ="50">
Text grouped with shapes</text>
</g>
</svg>
class TextSVG : public ShapeSVG {
private:
PointSVG p;
double fontSize = 0;
int fontWeight1 = 0;
string fontWeight2 = "";
string fontStyle = "";
string fontFamily = "Times New Roman";
string textAnchor = "";
string textDecoration = "";
string textTransform = "";
string textContent = "";
bool checkStroke = 0;
public:;
void parseShapeSVG(const SVGElement& element) override;
void drawSVG(Graphics& graphics) override;
void TranslateText(Graphics& graphics, float dx, float dy) {
graphics.TranslateTransform(dx, dy);
}
void ScaleText(Graphics& graphics, float x, float y) {
graphics.ScaleTransform(x, y);
}
void RotateText(Graphics& graphics, float angleDegrees) {
//graphics.TranslateTransform(0, 0);
graphics.RotateTransform(angleDegrees);
}
void getPointMINMAX(pointMinMax&) override;
};
void TextSVG::drawSVG(Graphics& graphics) {
graphics.SetSmoothingMode(SmoothingModeAntiAlias);
//graphics.SetTextRenderingHint(TextRenderingHintAntiAlias);
GraphicsState state = graphics.Save();
bool checkScale = 0;
for (const auto& tf : tfSVG) {
if (tf.transformType == "translate") {
this->TranslateText(graphics, tf.translateX, tf.translateY);
}
else if (tf.transformType == "scale") {
this->ScaleText(graphics, tf.scaleX, tf.scaleY);
checkScale = 1;
}
else if (tf.transformType == "rotate") {
this->RotateText(graphics, tf.rotateAngle);
}
}
int font1 = FontStyleRegular;
if (fontWeight2 == "bold" || fontWeight2 == "Bold" || fontWeight1 >= 550) {
font1 = FontStyleBold;
}
else if (fontStyle == "italic" || fontStyle == "Italic") {
font1 = FontStyleItalic;
}
else if ((fontWeight2 == "bold" || fontWeight2 == "Bold" || fontWeight1 >= 550) && (fontStyle == "italic" || fontStyle == "Italic")) {
font1 = FontStyleBoldItalic;
}
else if (textDecoration == "underline" || textDecoration == "Underline") {
font1 = FontStyleUnderline;
}
else if (textDecoration == "line-through") {
font1 = FontStyleStrikeout;
}
unordered_map <string, float>offset_map= {
{"start", -0.15 * fontSize},
{"middle", 0.0f},
{"end", 0.15 * fontSize}
};
unordered_map <string, Gdiplus::StringAlignment> text_anchor_map = {
{ "start", Gdiplus::StringAlignment::StringAlignmentNear },
{ "middle", Gdiplus::StringAlignment::StringAlignmentCenter },
{ "end", Gdiplus::StringAlignment::StringAlignmentFar }
};
wstring wstr = wstring(textContent.begin(), textContent.end());
std::wstring ws = wstring(fontFamily.begin(), fontFamily.end());
FontFamily fontFamily1(ws.c_str());
Gdiplus::PointF origin(p.x, p.y - 0.9 * fontSize);
origin.X += offset_map[textAnchor];
Gdiplus::StringFormat format(Gdiplus::StringFormat::GenericDefault());
format.SetAlignment(text_anchor_map[textAnchor]);
GraphicsPath path;
path.AddString(wstr.c_str(), -1, &fontFamily1, font1, fontSize, origin, &format);
SolidBrush brush(Color(fillOpacity * 255, fill.R, fill.G, fill.B));
graphics.FillPath(&brush, &path);
if (checkStroke == 1) {
Pen pen(Color(strokeOpacity * 255, stroke.R, stroke.G, stroke.B), strokeWidth);
graphics.DrawPath(&pen, &path);
}
graphics.Restore(state);
}
UPDATE: i know what is wrong, that is i forgot to add more cases to read text, when the text content is on a new line, it represents the same drawing. My code just works correct when it is like this:
<svg xmlns="http://www.w3.org/2000/svg">
<g transform="translate(100, 100) rotate(45)">
<line x1="10" y1="10" x2="85" y2="10" stroke="rgb(255,0,0)"/>
<rect x="10" y="20" height="50" width="75"
stroke="rgb(0,255,0)" fill="rgb(0,255,0)"/>
<text x="10" y="120" stroke="rgb(255,0,0)" fill="rgb(0,0,255)" font-size ="50">Text grouped with shapes</text>
</g>
</svg>
Instead of the original version. Many thanks to all that have helped me so far on this post :DD.
