class FontSelector {

    protected ArrayList<Font> fonts = new ArrayList<>();

    public FontSelector() {
        FontFactory.register("font-fallback/LiberationSans-Regular.ttf", "sans");
        Font font = FontFactory.getFont("sans", BaseFont.IDENTITY_H);
        fonts.add(font);
    }

    /**
     * change the color of default font in <CODE>FontSelector</CODE>.
     *
     * @param color the <CODE>Color</CODE> of default font
     */
    public void setDefaultColor(Color color) {
        fonts.get(fonts.size() - 1).setColor(color);
    }

    /**
     * change the size of default font in <CODE>FontSelector</CODE>.
     *
     * @param size the size of default font
     */
    public void setDefaultSize(float size) {
        fonts.get(fonts.size() - 1).setSize(size);
    }

    /**
     * Adds a <CODE>Font</CODE> to be searched for valid characters.
     *
     * @param font the <CODE>Font</CODE>
     */
    public void addFont(Font font) {
        if (font.getBaseFont() != null) {
            fonts.add(fonts.size() - 1, font);
            return;
        }
        BaseFont bf = font.getCalculatedBaseFont(true);
        Font f2 = new Font(bf, font.getSize(), font.getCalculatedStyle(), font.getColor());
        fonts.add(fonts.size() - 1, f2);
    }

    /**
     * Process the text so that it will render with a combination of fonts if needed.
     *
     * @param text the text
     * @return a <CODE>Phrase</CODE> with one or more chunks
     */
    public Phrase process(String text) {<FILL_FUNCTION_BODY>}
}

        int fsize = fonts.size();
        char[] cc = text.toCharArray();
        int len = cc.length;
        StringBuilder sb = new StringBuilder();
        Font font = null;
        int lastidx = -1;
        Phrase ret = new Phrase();
        for (int k = 0; k < len; ++k) {
            char c = cc[k];
            if (c == '\n' || c == '\r') {
                sb.append(c);
                continue;
            }
            if (Utilities.isSurrogatePair(cc, k)) {
                int u = Utilities.convertToUtf32(cc, k);
                for (int f = 0; f < fsize; ++f) {
                    font = fonts.get(f);
                    if (font.getBaseFont().charExists(u)) {
                        if (lastidx != f) {
                            if (sb.length() > 0 && lastidx != -1) {
                                Chunk ck = new Chunk(sb.toString(), fonts.get(lastidx));
                                ret.add(ck);
                                sb.setLength(0);
                            }
                            lastidx = f;
                        }
                        sb.append(c);
                        if (cc.length > k + 1) {
                            sb.append(cc[++k]);
                        }
                        break;
                    }
                }
            } else {
                for (int f = 0; f < fsize; ++f) {
                    font = fonts.get(f);
                    if (font.getBaseFont().charExists(c)) {
                        if (lastidx != f) {
                            if (sb.length() > 0 && lastidx != -1) {
                                Chunk ck = new Chunk(sb.toString(), fonts.get(lastidx));
                                ret.add(ck);
                                sb.setLength(0);
                            }
                            lastidx = f;
                        }
                        sb.append(c);
                        break;
                    }
                }
            }
        }
        if (sb.length() > 0) {
            Chunk ck;
            if (lastidx == -1) {
                ck = new Chunk(sb.toString());
            } else {
                ck = new Chunk(sb.toString(), fonts.get(lastidx));
            }
            ret.add(ck);
        }
        return ret;
    
<no_super_class>