codenameone / CodenameOne

Cross-platform framework for building truly native mobile apps with Java or Kotlin. Write Once Run Anywhere support for iOS, Android, Desktop & Web.
https://www.codenameone.com/
Other
1.72k stars 408 forks source link

issue rendering svg using flamingo in ios side #3750

Open DurankGts opened 1 year ago

DurankGts commented 1 year ago

Please check wrong rendering in ios side painting perfect circle. image

this committ is the cause ?https://github.com/codenameone/CodenameOne/commit/b36b68df44198d19e3bc19c224927936358ca073

DurankGts commented 1 year ago

tested on iphone 13 ios 16.6.1

DurankGts commented 1 year ago

remenber that flamingo lib use GeneralPath class

DurankGts commented 1 year ago

image

DurankGts commented 1 year ago

please check the private email with the source code

DurankGts commented 1 year ago

please anyone can help me? this issue painting circle in ios side it' very important to me..

DurankGts commented 1 year ago

I have check that you aren't released to production this tag yet 7.0.123

image

when you will be update this commit in your built server?

I supouse the this the actually code in your build server sure?

image

shai-almog commented 1 year ago

The general path fix has been in production for a while. I doubt that is due to this. You problem is in the SVG file that has multiple separate arc statements instead of one arc. That's both inefficient and can cause artifacts due to rounding issues. Our renderer can't provide the same level of smoothing as a desktop graphics app.

DurankGts commented 1 year ago

The test was created in real iOS side iphone 13 iOS 16.6.1 not in desktop environment. How can you explain me that your method fillArc() in your Gráfic Class work perfectly but when I use GeneralPath() generated by the flamingo transcoder this circle is very perceptible not perfect circle?

shai-almog commented 1 year ago

The API you used was curveTo 4 times. Not arc. This will obviously create artifacts. Use arc. When I say "desktop" I mean an App like Sketch. Not the simulator.

DurankGts commented 1 year ago

I use this because your flamingo transcoder created automatically that way when I convert svg file to java class. If this create a problem why just fail in iOS side?. You must to update the flamingo transcoder lib to avoid this way.

DurankGts commented 1 year ago

Remenber that the readme in flamingo project said in the bold text:

Tips and tricks to get a working Java code from a simple SVG image: Before export your vectorial drawing to SVG, if you can: 1a. transform any special object (like spirals, circles or stars) in a pure path;

2a. remove all transformations.

Export your vectorial drawing to SVG in the simplest format, that means without incorporated rasters, without incorporated fonts (export text as curves), without gradients or translucents (full opaque or full transparent colors are fine). If you can choose the SVG version, SVG 1.0 is fine. A method to remove transformations (it should work in most simple cases):

Load your SVG in Method Draw http://editor.method.ac/ (File > Open Image). (Method Draw is a vector editor for the web, it is open source and you can find it on Github: https://github.com/duopixel/Method-Draw) Select the image and ungroup your elements (Object > Ungroup elements), you might have to do this more than once. Keeping the image selected, reorient the path (Object > Reorient Paths). Save your image (File > Save Image). Another method to remove transformations (if the previous method failed because Method Draw doesn't load correctly the image):

Ensure that the SVG has only one layer (you can use the XML editor of Inkscape) Install Affinity Designer (there is a ten-days trial version for Windows and Mac) Import the SVG in Affinity Designer and export with "no rasters", "use relative coordinates", "use hex colors", "flatten transforms", "set viewbox", "add line breaks". Try to use Method Draw (as above) with the just exported SVG: now it should load correctly the image. Last resort after all above trials: if you get errors in the generate java code related to unused gradients, unused transformations or unused variables, fix the code manually. In a desperate case, I've done few manual corrections and then the code started to work... :-) More info about removing transformations from an SVG: https://stackoverflow.com/questions/13329125/removing-transforms-in-svg-files

I did exactly this. All my svg files are created in pure path before pass to the flamingo lib to convert to java class. this curve is generated by your flamingo code. That is because your recomendation it'use pure path.

DurankGts commented 1 year ago

The API you used was curveTo 4 times. Not arc. This will obviously create artifacts. Use arc. When I say "desktop" I mean an App like Sketch. Not the simulator.

Please provide a definitive solution if possible because our client detect this issue in real ios devices and don't like that. I just use your method fillArc() to check is problem is solved and efectively it solve but it's very dificult to paint just circles but when the circle is inside of others shapes is very dificult to paint with fillArc().

 //-----------------------------------------------------------------------------------
    public static void setGuiWelcomePainteCircleIcons(Graphics g) {
        //------------------------------------------------
        //circle code generated from svg file wrong co;circle
        //------------------------------------------------
//        ((GeneralPath) shape).moveTo(112.5, 0.0);
//        ((GeneralPath) shape).curveTo(174.632, 0.0, 225.0, 50.368, 225.0, 112.5);
//        ((GeneralPath) shape).curveTo(225.0, 174.632, 174.632, 225.0, 112.5, 225.0);
//        ((GeneralPath) shape).curveTo(50.367996, 225.0, 0.0, 174.632, 0.0, 112.5);
//        ((GeneralPath) shape).curveTo(0.0, 50.367996, 50.368, 0.0, 112.5, 0.0);
//        ((GeneralPath) shape).closePath();
//        g.setColor(0x99ADD9); //this code work perfect
//        g.fillShape(shape);
        g.setColor(COLORS.GW_ICON_BORDER); //this code work perfect
        g.fillArc(0, 0, 225, 225, 0, 360);

        // _0_1
//        shape = new GeneralPath();
//        ((GeneralPath) shape).moveTo(112.0, 19.0);
//        ((GeneralPath) shape).curveTo(163.361, 19.0, 205.0, 60.638, 205.0, 112.0);
//        ((GeneralPath) shape).curveTo(205.0, 163.361, 163.361, 205.0, 112.0, 205.0);
//        ((GeneralPath) shape).curveTo(60.638, 205.0, 19.0, 163.361, 19.0, 112.0);
//        ((GeneralPath) shape).curveTo(19.0, 60.638, 60.638, 19.0, 112.0, 19.0);
//        ((GeneralPath) shape).closePath();
//        g.setColor(COLORS.GW_ICON_CIRCLE);
//        g.fillShape(shape);
        g.setColor(COLORS.GW_ICON_CIRCLE); //this code work perfect
        g.fillArc(20, 20, 186, 186, 0, 360);
    }
    //-----------------------------------------------------------------------------------
shai-almog commented 1 year ago

Flamingo is very simple. It takes the SVG commands and translates them to Codename One paths. So there's a path in the SVG that's not a circle. It's 4 curveTo commands. I haven't looked at the SVG file but I'm guessing that's what the SVG file contains since flamingo isn't clever and doesn't come up with these things.

You have two options:

Notice that when I say arc I mean: ((GeneralPath) shape).arc(...) not fillArc.

The graphics program will render the 4 separate curves correctly due to better subpixel anti-aliasing. This isn't something we can accomplish in a performant way across platforms.

DurankGts commented 1 year ago

If I update from pro to Enterprise account the problem will have some solutions? It's important to understand that the developers that use codenameone some times wait a better response in dificult cases.

Remember that if in ios side you can't provide a correct render in circles, circular fonts, etc, your framework have some disadvantages. The future is use SVG images, not use every diferent images by densities.

I don't know why sincerily you just implement the same way of fillArc() in the flamingo transcoder lib to avoid to developers that use your framework to edit next the SVG file is converted in java class. That's unproductive to owrs clients, because we lost must time. If I had time to modify the flamingo lib source code I would do. The reason because we decide to paid your framework is sincerilly because your framework offer easy way to compile finals app to any actual platforms in little time. But you must continue growing every time that the developers found any problems and take our time to documentate in your Git page. Please think some times in the developers side that must to deliver a final product that depend of your support.

DurankGts commented 1 year ago

how can I check please witch version have your actual Build server code in the section code of here? Why your aren't created a tag release to version 7.0.123 yet?

shai-almog commented 1 year ago

My answer would be the same if you were an enterprise customer married to my sister. The solution is to use an arc(). You can't invoke 4 separate APIs that draw a quarter arc and expect them to fit 100%.

Again, Flamingo didn't do it. Your SVG file did this...

DurankGts commented 1 year ago

your flamingo lib doesn't reconize tags <circle id="circcle" class="st1" cx="112.5" cy="112.5" r="92.8"/>

in your flamingo project is recommended use

Remenber that the readme in flamingo project said in the bold text:

Tips and tricks to get a working Java code from a simple SVG image: Before export your vectorial drawing to SVG, if you can: 1a. transform any special object (like spirals, circles or stars) in a pure path;

2a. remove all transformations.

that is what I did all times that I use Svg. Then if your flamingo lib doesn't reconize circle and other shape what do you sugest that I do?

DurankGts commented 1 year ago

Could you provide a SVG file that work correctly with your flamingo?

shai-almog commented 1 year ago

We didn't write flamingo. We just ported it. It seems to be generated by this code here: https://github.com/codenameone/flamingo-svg-transcoder/blob/master/core/src/main/java/org/pushingpixels/flamingo/api/svg/transcoders/EllipseTranscoder.java#L35

I'm guessing that is behavior from Batik or some other weird thing. Regardless, I don't understand why you don't just fix the generated code to use a single arc() call?

We never promised 100% fidelity in SVG translation.

DurankGts commented 1 year ago

because this method in simulator draw very bad the circle. Althought in real devices the result isn't same that the simulator i prefere use Grafic.fillArc() that work perfectly in simulator, ios, and android

image