Fix KanjiVG drawing issue

Julien LepillerThu Jun 30 21:16:54+0200 2022

2f9c914

Fix KanjiVG drawing issue

app/src/main/java/eu/lepiller/nani/dictionary/KanjiVG.java

149149
        return new Pair<>(pos, res);
150150
    }
151151
152-
    private static int parsePathMoveTo(Path path, String command, int pos, boolean relative) throws ParseException {
153-
        Pair<Integer, List<Float>> lst = parsePathFloatList(command, pos);
154-
        if(lst.second.size() != 2)
155-
            throw new ParseException();
156-
        pos = lst.first;
157-
        if(relative)
158-
            path.rMoveTo(lst.second.get(0), lst.second.get(1));
159-
        else
160-
            path.moveTo(lst.second.get(0), lst.second.get(1));
161-
        return pos;
162-
    }
163-
164-
    private static int parsePathCurveTo(Path path, String command, int pos, boolean relative) throws ParseException {
165-
        Pair<Integer, List<Float>> lst = parsePathFloatList(command, pos);
166-
        if(lst.second.size() != 6) {
167-
            Log.e(TAG, "list: " + lst.second.size() + " with " + Arrays.toString(lst.second.toArray()));
168-
            Log.e(TAG, "command: " + command);
169-
            Log.e(TAG, "next pos: " + pos + " with char " + command.charAt(pos));
170-
            throw new ParseException();
171-
        }
172-
        pos = lst.first;
173-
        if(relative)
174-
            path.rCubicTo(lst.second.get(0), lst.second.get(1), lst.second.get(2), lst.second.get(3), lst.second.get(4), lst.second.get(5));
175-
        else
176-
            path.cubicTo(lst.second.get(0), lst.second.get(1), lst.second.get(2), lst.second.get(3), lst.second.get(4), lst.second.get(5));
177-
        return pos;
178-
    }
179-
180-
    private static int parsePathLineTo(Path path, String command, int pos, boolean relative) throws ParseException {
181-
        Pair<Integer, List<Float>> lst = parsePathFloatList(command, pos);
182-
        if(lst.second.size() != 2)
183-
            throw new ParseException();
184-
        pos = lst.first;
185-
        if(relative)
186-
            path.rLineTo(lst.second.get(0), lst.second.get(1));
187-
        else
188-
            path.lineTo(lst.second.get(0), lst.second.get(1));
189-
        return pos;
190-
    }
191-
192-
    private static int parsePathQuadraticTo(Path path, String command, int pos, boolean relative) throws ParseException {
193-
        Pair<Integer, List<Float>> lst = parsePathFloatList(command, pos);
194-
        if(lst.second.size() != 4)
195-
            throw new ParseException();
196-
        pos = lst.first;
197-
        if(relative)
198-
            path.rQuadTo(lst.second.get(0), lst.second.get(1), lst.second.get(2), lst.second.get(3));
199-
        else
200-
            path.quadTo(lst.second.get(0), lst.second.get(1), lst.second.get(2), lst.second.get(3));
201-
        return pos;
202-
    }
203-
204152
    private static void parsePath(Path path, String command) throws ParseException {
205153
        int pos = 0;
154+
        float lastX = 0; float lastY = 0;
155+
        float lastX1 = 0; float lastY1 = 0;
156+
        float x1, y1;
157+
        Pair<Integer, List<Float>> lst;
206158
        while(pos < command.length()) {
207159
            char com = command.charAt(pos);
208160
            boolean relative = com < 'A' || com > 'Z';

210162
            switch(com) {
211163
                case 'm':
212164
                case 'M':
213-
                    pos = parsePathMoveTo(path, command, pos, relative);
165+
                    lst = parsePathFloatList(command, pos);
166+
                    if(lst.second.size() != 2)
167+
                        throw new ParseException();
168+
                    pos = lst.first;
169+
                    if(relative) {
170+
                        lastX += lst.second.get(0);
171+
                        lastY += lst.second.get(1);
172+
                    } else {
173+
                        lastX = lst.second.get(0);
174+
                        lastY = lst.second.get(1);
175+
                    }
176+
                    path.moveTo(lastX, lastY);
214177
                    break;
215178
                case 'c':
216179
                case 'C':
180+
                    lst = parsePathFloatList(command, pos);
181+
                    if(lst.second.size() != 6)
182+
                        throw new ParseException();
183+
                    pos = lst.first;
184+
                    if(relative) {
185+
                        lastX1 = lastX + lst.second.get(2);
186+
                        lastY1 = lastY + lst.second.get(3);
187+
                        x1 = lastX + lst.second.get(0);
188+
                        y1 = lastY + lst.second.get(1);
189+
                        lastX += lst.second.get(4);
190+
                        lastY += lst.second.get(5);
191+
                    } else {
192+
                        x1 = lst.second.get(0);
193+
                        y1 = lst.second.get(1);
194+
                        lastX1 = lst.second.get(2);
195+
                        lastY1 = lst.second.get(3);
196+
                        lastX = lst.second.get(4);
197+
                        lastY = lst.second.get(5);
198+
                    }
199+
                    path.cubicTo(x1, y1, lastX1, lastY1, lastX, lastY);
200+
                    break;
217201
                case 's':
218202
                case 'S':
219-
                    pos = parsePathCurveTo(path, command, pos, relative);
203+
                    lst = parsePathFloatList(command, pos);
204+
                    if(lst.second.size() != 4)
205+
                        throw new ParseException();
206+
                    pos = lst.first;
207+
                    x1 = 2*lastX - lastX1;
208+
                    y1 = 2*lastY - lastY1;
209+
                    if(relative) {
210+
                        lastX1 = lastX + lst.second.get(0);
211+
                        lastY1 = lastY + lst.second.get(1);
212+
                        lastX += lst.second.get(2);
213+
                        lastY += lst.second.get(3);
214+
                    } else {
215+
                        lastX1 = lst.second.get(0);
216+
                        lastY1 = lst.second.get(1);
217+
                        lastX = lst.second.get(2);
218+
                        lastY = lst.second.get(3);
219+
                    }
220+
                    path.cubicTo(x1, y1, lastX1, lastY1, lastX, lastY);
220221
                    break;
221222
                case 'l':
222223
                case 'L':
223-
                    pos = parsePathLineTo(path, command, pos, relative);
224+
                    lst = parsePathFloatList(command, pos);
225+
                    if(lst.second.size() != 2)
226+
                        throw new ParseException();
227+
                    pos = lst.first;
228+
                    if(relative) {
229+
                        lastX += lst.second.get(0);
230+
                        lastY += lst.second.get(1);
231+
                    } else {
232+
                        lastX = lst.second.get(0);
233+
                        lastY = lst.second.get(1);
234+
                    }
235+
                    path.lineTo(lastX, lastY);
236+
                    break;
237+
                case 'h':
238+
                case 'H':
239+
                    lst = parsePathFloatList(command, pos);
240+
                    if(lst.second.size() != 1)
241+
                        throw new ParseException();
242+
                    pos = lst.first;
243+
                    if(relative) {
244+
                        lastX += lst.second.get(0);
245+
                    } else {
246+
                        lastX = lst.second.get(0);
247+
                    }
248+
                    path.lineTo(lastX, lastY);
249+
                    break;
250+
                case 'v':
251+
                case 'V':
252+
                    lst = parsePathFloatList(command, pos);
253+
                    if(lst.second.size() != 1)
254+
                        throw new ParseException();
255+
                    pos = lst.first;
256+
                    if(relative) {
257+
                        lastY += lst.second.get(0);
258+
                    } else {
259+
                        lastY = lst.second.get(0);
260+
                    }
261+
                    path.lineTo(lastX, lastY);
224262
                    break;
225263
                case 'q':
226264
                case 'Q':
265+
                    lst = parsePathFloatList(command, pos);
266+
                    if(lst.second.size() != 4)
267+
                        throw new ParseException();
268+
                    pos = lst.first;
269+
                    if(relative) {
270+
                        lastX1 = lastX + lst.second.get(0);
271+
                        lastY1 = lastY + lst.second.get(1);
272+
                        lastX += lst.second.get(2);
273+
                        lastY += lst.second.get(3);
274+
                    } else {
275+
                        lastX1 = lst.second.get(0);
276+
                        lastY1 = lst.second.get(1);
277+
                        lastX = lst.second.get(2);
278+
                        lastY = lst.second.get(3);
279+
                    }
280+
                    path.quadTo(lastX1, lastY1, lastX, lastY);
281+
                    break;
227282
                case 't':
228283
                case 'T':
229-
                    pos = parsePathQuadraticTo(path, command, pos, relative);
284+
                    lst = parsePathFloatList(command, pos);
285+
                    if(lst.second.size() != 2)
286+
                        throw new ParseException();
287+
                    pos = lst.first;
288+
                    lastX1 = 2*lastX - lastX1;
289+
                    lastY1 = 2*lastY - lastY1;
290+
                    if(relative) {
291+
                        lastX += lst.second.get(0);
292+
                        lastY += lst.second.get(1);
293+
                    } else {
294+
                        lastX = lst.second.get(0);
295+
                        lastY = lst.second.get(1);
296+
                    }
297+
                    path.quadTo(lastX1, lastY1, lastX, lastY);
230298
                    break;
231299
                case 'z':
232300
                case 'Z':