Skip to content

方法名一样参数不一样的时候会判断为同一个方法,方法参数会混淆;没有对类的继承和子类的处理 #3

@lavon321

Description

@lavon321
Image

没有对方法名一样的处理:
Image

Image

没有对类的继承的·处理:

Image

NoCache类继承与RenderImpl类,其中的permission方法如下:

Image

没有对子类的处理:

Image
// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov.
// Jad home page: http://www.kpdus.com/jad.html
// Decompiler options: packimports(3) fieldsfirst 
// Source File Name:   Alter.java

package com.suwell.reader.v3;

import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParseException;
import com.google.gson.JsonParser;
import com.google.gson.reflect.TypeToken;
import com.suwell.ofd.render.OFDocument;
import com.suwell.ofd.render.RenderException;
import com.suwell.ofd.render.model.OFDAnnotation;
import com.suwell.ofd.render.model.OFDFont;
import com.suwell.ofd.render.model.OFDLine;
import com.suwell.ofd.render.model.OFDRect;
import com.suwell.ofd.render.model.gu.OFDPageBlock;
import com.suwell.ofd.render.model.gu.OFDPath;
import com.suwell.ofd.render.model.gu.OFDText;
import com.suwell.ofd.render.model.gu.TextCode;
import com.suwell.ofd.render.util.Annotations;
import com.suwell.ofd.render.util.ExtendedGeneralPath;
import com.suwell.ofd.render.util.ExtendedPathIterator;
import com.suwell.ofd.render.util.Operator;
import com.suwell.ofd.render.util.Security;
import com.suwell.reader.impl.CoreFactory;
import com.suwell.reader.resource.OFDResource;
import com.suwell.reader.resource.OFDStorage;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics2D;
import java.awt.Shape;
import java.awt.Stroke;
import java.awt.geom.AffineTransform;
import java.awt.geom.Area;
import java.awt.geom.Ellipse2D;
import java.awt.geom.GeneralPath;
import java.awt.geom.Line2D;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringWriter;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import javax.imageio.ImageIO;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.jcs3.JCS;
import org.apache.commons.jcs3.access.CacheAccess;
import org.apache.http.impl.io.EmptyInputStream;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;

// Referenced classes of package com.suwell.reader.v3:
//            Util, SVGPath, FileAccessNIO

public class Alter
{
    public static class Ret
    {

        private static final String KEY_RET = "ret";
        private static final String KEY_MSG = "msg";
        static final Ret NOT_STORAGE = new Ret(0, "Resource provider is not implements OFDStorage");
        static final Ret EMPTY = new Ret(0, "Data is empty");
        static final Ret NOT_FOUND = new Ret(0, "Not found any result by tid");
        public final int code;
        public final String message;

        boolean isFinish()
        {
            return code != 2;
        }

        boolean isOK()
        {
            return code == 1;
        }

        void fill(Map map)
        {
            map.put("ret", Integer.valueOf(code));
            if(message != null)
                map.put("msg", message);
        }


        public Ret(int code, String message)
        {
            this.code = code;
            this.message = message;
        }
    }

    private static class DRevision
    {

        String type;
        String textarea;
        java.util.List area;
        String id;

        static DRevision parse(JsonElement je)
        {
            DRevision dr = (DRevision)Alter.gson.fromJson(je, com/suwell/reader/v3/Alter$DRevision);
            return dr;
        }

        private DRevision()
        {
        }
    }

    static class DTStyle
    {

        private Map styles;

        static DTStyle parse(Map style)
        {
            DTStyle ts = new DTStyle();
            if(style == null)
                return ts;
            ts.styles = new LinkedHashMap();
            for(Iterator iterator = style.entrySet().iterator(); iterator.hasNext();)
            {
                java.util.Map.Entry entry = (java.util.Map.Entry)iterator.next();
                int row = Integer.valueOf((String)entry.getKey()).intValue();
                Map map = new LinkedHashMap();
                ts.styles.put(Integer.valueOf(row), map);
                Map val = (Map)entry.getValue();
                Iterator iterator1 = val.entrySet().iterator();
                while(iterator1.hasNext()) 
                {
                    java.util.Map.Entry me = (java.util.Map.Entry)iterator1.next();
                    int col = Integer.valueOf(me.getKey().toString()).intValue();
                    Map v = (Map)me.getValue();
                    LinkedHashMap lhm = new LinkedHashMap(v.size());
                    Object o;
                    for(Iterator iterator2 = v.keySet().iterator(); iterator2.hasNext(); lhm.put(o.toString(), v.get(o).toString()))
                        o = iterator2.next();

                    map.put(Integer.valueOf(col), lhm);
                }
            }

            return ts;
        }

        static DTStyle parse(String style)
        {
            DTStyle ts = new DTStyle();
            if(style == null)
                return ts;
            ts.styles = new LinkedHashMap();
            JsonParser jp = new JsonParser();
            try
            {
                JsonElement root = jp.parse(style);
                if(root.isJsonObject())
                {
                    Iterator iterator = root.getAsJsonObject().entrySet().iterator();
                    do
                    {
                        if(!iterator.hasNext())
                            break;
                        java.util.Map.Entry entry = (java.util.Map.Entry)iterator.next();
                        int row = Integer.valueOf((String)entry.getKey()).intValue();
                        Map map = new LinkedHashMap();
                        ts.styles.put(Integer.valueOf(row), map);
                        JsonElement je = (JsonElement)entry.getValue();
                        if(je.isJsonObject())
                        {
                            Iterator iterator1 = je.getAsJsonObject().entrySet().iterator();
                            while(iterator1.hasNext()) 
                            {
                                java.util.Map.Entry me = (java.util.Map.Entry)iterator1.next();
                                int col = Integer.valueOf((String)me.getKey()).intValue();
                                Map val = (Map)Alter.gson.fromJson((JsonElement)me.getValue(), (new TypeToken() {

                                }
).getType());
                                map.put(Integer.valueOf(col), val);
                            }
                        }
                    } while(true);
                }
            }
            catch(JsonParseException e)
            {
                Alter.log.error(e.getMessage(), e);
            }
            return ts;
        }

        Map style(int row, int column)
        {
            if(styles == null)
                return Collections.emptyMap();
            Map col = (Map)styles.get(Integer.valueOf(row));
            if(col == null)
                return Collections.emptyMap();
            Map m = (Map)col.get(Integer.valueOf(column));
            if(m == null)
                return Collections.emptyMap();
            else
                return m;
        }

        Font font(int row, int column)
        {
            Map map = style(row, column);
            String ff = (String)map.get("fontFamily");
            String fs = (String)map.get("fontSize");
            String fw = (String)map.get("fontWeight");
            String ft = (String)map.get("fontStyle");
            if(ff == null)
                ff = "SimSun";
            Font font = new Font(ff, 0, 3600);
            if(fs != null)
                font = font.deriveFont(java.lang.Float.valueOf(fs).floatValue() * 100F);
            if("bold".equals(fw))
                font = font.deriveFont(font.getStyle() | 1);
            if("italic".equals(ft))
                font = font.deriveFont(font.getStyle() | 2);
            return font;
        }

        Color color(int row, int column)
        {
            Map map = style(row, column);
            String c = (String)map.get("fill");
            Color r = DObject.toColor(c);
            return r != null ? r : new Color(0, 0, 0);
        }

        float height(int row)
        {
            Map map = style(row, -1);
            if(map == null || map.isEmpty())
                return 0.0F;
            String v = (String)map.get("height");
            if(v == null)
                return 0.0F;
            else
                return java.lang.Float.valueOf(v).floatValue();
        }

        DTStyle()
        {
        }
    }

    static class DObject
    {

        String type;
        float x;
        float y;
        float w;
        float h;
        String strokeColor;
        float lineWidth;
        String lineJoin;
        String lineCap;
        String path;
        boolean erase;
        String fillColor;
        String ID;
        Color color;
        ExtendedGeneralPath egp;
        String text;
        Map border;
        Map styles;
        DTStyle textStyle;

        private static int hex2int(String v)
        {
            return Integer.parseInt(v, 16);
        }

        boolean isText()
        {
            return type.contains("text");
        }

        private static Color toColor(String c)
        {
            if(Util.isEmpty(c))
                return null;
            if(c.startsWith("rgb"))
            {
                int i = c.indexOf("(");
                int j = c.indexOf(")");
                String v = c.substring(i + 1, j);
                String array[] = v.split(",");
                String r = array[0];
                String g = array[1];
                String b = array[2];
                String a = "255";
                if(c.startsWith("rgba"))
                    a = array[3];
                return new Color(Integer.valueOf(r).intValue(), Integer.valueOf(g).intValue(), Integer.valueOf(b).intValue(), Math.min(255, Math.round(Integer.valueOf(a).intValue() * 255)));
            }
            if(c.startsWith("#"))
                c = c.substring(1);
            String r = c.substring(0, 2);
            String g = c.substring(2, 4);
            String b = c.substring(4, 6);
            String a = "FF";
            if(c.length() > 6)
                a = c.substring(6);
            return new Color(hex2int(r), hex2int(g), hex2int(b), hex2int(a));
        }

        static DObject parse(JsonElement je)
        {
            DObject shape = (DObject)Alter.gson.fromJson(je, com/suwell/reader/v3/Alter$DObject);
            if(shape.isText())
                shape.textStyle = DTStyle.parse(shape.styles);
            else
            if(!Util.isEmpty(shape.path))
                if(shape.erase && "crate".equals(shape.type))
                {
                    ExtendedGeneralPath gp = new ExtendedGeneralPath(1);
                    String circles[] = shape.path.split(";");
                    String as[] = circles;
                    int i = as.length;
                    for(int j = 0; j < i; j++)
                    {
                        String circle = as[j];
                        String rxy[] = circle.split(" ");
                        float r = Util.floatValue(rxy[0], 0.0F);
                        float x = Util.floatValue(rxy[1], 0.0F);
                        float y = Util.floatValue(rxy[2], 0.0F);
                        java.awt.geom.Ellipse2D.Float e = new java.awt.geom.Ellipse2D.Float(x, y, r * 2.0F, r * 2.0F);
                        gp.append(e, false);
                    }

                    shape.egp = gp;
                } else
                {
                    shape.egp = SVGPath.parse(shape.path, 1);
                }
            if("gpath".equals(shape.type))
                shape.color = toColor(shape.fillColor);
            else
                shape.color = toColor(shape.strokeColor);
            return shape;
        }


        DObject()
        {
        }
    }

    private static class DPage
    {

        int index;
        float width;
        float height;
        java.util.List deleted;
        java.util.List shapes;
        java.util.List revisions;

        static DPage parse(JsonElement je)
        {
            DPage pp = (DPage)Alter.gson.fromJson(je, com/suwell/reader/v3/Alter$DPage);
            JsonObject jo = je.getAsJsonObject();
            JsonArray ja = jo.getAsJsonArray("s");
            if(ja != null)
            {
                pp.shapes = new ArrayList();
                Iterator iterator = ja.iterator();
                do
                {
                    if(!iterator.hasNext())
                        break;
                    JsonElement e = (JsonElement)iterator.next();
                    DObject shape = DObject.parse(e);
                    if(shape.egp != null || shape.isText())
                        pp.shapes.add(shape);
                } while(true);
            }
            ja = jo.getAsJsonArray("r");
            if(ja != null)
            {
                pp.revisions = new ArrayList();
                DRevision rev;
                for(Iterator iterator1 = ja.iterator(); iterator1.hasNext(); pp.revisions.add(rev))
                {
                    JsonElement e = (JsonElement)iterator1.next();
                    rev = DRevision.parse(e);
                }

            }
            return pp;
        }

        private DPage()
        {
        }
    }

    public static class Data
    {

        private String action;
        private Map extra;
        private java.util.List pages;







        public Data()
        {
        }
    }

    private static class PaintJob extends Job
    {

        private String data;

        protected Ret doCall()
            throws Exception
        {
            java.util.List ds;
            java.util.List nds;
            Map ext;
            OFDocument doc;
            Map map;
            ds = Alter.parse(data);
            nds = new ArrayList();
            if(ds == null || ds.isEmpty())
                return new Ret(0, "Data parse failed");
            Ret ret = next(true);
            if(ret != null)
                return ret;
            ext = new LinkedHashMap();
            doc = core.document();
            map = new LinkedHashMap();
            map.put("ID", fid);
            map.put("LastVersion", String.valueOf(version));
            map.put("Version", String.valueOf(nextVersion));
            core.setModify(true);
            Ret ret1;
            boolean modified = false;
            Iterator iterator = ds.iterator();
            do
            {
                if(!iterator.hasNext())
                    break;
                Data d = (Data)iterator.next();
                if(d.extra != null)
                    ext.putAll(d.extra);
                if("annot".equals(d.action) || "path".equals(d.action))
                    modified = Alter.addAnnot(doc, d, map) || modified;
                else
                if("sign".equals(d.action))
                    modified = Alter.addSign(doc) || modified;
                else
                if("revision".equals(d.action))
                {
                    java.util.List dPages = Alter.addRevision(doc, d, map);
                    if(d.pages != dPages)
                        d.pages = dPages;
                    nds.add(d);
                    modified = true;
                }
            } while(true);
            if(!modified)
                break MISSING_BLOCK_LABEL_389;
            try
            {
                doc.save();
                break MISSING_BLOCK_LABEL_389;
            }
            catch(RenderException e)
            {
                Alter.log.error(e.getMessage(), e);
                ret1 = new Ret(0, "Save file failed");
            }
            core.setModify(false);
            return ret1;
            core.setModify(false);
            break MISSING_BLOCK_LABEL_415;
            Exception exception;
            exception;
            core.setModify(false);
            throw exception;
            if(nds.isEmpty())
                ext.put("_data", data);
            else
                ext.put("_data", Alter.gson.toJson(nds));
            return writeBack(ext);
        }

        protected void doEnd()
        {
        }

        private PaintJob(OFDResource producer, OFDStorage os, String id, long version, String data)
        {
            super(producer, os, id, version);
            this.data = data;
        }

        PaintJob(OFDResource x0, OFDStorage x1, String x2, long x3, String x4, _cls1 x5)
        {
            this(x0, x1, x2, x3, x4);
        }
    }

    private static class DAJob extends Job
    {

        private int page;
        private String aid;
        private Map data;

        protected Ret doCall()
            throws Exception
        {
            Ret ret = next(true);
            if(ret != null)
                return ret;
            OFDocument doc = core.document();
            com.suwell.ofd.render.OFDocument.OFDPage op;
            boolean b;
            RenderException e;
            Ret ret1;
            Ret ret2;
            Exception exception;
            try
            {
                op = doc.getPageAt(page);
                if(op == null)
                    return new Ret(0, "Page is null");
            }
            catch(IndexOutOfBoundsException e)
            {
                return new Ret(0, "Page index is invalid");
            }
            core.setModify(true);
            b = Annotations.delete(op, aid);
            if(!b)
                break MISSING_BLOCK_LABEL_116;
            doc.save();
            break MISSING_BLOCK_LABEL_140;
            e;
            Alter.log.error(e.getMessage(), e);
            ret2 = new Ret(0, "Save file failed");
            core.setModify(false);
            return ret2;
            ret1 = new Ret(0, "Delete annotation failed");
            core.setModify(false);
            return ret1;
            core.setModify(false);
            break MISSING_BLOCK_LABEL_166;
            exception;
            core.setModify(false);
            throw exception;
            return writeBack(data);
        }

        protected void doEnd()
        {
        }

        private DAJob(OFDResource producer, OFDStorage os, String id, long version, int page, String aid, 
                Map data)
        {
            super(producer, os, id, version);
            this.page = page;
            this.aid = aid;
            this.data = data;
        }

        DAJob(OFDResource x0, OFDStorage x1, String x2, long x3, int x4, String x5, 
                Map x6, _cls1 x7)
        {
            this(x0, x1, x2, x3, x4, x5, x6);
        }
    }

    public static abstract class Job
        implements Callable
    {

        protected String tid;
        protected String fid;
        protected OFDResource producer;
        protected OFDStorage storage;
        protected long version;
        protected long nextVersion;
        protected File nextDir;
        protected File nextData;
        protected com.suwell.reader.impl.CoreFactory.Core core;

        void setTaskID(String tid)
        {
            this.tid = tid;
        }

        protected Ret next(boolean update)
        {
            File root = Util.baseDir(fid);
            File dir = new File(root, String.valueOf(version));
            FileAccessNIO access = new FileAccessNIO(producer, dir, fid, version);
            File data = null;
            try
            {
                data = access.selectData(5000L);
            }
            catch(Exception e)
            {
                Alter.log.error(e.getMessage(), e);
            }
            if(data == null)
                return new Ret(0, "File data is not readable");
            nextVersion = storage.next(fid, version);
            if(nextVersion <= version)
                return new Ret(0, String.format("Next version %d is less than current version %d", new Object[] {
                    Long.valueOf(nextVersion), Long.valueOf(version)
                }));
            nextDir = Util.mkdir(new File(root, String.valueOf(nextVersion)));
            nextData = new File(nextDir, ".data");
            if(update)
            {
                try
                {
                    FileUtils.copyFile(data, nextData);
                }
                catch(IOException e)
                {
                    Alter.log.error(e.getMessage(), e);
                    return new Ret(0, "Copy file failed");
                }
                try
                {
                    core = CoreFactory.instance().produce(nextData, fid, nextVersion);
                    return null;
                }
                catch(IOException e)
                {
                    Alter.log.error(e.getMessage(), e);
                }
                return new Ret(0, "Open file failed");
            } else
            {
                return null;
            }
        }

        protected Ret writeBack(Map data)
        {
            InputStream in = null;
            Ret ret;
            Util.create(new File(nextDir, ".mate"));
            in = FileUtils.openInputStream(nextData);
            if(storage.save(fid, nextVersion, in, data))
                break MISSING_BLOCK_LABEL_87;
            core.close(false);
            FileUtils.deleteQuietly(nextDir);
            ret = new Ret(0, String.valueOf(version));
            IOUtils.closeQuietly(in);
            return ret;
            ret = new Ret(1, String.valueOf(nextVersion));
            IOUtils.closeQuietly(in);
            return ret;
            IOException e;
            e;
            Ret ret1;
            Alter.log.error(e.getMessage(), e);
            ret1 = new Ret(0, "Store file failed");
            IOUtils.closeQuietly(in);
            return ret1;
            Exception exception;
            exception;
            IOUtils.closeQuietly(in);
            throw exception;
        }

        protected void writeFail(Map data)
        {
            try
            {
                storage.save(fid, version, EmptyInputStream.INSTANCE, data);
            }
            catch(IOException e)
            {
                e.printStackTrace();
            }
        }

        public Void call()
            throws Exception
        {
            Ret ret = doCall();
            doEnd();
            break MISSING_BLOCK_LABEL_71;
            Exception e;
            e;
            Alter.log.error(e.getMessage(), e);
            ret = new Ret(0, (new StringBuilder()).append("Other failed: ").append(e.getMessage()).toString());
            doEnd();
            break MISSING_BLOCK_LABEL_71;
            Exception exception;
            exception;
            doEnd();
            throw exception;
            if(!ret.isOK());
            Alter.toil.put(tid, ret);
            return null;
        }

        protected abstract Ret doCall()
            throws Exception;

        protected abstract void doEnd();

        public volatile Object call()
            throws Exception
        {
            return call();
        }

        protected Job(OFDResource producer, OFDStorage storage, String fid, long version)
        {
            this.fid = fid;
            this.producer = producer;
            this.storage = storage;
            this.version = version;
        }
    }


    private static Logger log = LoggerFactory.getLogger(com/suwell/reader/v3/Alter);
    static final int FONT_SIZE_RATIO = 100;
    public static final int RET_FAILED = 0;
    public static final int RET_OK = 1;
    public static final int RET_DOING = 2;
    static final String CREATOR = "SuwellWebReader";
    private static CacheAccess toil = JCS.getInstance("Toil");
    private static ExecutorService es = Executors.newFixedThreadPool(100);
    private static Gson gson = new Gson();

    public Alter()
    {
    }

    static Ret result(String uid)
    {
        Ret ret = (Ret)toil.get(uid);
        if(ret == null)
            ret = Ret.NOT_FOUND;
        return ret;
    }

    private static Data parse(JsonObject o)
    {
        Data d = new Data();
        String act = o.get("action").getAsString();
        d.action = act;
        JsonElement ee = o.get("extra");
        if(ee != null)
        {
            JsonObject ex = ee.getAsJsonObject();
            Iterator iterator = ex.entrySet().iterator();
            do
            {
                if(!iterator.hasNext())
                    break;
                java.util.Map.Entry me = (java.util.Map.Entry)iterator.next();
                String key = (String)me.getKey();
                JsonElement e = (JsonElement)me.getValue();
                if(e != null)
                {
                    String val = e.getAsString();
                    if(d.extra == null)
                        d.extra = new LinkedHashMap();
                    d.extra.put(key, val);
                }
            } while(true);
        }
        if("annot".equals(act) || "path".equals(act) || "revision".equals(act))
        {
            JsonArray pgs = o.getAsJsonArray("data");
            d.pages = new ArrayList(pgs.size());
            DPage pp;
            for(Iterator iterator1 = pgs.iterator(); iterator1.hasNext(); d.pages.add(pp))
            {
                JsonElement pg = (JsonElement)iterator1.next();
                pp = DPage.parse(pg);
            }

        }
        return d;
    }

    public static java.util.List parse(String data)
    {
        if(Util.isEmpty(data))
            return null;
        ArrayList list = new ArrayList();
        JsonParser jp = new JsonParser();
        try
        {
            JsonElement root = jp.parse(data);
            if(root.isJsonArray())
            {
                JsonArray ja = root.getAsJsonArray();
                Iterator iterator = ja.iterator();
                do
                {
                    if(!iterator.hasNext())
                        break;
                    JsonElement je = (JsonElement)iterator.next();
                    if(je.isJsonObject())
                    {
                        Data d = parse(je.getAsJsonObject());
                        if(d != null)
                            list.add(d);
                    }
                } while(true);
            } else
            if(root.isJsonObject())
            {
                JsonObject jo = root.getAsJsonObject();
                Data d = parse(jo);
                if(d != null)
                    list.add(d);
            }
        }
        catch(JsonParseException e)
        {
            log.error(e.getMessage(), e);
        }
        return list;
    }

    public static String doJob(Job job)
    {
        String uuid = UUID.randomUUID().toString();
        toil.put(uuid, new Ret(2, uuid));
        job.setTaskID(uuid);
        es.submit(job);
        return uuid;
    }

    static String paint(OFDResource producer, OFDStorage os, String id, long version, String data)
        throws IOException
    {
        return doJob(new PaintJob(producer, os, id, version, data));
    }

    static String delAnnot(OFDResource producer, OFDStorage os, String id, long version, int page, String aid, Map data)
        throws IOException
    {
        return doJob(new DAJob(producer, os, id, version, page, aid, data));
    }

    private static Shape ds2as(DObject shape)
    {
        ExtendedGeneralPath gp = shape.egp;
        if(shape.lineWidth > 0.0F)
        {
            int join = 1;
            if("miter".equalsIgnoreCase(shape.lineJoin))
                join = 0;
            else
            if("bevel".equalsIgnoreCase(shape.lineJoin))
                join = 2;
            int cap = 1;
            if("butt".equalsIgnoreCase(shape.lineCap))
                cap = 0;
            else
            if("square".equalsIgnoreCase(shape.lineCap))
                cap = 2;
            Stroke stroke = new BasicStroke(shape.lineWidth, cap, join, 10F);
            return stroke.createStrokedShape(gp);
        } else
        {
            return gp;
        }
    }

    private static void dump(Shape shape, String out)
    {
        BufferedImage bi = new BufferedImage(2000, 2000, 2);
        Graphics2D g = bi.createGraphics();
        g.setColor(Color.CYAN);
        g.fill(new java.awt.geom.Rectangle2D.Float(0.0F, 0.0F, bi.getWidth(), bi.getHeight()));
        g.setColor(Color.RED);
        g.fill(shape);
        g.dispose();
        try
        {
            ImageIO.write(bi, "png", new File(Util.mkdir(new File(Util.cacheDir, "alter")), out));
        }
        catch(IOException e)
        {
            e.printStackTrace();
        }
    }

    private static OFDAnnotation newAnnot(Map param, Map extra)
    {
        OFDAnnotation an = new OFDAnnotation();
        an.setCreator("SuwellWebReader");
        an.setLastModDate((new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")).format(new Date(System.currentTimeMillis())));
        Map args = new LinkedHashMap();
        if(param != null)
            args.putAll(param);
        if(extra != null)
            args.putAll(extra);
        an.setParameter(args);
        return an;
    }

    private static boolean addFreeText(OFDocument document, DPage dp, DObject dob, Map param, Map extra)
    {
        com.suwell.ofd.render.OFDocument.OFDPage page = document.getPageAt(dp.index);
        float size[] = page.size();
        float mw = size[0];
        float mh = size[1];
        float sx = mw / dp.width;
        float sy = mh / dp.height;
        float bx = dob.x * sx;
        float by = dob.y * sy;
        float bw = dob.w * sx;
        float bh = dob.h * sy;
        OFDAnnotation an = newAnnot(param, extra);
        an.setType(4);
        an.setSubtype("FreeText");
        an.setReadonly(false);
        OFDRect rect = new OFDRect(bx, by, bw, bh);
        fillFreeText(sx, sy, rect, an, dob.text, dob.textStyle, dob.color, dob.border);
        if("".equals(dob.ID) || null == dob.ID)
        {
            return page.operator(com/suwell/ofd/render/model/OFDAnnotation).add(an);
        } else
        {
            an.setId(dob.ID);
            return page.operator(com/suwell/ofd/render/model/OFDAnnotation).modify(an);
        }
    }

    static void fillFreeText(float sx, float sy, OFDRect rect, OFDAnnotation an, String text, DTStyle dts, Color bgc, Map border)
    {
        float bw = rect.getWidth();
        float bh = rect.getHeight();
        OFDRect bound = new OFDRect(0.0F, 0.0F, bw, bh);
        Map args = an.getParameter();
        args.put("text", text);
        args.put("transparent", "0");
        OFDPageBlock block = new OFDPageBlock();
        if(bgc != null)
        {
            OFDPath path = new OFDPath();
            path.setBoundary(bound);
            path.setPath(new java.awt.geom.Rectangle2D.Double(0.0D, 0.0D, bw, bh));
            path.setFill(bgc);
            path.setStroke(null);
            block.add(path);
            args.put("fillcolor", String.format("#%02x%02x%02x", new Object[] {
                Integer.valueOf(bgc.getRed()), Integer.valueOf(bgc.getGreen()), Integer.valueOf(bgc.getBlue())
            }));
        }
        Document xml = null;
        try
        {
            xml = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
        }
        catch(ParserConfigurationException e)
        {
            log.error(e.getMessage(), e);
        }
        Element fl = null;
        if(xml != null)
        {
            fl = xml.createElement("fragmentlist");
            xml.appendChild(fl);
        }
        String lines[] = text.split("\n");
        BufferedImage bi = new BufferedImage(1, 1, 2);
        Graphics2D g2d = bi.createGraphics();
        float ty = 0.0F;
        java.util.List codes = new ArrayList();
        int row = 0;
        for(int len = lines.length; row < len; row++)
        {
            String line = lines[row];
            float tx = 0.0F;
            float maxH = 0.0F;
            codes.clear();
            int col = 0;
            for(int l = line.length(); col < l; col++)
            {
                char c = line.charAt(col);
                Font af = dts.font(row, col);
                Color ac = dts.color(row, col);
                FontMetrics fm = g2d.getFontMetrics(af);
                OFDText ot = new OFDText();
                ot.setFill(ac);
                ot.setBoundary(bound);
                OFDFont of = new OFDFont();
                of.setName(af.getName());
                of.setSize((af.getSize2D() * sy) / 100F);
                if(af.isBold())
                    of.setWeight(700);
                of.setItalic(af.isItalic());
                ot.setFont(of);
                TextCode code = new TextCode(tx, ((float)fm.getDescent() * sy) / 100F, c);
                ot.addCode(code);
                codes.add(code);
                block.add(ot);
                maxH = Math.max(maxH, of.getSize());
                tx += ((float)fm.charWidth(c) * sx) / 100F;
                if(fl != null)
                {
                    Element fragment = xml.createElement("fragment");
                    fl.appendChild(fragment);
                    fragment.setAttribute("content", String.valueOf(c));
                    fragment.setAttribute("fontSize", String.valueOf(Math.round((double)(of.getSize() * 72F) / 25.399999999999999D)));
                    fragment.setAttribute("fontBold", String.valueOf(af.isBold()));
                    fragment.setAttribute("blockIndex", String.valueOf(row));
                    fragment.setAttribute("fontUnderline", String.valueOf(false));
                    fragment.setAttribute("fontItalic", String.valueOf(af.isItalic()));
                    fragment.setAttribute("fontColor", String.format("#%02x%02x%02x", new Object[] {
                        Integer.valueOf(ac.getRed()), Integer.valueOf(ac.getGreen()), Integer.valueOf(ac.getBlue())
                    }));
                    fragment.setAttribute("fontName", String.valueOf(af.getName()));
                }
            }

            if(maxH <= 0.0F)
            {
                Font af = dts.font(row, 0);
                maxH = (af.getSize2D() * sy) / 100F;
            }
            ty += maxH;
            TextCode code;
            for(Iterator iterator = codes.iterator(); iterator.hasNext(); code.setY(ty - code.getY()))
                code = (TextCode)iterator.next();

        }

        g2d.dispose();
        if(fl != null)
            try
            {
                StringWriter sw = new StringWriter();
                Transformer tf = TransformerFactory.newInstance().newTransformer();
                tf.transform(new DOMSource(fl), new StreamResult(sw));
                String ret = sw.toString();
                int index = ret.indexOf("<fragmentlist>");
                if(index > 0)
                    ret = ret.substring(index);
                args.put("formattext", ret);
            }
            catch(TransformerException e)
            {
                log.error(e.getMessage(), e);
            }
        if(border != null)
        {
            boolean visible = true;
            OFDLine line = new OFDLine();
            String width = (String)border.get("width");
            String style = (String)border.get("style");
            String color = (String)border.get("color");
            float w = java.lang.Float.valueOf(width).floatValue() * sx;
            if(w > 0.0F)
                line.setWidth(w);
            else
                visible = false;
            int sv = 0;
            if("none".equals(style))
                sv = 1;
            else
            if("dash".equals(style))
            {
                line.setDashPattern(new float[] {
                    5F * sx, 1.0F * sx
                });
                sv = 2;
            } else
            if("dot".equals(style))
            {
                line.setDashPattern(new float[] {
                    2.0F * sx, 1.0F * sx
                });
                sv = 3;
            } else
            if("dashdot".equals(style))
            {
                line.setDashPattern(new float[] {
                    5F * sx, 1.0F * sx, 2.0F * sx, 1.0F * sx
                });
                sv = 4;
            } else
            if("dashdotdot".equals(style))
            {
                line.setDashPattern(new float[] {
                    5F * sx, 1.0F * sx, 2.0F * sx, 1.0F * sx, 2.0F * sx, 1.0F * sx
                });
                sv = 5;
            } else
            {
                visible = false;
            }
            if(visible)
            {
                args.put("framestyle", String.valueOf(sv));
                args.put("framewidth", String.valueOf(w));
                Color c = DObject.toColor(color);
                if(c != null)
                    args.put("framecolor", String.format("#%02x%02x%02x", new Object[] {
                        Integer.valueOf(c.getRed()), Integer.valueOf(c.getGreen()), Integer.valueOf(c.getBlue())
                    }));
                OFDPath path = new OFDPath();
                path.setBoundary(bound);
                path.setPath(new ExtendedGeneralPath(new java.awt.geom.Rectangle2D.Double(w / 2.0F, w / 2.0F, bw - w, bh - w)));
                path.setFill(null);
                path.setStroke(c);
                path.setLine(line);
                block.add(path);
            }
        }
        an.setBoundary(rect);
        an.setAppearance(block);
    }

    public static boolean addAnnot(OFDocument document, Data data, Map param)
        throws IndexOutOfBoundsException
    {
        java.util.List dps = data.pages;
        if(dps == null || dps.isEmpty())
            return false;
        boolean b = false;
        Iterator iterator = dps.iterator();
        do
        {
            if(!iterator.hasNext())
                break;
            DPage dp = (DPage)iterator.next();
            java.util.List list = dp.shapes;
            if(list != null && !list.isEmpty())
            {
                int len = list.size();
                boolean hasErase = false;
                Area es[] = new Area[list.size()];
                Shape gs[] = new Shape[list.size()];
                Rectangle2D bound = null;
                for(int i = 0; i < len; i++)
                {
                    DObject shape = (DObject)list.get(i);
                    if(shape.isText())
                    {
                        b = addFreeText(document, dp, shape, param, data.extra) || b;
                        continue;
                    }
                    Shape as = ds2as(shape);
                    Rectangle2D rect = as.getBounds2D();
                    if(rect.getWidth() <= 0.0D || rect.getHeight() <= 0.0D)
                        continue;
                    if(shape.erase)
                    {
                        es[i] = new Area(as);
                        hasErase = true;
                        continue;
                    }
                    gs[i] = as;
                    if(bound == null)
                        bound = rect;
                    else
                        bound = bound.createUnion(rect);
                }

                if(bound != null)
                {
                    com.suwell.ofd.render.OFDocument.OFDPage page = document.getPageAt(dp.index);
                    float size[] = page.size();
                    float mw = size[0];
                    float mh = size[1];
                    float sx = mw / dp.width;
                    float sy = mh / dp.height;
                    double bx = bound.getX() * (double)sx;
                    double by = bound.getY() * (double)sy;
                    OFDAnnotation an = newAnnot(param, data.extra);
                    an.setType(2);
                    an.setSubtype("PolyLine");
                    OFDPageBlock block = new OFDPageBlock();
                    for(int i = 0; i < len; i++)
                    {
                        Shape as = gs[i];
                        if(as == null)
                            continue;
                        DObject shape = (DObject)list.get(i);
                        if(shape.erase)
                            continue;
                        GeneralPath gp;
                        if(hasErase)
                        {
                            Area area = new Area(as);
                            for(int e = i + 1; e < len; e++)
                            {
                                Area erase = es[e];
                                if(erase != null)
                                    area.subtract(erase);
                            }

                            if(area.isEmpty())
                            {
                                log.debug("After erase, shape is emtpy");
                                continue;
                            }
                            gp = new GeneralPath(area);
                        } else
                        {
                            gp = new GeneralPath(as);
                        }
                        Rectangle2D rect = gp.getBounds2D();
                        double x = rect.getX();
                        double y = rect.getY();
                        gp.transform(AffineTransform.getTranslateInstance(-x, -y));
                        gp.transform(AffineTransform.getScaleInstance(sx, sy));
                        rect = gp.getBounds2D();
                        double w = rect.getWidth();
                        double h = rect.getHeight();
                        OFDPath path = new OFDPath();
                        path.setBoundary(new OFDRect((float)(x * (double)sx - bx), (float)(y * (double)sy - by), (float)w, (float)h));
                        path.setPath(gp);
                        path.setFill(shape.color);
                        block.add(path);
                    }

                    if(block.getChildren().isEmpty())
                    {
                        log.debug("All unit empty");
                    } else
                    {
                        an.setBoundary(new OFDRect((float)bx, (float)by, (float)bound.getWidth() * sx, (float)bound.getHeight() * sy));
                        an.setAppearance(block);
                        b = page.operator(com/suwell/ofd/render/model/OFDAnnotation).add(an) || b;
                    }
                }
            }
        } while(true);
        return b;
    }

    static boolean addSign(OFDocument document)
    {
        com.suwell.ofd.render.util.Security.OES oes = new com.suwell.ofd.render.util.Security.OES("", "", "");
        return Security.signature(document, oes, 42F, 42F, new com.suwell.ofd.render.util.Security.Place[] {
            new com.suwell.ofd.render.util.Security.Place(0, 0.0F, 0.0F)
        });
    }

    public static java.util.List addRevision(OFDocument document, Data data, Map param)
    {
        java.util.List dps = data.pages;
        java.util.List ndps = new ArrayList();
        if(dps == null || dps.isEmpty())
            return dps;
        boolean b = false;
        for(Iterator iterator = dps.iterator(); iterator.hasNext();)
        {
            DPage dp = (DPage)iterator.next();
            java.util.List del = dp.deleted;
            com.suwell.ofd.render.OFDocument.OFDPage page = document.getPageAt(dp.index);
            if(del != null)
            {
                for(Iterator iterator1 = del.iterator(); iterator1.hasNext();)
                {
                    String id = (String)iterator1.next();
                    b = Annotations.delete(page, id) || b;
                }

            }
            java.util.List list = dp.revisions;
            java.util.List nlist = new ArrayList();
            if(list == null || list.isEmpty())
            {
                ndps.add(dp);
            } else
            {
                float size[] = page.size();
                float mw = size[0];
                float mh = size[1];
                float sx = mw / dp.width;
                float sy = mh / dp.height;
                Iterator iterator2 = list.iterator();
                do
                {
                    if(!iterator2.hasNext())
                        break;
                    DRevision revision = (DRevision)iterator2.next();
                    java.util.List area = revision.area;
                    Rectangle2D r2d = null;
                    java.util.List rs = new ArrayList();
                    Rectangle2D r;
                    for(Iterator iterator3 = area.iterator(); iterator3.hasNext(); rs.add(r))
                    {
                        java.util.List rect = (java.util.List)iterator3.next();
                        float x = ((Float)rect.get(0)).floatValue();
                        float y = ((Float)rect.get(1)).floatValue();
                        float w = ((Float)rect.get(2)).floatValue();
                        float h = ((Float)rect.get(3)).floatValue();
                        r = new java.awt.geom.Rectangle2D.Float(x * sx, y * sy, w * sx, h * sy);
                        if(r2d == null)
                            r2d = r;
                        else
                            r2d = r2d.createUnion(r);
                    }

                    if(!rs.isEmpty())
                    {
                        OFDAnnotation an = newAnnot(param, data.extra);
                        an.setReadonly(false);
                        Map args = an.getParameter();
                        Rectangle2D last = null;
                        OFDPageBlock block = new OFDPageBlock();
                        String type = revision.type;
                        if("add".equals(type))
                        {
                            an.setType(3);
                            an.setSubtype("AddRevisions");
                            an.setRemark(revision.textarea);
                            for(Iterator iterator4 = rs.iterator(); iterator4.hasNext();)
                            {
                                Rectangle2D r = (Rectangle2D)iterator4.next();
                                OFDPath path = new OFDPath();
                                path.setBoundary(new OFDRect((float)(r.getX() - r2d.getX()), (float)(r.getY() - r2d.getY()), (float)r.getWidth(), (float)r.getHeight()));
                                path.setPath(new ExtendedGeneralPath(new java.awt.geom.Rectangle2D.Double(0.0D, 0.0D, r.getWidth(), r.getHeight())));
                                path.setFill(new Color(255, 237, 0));
                                block.add(path);
                                last = r;
                            }

                        } else
                        if("del".equals(type))
                        {
                            an.setType(7);
                            an.setSubtype("DelRevisions");
                            for(Iterator iterator5 = rs.iterator(); iterator5.hasNext();)
                            {
                                Rectangle2D r = (Rectangle2D)iterator5.next();
                                OFDPath path = new OFDPath();
                                float w = (float)r.getWidth();
                                float h = (float)r.getHeight();
                                float lw = 0.6271F;
                                float y = h / 2.0F + lw / 2.0F;
                                path.setBoundary(new OFDRect((float)(r.getX() - r2d.getX()), (float)(r.getY() - r2d.getY()), w, h));
                                path.setPath(new ExtendedGeneralPath(new java.awt.geom.Line2D.Double(0.0D, y, w, y)));
                                OFDLine line = new OFDLine();
                                line.setWidth(lw);
                                path.setLine(line);
                                path.setStroke(new Color(249, 66, 68));
                                block.add(path);
                                last = r;
                            }

                        }
                        args.put("keyPoint", (new StringBuilder()).append(last.getMaxX()).append(" ").append(last.getMaxY()).toString());
                        an.setBoundary(new OFDRect((float)r2d.getX(), (float)r2d.getY(), (float)r2d.getWidth(), (float)r2d.getHeight()));
                        an.setAppearance(block);
                        b = page.operator(com/suwell/ofd/render/model/OFDAnnotation).add(an) || b;
                        revision.id = an.getId();
                        nlist.add(revision);
                    }
                    if(!nlist.isEmpty())
                        dp.revisions = nlist;
                } while(true);
                ndps.add(dp);
            }
        }

        return ndps;
    }




}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions