You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++使用GDI+解析SVG绘制文本时坐标定位错误的解决求助

SVG文本绘制位置异常问题排查与解决

近期开发一个读取SVG文件并使用GDI+绘制的小型项目,遇到文本绘制位置与SVG显示效果不一致的问题。已确认SVG信息读取正确,最初推测是GDI+与SVG坐标系存在差异,相关代码及SVG示例如下:

SVG与GDI+绘制效果对比

SVG示例代码

<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>

C++类定义代码

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;
};

C++文本绘制代码

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);
}

更新说明:已找到问题根源——未处理文本内容换行的解析场景。SVG中<text>标签文本内容不换行时代码可正常工作,换行则绘制出错。感谢各位帮助!

内容的提问来源于stack exchange,提问作者Tran_Duc_Tung_HCMUS

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 08:23:10