Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds basic text parsing #94

Open
wants to merge 3 commits into
base: master
Choose a base branch
from

Conversation

jamislike
Copy link

Began work on basic text parsing, would you consider adding an improved version of this to NanoSVG..

src/nanosvg.h Outdated Show resolved Hide resolved
@lieff
Copy link
Contributor

lieff commented Oct 2, 2017

Tabs replaced by spaces, formatting garbled. Tabs are annoying )

@jamislike
Copy link
Author

@lieff editor was set spaces, removed! Thanks!

@asmwarrior
Copy link

Good work, If it could parse the Text field, we can extract the those information, and draw the text in some native API. For example, all the non Text elements can be rendered by the current implementation, and the text element can be drawn by the DrawText function from the wxWidgets library.

@asmwarrior
Copy link

@jamislike can you merge the work in year 2017 with the current head maser?

It looks like some code and structure are changed from the years.

Thanks.

@asmwarrior
Copy link

2022-04-05.zip
I have manually merged your work with the recent master, but I'm not sure this is OK, can you have a look at this patch file(in the attachment zip file)? Thanks.

@asmwarrior
Copy link

In the patch file, I have add a comment:

@@ -1019,12 +1095,18 @@ static void nsvg__addShape(NSVGparser* p)
 	// Set flags
 	shape->flags = (attr->visible ? NSVG_FLAGS_VISIBLE : 0x00);
 
+// should to be fixed!!!
 	// Add to tail
-	if (p->image->shapes == NULL)
+	prev = NULL;
+	cur = p->image->shapes;
+	while (cur != NULL) {
+		prev = cur;
+		cur = cur->next;
+	}
+	if (prev == NULL)
 		p->image->shapes = shape;
 	else
-		p->shapesTail->next = shape;
-	p->shapesTail = shape;
+		prev->next = shape;
 
 	return;
 

I'm not sure what does the shapesTail used for, since in your work, this is not used, I think this should be fixed.

@asmwarrior
Copy link

I got a shape like below: (I show this from the GDB debugger command line)

$2 = {id = "text35", '\000' <repeats 249 times>, fill = {type = 1 '\001', {color = 4278190080, gradient = 0xff000000}}, stroke = {type = 0 '\000', {color = 0, gradient = 0x0}}, opacity = 1, strokeWidth = 0.999998748, strokeDashOffset = 0, strokeDashArray = {0, 0, 0, 0, 0, 0, 0, 0}, strokeDashCount = 0 '\000', strokeLineJoin = 0 '\000', strokeLineCap = 0 '\000', miterLimit = 4, fillRule = 0 '\000', flags = 1 '\001', bounds = {0, 0, 0, 0}, paths = 0x0, group = 0x6a37b40, next = 0x0, fontFamily = "sans-serif", '\000' <repeats 53 times>, fontWeight = "sans-serif", '\000' <repeats 53 times>, fontSize = 13.2292004, isText = 1 '\001', textData = "abc", '\000' <repeats 252 times>}

When I try to parse a text field in svg file like below:

    <text
       xml:space="preserve"
       style="font-style:normal;font-weight:normal;font-size:13.2292px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
       x="74.839287"
       y="66.523811"
       id="text35"><tspan
         sodipodi:role="line"
         id="tspan33"
         x="74.839287"
         y="66.523811"
         style="stroke-width:0.264583px">abc</tspan></text>

The svg file is generated by inkscape software.

It looks like the "x" and "y" coordinates is missing from the shape, are there any way to record them?
Thanks.

@asmwarrior
Copy link

I debugged this code for a while, and I see that in this function:

static void nsvg__parseText(NSVGparser* p, const char** attr)
{
	float x = 0.0f;
	float y = 0.0f;
	float r = 0.0f;
	float xform[6];

	int i;

	for (i = 0; attr[i]; i += 2) {
		if (!nsvg__parseAttr(p, attr[i], attr[i + 1])) {
			if (strcmp(attr[i], "x") == 0) x = nsvg__parseCoordinate(p, attr[i+1], nsvg__actualOrigX(p), nsvg__actualWidth(p));
			if (strcmp(attr[i], "y") == 0) y = nsvg__parseCoordinate(p, attr[i+1], nsvg__actualOrigY(p), nsvg__actualHeight(p));
			if (strcmp(attr[i], "transform") == 0)
			{
				nsvg__parseTransform(xform, attr[i+1]);
				x = nsvg__parseCoordinate(p, attr[i+1], xform[4], 0);
				y = nsvg__parseCoordinate(p, attr[i+1], xform[5], 0);
			}
			if (strcmp(attr[i], "font-size") == 0)  r = fabsf(nsvg__parseCoordinate(p, attr[i+1], 0.0f, nsvg__actualLength(p)) );

		}
	}
	p->isText = 1;

	nsvg__addShape(p);
}

The x and y value are correctly get, but those two variables are local variables, and I see there is no code to use them.
So, they never get saved in the shape structure.

@asmwarrior
Copy link

I have see a pull request here:

Push/pop attributes for SVG element. Add support for x and y attributes. by mindbrix · Pull Request #131 · memononen/nanosvg

With the commits in the pull request, it has to handle the x and 'y` in the attribute. And when adding the shape, it has such result:

[debug]> p shape->bounds
[debug]$1 = {74.8392868, 66.5238113, 74.8392868, 66.5238113}

So, the x,y coordinates of the text elements were stored in the bounds field, so we may later to use this information to draw the text on the screen(use our own API, not the rasterization function in nanosvg, but some DrawText like function in wxWidgets library.).

@asmwarrior
Copy link

Here is the result of my research, I extract the text elements by the nanosvg and this pull request, and draw the text elements on the rendered image. See the image below. With a comparing of the original svg image in Inkscape tool and the svg viewer window by wxWidgets.

show_text_by_wx_dc_DrawText

@asmwarrior
Copy link

FYI: I create a very simple project which uses wxWidgets to draw the text, see here: asmwarrior/SvgPanel: a wxPanel which can show svg image and simple text labels

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants