Skip to content

Commit

Permalink
Complete viewbox
Browse files Browse the repository at this point in the history
  • Loading branch information
hoangfitus committed Dec 26, 2023
1 parent b7f5cef commit dc3cded
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 16 deletions.
13 changes: 12 additions & 1 deletion src/Parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -343,7 +343,18 @@ float Parser::getFloatAttribute(rapidxml::xml_node<> *node, std::string name) {
result = 0;
}
} else {
result = std::stof(node->first_attribute(name.c_str())->value());
if (name == "width" || name == "height") {
std::string value = node->first_attribute(name.c_str())->value();
if (value.find("%") != std::string::npos) {
result = std::stof(value.substr(0, value.find("%"))) *
this->viewbox.second.x / 100;
} else if (value.find("pt") != std::string::npos) {
result = std::stof(value.substr(0, value.find("pt"))) * 1.33;
} else {
result = std::stof(value);
}
} else
result = std::stof(node->first_attribute(name.c_str())->value());
}
return result;
}
Expand Down
30 changes: 22 additions & 8 deletions src/Renderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -308,7 +308,8 @@ void Renderer::drawText(Gdiplus::Graphics& graphics, Text* text) const {
graphics.FillPath(&corner_fill, &path);
}
graphics.FillPath(text_fill, &path);
if (text->getOutlineColor().a == text->getFillColor().a) {
if (text->getOutlineColor().a != 0 &&
text->getOutlineColor().a == text->getFillColor().a) {
text_outline.SetColor(Gdiplus::Color(255, 255, 255, 255));
graphics.DrawPath(&text_outline, &path);
text_outline.SetColor(Gdiplus::Color(outline_color.a, outline_color.r,
Expand Down Expand Up @@ -565,11 +566,11 @@ Gdiplus::Brush* Renderer::getBrush(SVGElement* shape,
Gdiplus::Color* colors = new Gdiplus::Color[stop_size];
float* offsets = new float[stop_size];
if (gradient->getClass() == "LinearGradient") {
if (gradient->getUnits() == "userSpaceOnUse") {
bound.X = points.first.x;
bound.Y = points.first.y;
bound.Width = points.second.x;
bound.Height = points.second.y;
if (gradient->getUnits() == "objectBoundingBox") {
points.first.x = bound.X;
points.first.y = bound.Y;
points.second.x = bound.X + bound.Width;
points.second.y = bound.Y + bound.Height;
}
offsets[0] = 0;
offsets[stop_size - 1] = 1;
Expand All @@ -589,8 +590,10 @@ Gdiplus::Brush* Renderer::getBrush(SVGElement* shape,
}
Gdiplus::LinearGradientBrush* fill =
new Gdiplus::LinearGradientBrush(
bound, colors[0], colors[stop_size - 1],
Gdiplus::LinearGradientMode::LinearGradientModeHorizontal);
Gdiplus::PointF(points.first.x, points.first.y),
Gdiplus::PointF(points.second.x, points.second.y),
colors[0], colors[stop_size - 1]);
fill->SetWrapMode(Gdiplus::WrapModeClamp);
fill->SetInterpolationColors(colors, offsets, stop_size);
applyTransformsOnBrush(gradient->getTransforms(), fill);
delete[] colors;
Expand Down Expand Up @@ -654,6 +657,7 @@ void Renderer::applyTransformsOnBrush(
} else if (type.find("rotate") != std::string::npos) {
float degree = getRotate(type);
brush->RotateTranform(degree);
brush->TranslateTransform(degree, degree);
} else if (type.find("scale") != std::string::npos) {
if (type.find(",") != std::string::npos) {
float scale_x = getScaleXY(type).first,
Expand All @@ -663,6 +667,16 @@ void Renderer::applyTransformsOnBrush(
float scale = getScale(type);
brush->ScaleTransform(scale, scale);
}
} else if (type.find("matrix") != std::string::npos) {
float a = 0, b = 0, c = 0, d = 0, e = 0, f = 0;
if (type.find(",") != std::string::npos) {
type.erase(std::remove(type.begin(), type.end(), ','),
type.end());
}
sscanf(type.c_str(), "matrix(%f %f %f %f %f %f)", &a, &b, &c, &d,
&e, &f);
Gdiplus::Matrix matrix(a, b, c, d, e, f);
brush->SetTransform(&matrix);
}
}
}
Expand Down
47 changes: 40 additions & 7 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,19 +19,52 @@ void OnPaint(HDC hdc, const std::string& filePath, Viewer& viewer) {
}
Vector2Df viewport = parser->getViewPort();
std::pair< Vector2Df, Vector2Df > viewbox = parser->getViewBox();
float scale_x = viewer.window_size.x / viewbox.second.x;
float scale_y = viewer.window_size.y / viewbox.second.y;
float scale = std::min(scale_x, scale_y);
graphics.SetClip(Gdiplus::Rect(0, 0, viewport.x, viewport.y));
Gdiplus::GraphicsState state = graphics.Save();
if (viewport.x == 0 && viewport.y == 0) {
viewport.x = viewer.window_size.x;
viewport.y = viewer.window_size.y;
}
if ((viewport.x != viewbox.second.x || viewport.y != viewbox.second.y) &&
viewbox.second.x != 0 && viewbox.second.y != 0) {
float scale_x = viewport.x / viewbox.second.x;
float scale_y = viewport.y / viewbox.second.y;
float scale = std::min(scale_x, scale_y);
scale = roundf(scale * 100) / 100;
graphics.ScaleTransform(scale, scale);
float offset_x = 0.0f;
float offset_y = 0.0f;
if (viewport.x > viewbox.second.x) {
offset_x = (viewport.x - viewbox.second.x * scale) / 2 / scale;
}
if (viewport.y > viewbox.second.y) {
offset_y = (viewport.y - viewbox.second.y * scale) / 2 / scale;
}
graphics.TranslateTransform(offset_x, offset_y);
}

graphics.ScaleTransform(scale, scale);
Gdiplus::Matrix matrix;
Gdiplus::Region region;
graphics.GetClip(&region);
graphics.RotateTransform(viewer.rotate_angle);
if (viewer.rotate_angle != 0) {
matrix.Rotate(viewer.rotate_angle);
region.Transform(&matrix);
}
graphics.ScaleTransform(viewer.zoom_factor, viewer.zoom_factor);
if (viewer.zoom_factor != 1) {
matrix.Scale(viewer.zoom_factor, viewer.zoom_factor);
region.Transform(&matrix);
}
graphics.SetClip(&region);
graphics.TranslateTransform(viewer.offset_x, viewer.offset_y);
graphics.TranslateClip(viewer.offset_x, viewer.offset_y);
graphics.SetSmoothingMode(Gdiplus::SmoothingModeAntiAlias8x8);
graphics.SetTextContrast(100);
graphics.SetCompositingMode(Gdiplus::CompositingModeSourceOver);
graphics.SetPixelOffsetMode(Gdiplus::PixelOffsetModeHighQuality);
graphics.SetInterpolationMode(Gdiplus::InterpolationModeHighQuality);

Renderer* renderer = Renderer::getInstance();
SVGElement* root = parser->getRoot();
Group* group = dynamic_cast< Group* >(root);
Expand Down Expand Up @@ -65,10 +98,10 @@ INT WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, PSTR, INT iCmdShow) {
TEXT("svg-reader-v0.2"), // window class name
TEXT("svg-reader-v0.2"), // window caption
WS_OVERLAPPEDWINDOW, // window style
CW_USEDEFAULT, // initial x position
CW_USEDEFAULT, // initial y position
0, // initial x position
0, // initial y position
1600, // initial x size
1200, // initial y size
900, // initial y size
NULL, // parent window handle
NULL, // window menu handle
hInstance, // program instance handle
Expand Down

0 comments on commit dc3cded

Please sign in to comment.