Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5e7ed8da authored by Xavier Ducrohet's avatar Xavier Ducrohet
Browse files

Move layoutlib typeface implementation to delegate.

Also move BridgeContentProvider to its own class to make it
less messy in BridgeContentResolver.

Change-Id: Id3462218b500d43d4c9b20b25326ad24e4106fa5
parent 162b689c
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -249,7 +249,7 @@ public class Paint extends _Original_Paint {
    private void updateFontObject() {
        if (mTypeface != null) {
            // Get the fonts from the TypeFace object.
            List<Font> fonts = mTypeface.getFonts();
            List<Font> fonts = Typeface_Delegate.getFonts(mTypeface);

            // create new font objects as well as FontMetrics, based on the current text size
            // and skew info.
+0 −190
Original line number Diff line number Diff line
/*
 * Copyright (C) 2008 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.graphics;

import com.android.layoutlib.bridge.FontLoader;

import android.content.res.AssetManager;

import java.awt.Font;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * Re-implementation of Typeface over java.awt
 */
public class Typeface {
    private static final String DEFAULT_FAMILY = "sans-serif";
    private static final int[] styleBuffer = new int[1];

    /** The default NORMAL typeface object */
    public static Typeface DEFAULT;
    /**
     * The default BOLD typeface object. Note: this may be not actually be
     * bold, depending on what fonts are installed. Call getStyle() to know
     * for sure.
     */
    public static Typeface DEFAULT_BOLD;
    /** The NORMAL style of the default sans serif typeface. */
    public static Typeface SANS_SERIF;
    /** The NORMAL style of the default serif typeface. */
    public static Typeface SERIF;
    /** The NORMAL style of the default monospace typeface. */
    public static Typeface MONOSPACE;

    private static Typeface[] sDefaults;
    private static FontLoader mFontLoader;

    private final int mStyle;
    private final List<Font> mFonts;
    private final String mFamily;

    // Style
    public static final int NORMAL = _Original_Typeface.NORMAL;
    public static final int BOLD = _Original_Typeface.BOLD;
    public static final int ITALIC = _Original_Typeface.ITALIC;
    public static final int BOLD_ITALIC = _Original_Typeface.BOLD_ITALIC;

    /**
     * Returns the underlying {@link Font} objects. The first item in the list is the real
     * font. Any other items are fallback fonts for characters not found in the first one.
     */
    public List<Font> getFonts() {
        return mFonts;
    }

    /** Returns the typeface's intrinsic style attributes */
    public int getStyle() {
        return mStyle;
    }

    /** Returns true if getStyle() has the BOLD bit set. */
    public final boolean isBold() {
        return (getStyle() & BOLD) != 0;
    }

    /** Returns true if getStyle() has the ITALIC bit set. */
    public final boolean isItalic() {
        return (getStyle() & ITALIC) != 0;
    }

    /**
     * Create a typeface object given a family name, and option style information.
     * If null is passed for the name, then the "default" font will be chosen.
     * The resulting typeface object can be queried (getStyle()) to discover what
     * its "real" style characteristics are.
     *
     * @param familyName May be null. The name of the font family.
     * @param style  The style (normal, bold, italic) of the typeface.
     *               e.g. NORMAL, BOLD, ITALIC, BOLD_ITALIC
     * @return The best matching typeface.
     */
    public static Typeface create(String familyName, int style) {
        styleBuffer[0] = style;
        Font font = mFontLoader.getFont(familyName, styleBuffer);
        if (font != null) {
            ArrayList<Font> list = new ArrayList<Font>();
            list.add(font);
            list.addAll(mFontLoader.getFallBackFonts());
            return new Typeface(familyName, styleBuffer[0], list);
        }

        return null;
    }

    /**
     * Create a typeface object that best matches the specified existing
     * typeface and the specified Style. Use this call if you want to pick a new
     * style from the same family of an existing typeface object. If family is
     * null, this selects from the default font's family.
     *
     * @param family May be null. The name of the existing type face.
     * @param style  The style (normal, bold, italic) of the typeface.
     *               e.g. NORMAL, BOLD, ITALIC, BOLD_ITALIC
     * @return The best matching typeface.
     */
    public static Typeface create(Typeface family, int style) {
        styleBuffer[0] = style;
        Font font = mFontLoader.getFont(family.mFamily, styleBuffer);
        if (font != null) {
            ArrayList<Font> list = new ArrayList<Font>();
            list.add(font);
            list.addAll(mFontLoader.getFallBackFonts());
            return new Typeface(family.mFamily, styleBuffer[0], list);
        }

        return null;
    }

    /**
     * Returns one of the default typeface objects, based on the specified style
     *
     * @return the default typeface that corresponds to the style
     */
    public static Typeface defaultFromStyle(int style) {
        return sDefaults[style];
    }

    /**
     * Create a new typeface from the specified font data.
     * @param mgr The application's asset manager
     * @param path  The file name of the font data in the assets directory
     * @return The new typeface.
     */
    public static Typeface createFromAsset(AssetManager mgr, String path) {
        return null;
        //return new Typeface(nativeCreateFromAsset(mgr, path));
    }

    // don't allow clients to call this directly
    private Typeface(String family, int style, List<Font> fonts) {
        mFamily = family;
        mFonts = Collections.unmodifiableList(fonts);
        mStyle = style;
    }

    public static void init(FontLoader fontLoader) {
        mFontLoader = fontLoader;

        DEFAULT = create(DEFAULT_FAMILY, NORMAL);
        DEFAULT_BOLD = create(DEFAULT_FAMILY, BOLD);
        SANS_SERIF = create("sans-serif", NORMAL);
        SERIF = create("serif", NORMAL);
        MONOSPACE = create("monospace", NORMAL);
        sDefaults = new Typeface[] {
                DEFAULT,
                DEFAULT_BOLD,
                create(DEFAULT_FAMILY, ITALIC),
                create(DEFAULT_FAMILY, BOLD_ITALIC),
        };

        /*
        DEFAULT         = create((String)null, 0);
        DEFAULT_BOLD    = create((String)null, Typeface.BOLD);
        SANS_SERIF      = create("sans-serif", 0);
        SERIF           = create("serif", 0);
        MONOSPACE       = create("monospace", 0);

        sDefaults = new Typeface[] {
            DEFAULT,
            DEFAULT_BOLD,
            create((String)null, Typeface.ITALIC),
            create((String)null, Typeface.BOLD_ITALIC),
        };*/
    }
}
+171 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2010 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.graphics;

import com.android.layoutlib.bridge.DelegateManager;
import com.android.layoutlib.bridge.FontLoader;

import android.content.res.AssetManager;

import java.awt.Font;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * Delegate implementing the native methods of android.graphics.Typeface
 *
 * Through the layoutlib_create tool, the original native methods of Typeface have been replaced
 * by calls to methods of the same name in this delegate class.
 *
 * This class behaves like the original native implementation, but in Java, keeping previously
 * native data into its own objects and mapping them to int that are sent back and forth between
 * it and the original Matrix class.
 *
 * @see DelegateManager
 *
 */
public final class Typeface_Delegate {

    // ---- delegate manager ----
    private static final DelegateManager<Typeface_Delegate> sManager =
            new DelegateManager<Typeface_Delegate>();

    // ---- delegate helper data ----
    private static final String DEFAULT_FAMILY = "sans-serif";
    private static final int[] STYLE_BUFFER = new int[1];

    private static FontLoader sFontLoader;
    private static final List<Typeface_Delegate> sPostInitDelegate =
            new ArrayList<Typeface_Delegate>();

    // ---- delegate data ----

    private final String mFamily;
    private int mStyle;
    private List<Font> mFonts;


    // ---- Public Helper methods ----

    public static synchronized void init(FontLoader fontLoader) {
        sFontLoader = fontLoader;

        for (Typeface_Delegate delegate : sPostInitDelegate) {
            delegate.init();
        }
        sPostInitDelegate.clear();
    }

    public static List<Font> getFonts(Typeface typeface) {
        Typeface_Delegate delegate = sManager.getDelegate(typeface.native_instance);
        if (delegate == null) {
            assert false;
            return null;
        }

        return delegate.mFonts;
    }


    // ---- native methods ----

    public static synchronized int nativeCreate(String familyName, int style) {
        if (familyName == null) {
            familyName = DEFAULT_FAMILY;
        }

        Typeface_Delegate newDelegate = new Typeface_Delegate(familyName, style);
        if (sFontLoader != null) {
            newDelegate.init();
        } else {
            // font loader has not been initialized yet, add the delegate to a list of delegates
            // to init when the font loader is initialized.
            // There won't be any rendering before this happens anyway.
            sPostInitDelegate.add(newDelegate);
        }

        return sManager.addDelegate(newDelegate);
    }

    public static synchronized int nativeCreateFromTypeface(int native_instance, int style) {
        Typeface_Delegate delegate = sManager.getDelegate(native_instance);
        if (delegate == null) {
            assert false;
            return 0;
        }

        Typeface_Delegate newDelegate = new Typeface_Delegate(delegate.mFamily, style);
        if (sFontLoader != null) {
            newDelegate.init();
        } else {
            // font loader has not been initialized yet, add the delegate to a list of delegates
            // to init when the font loader is initialized.
            // There won't be any rendering before this happens anyway.
            sPostInitDelegate.add(newDelegate);
        }

        return sManager.addDelegate(newDelegate);
    }

    public static synchronized int nativeCreateFromAsset(AssetManager mgr, String path) {
        // FIXME
        throw new UnsupportedOperationException();
    }

    public static synchronized int nativeCreateFromFile(String path) {
        // FIXME
        throw new UnsupportedOperationException();
    }

    public static void nativeUnref(int native_instance) {
        sManager.removeDelegate(native_instance);
    }

    public static int nativeGetStyle(int native_instance) {
        Typeface_Delegate delegate = sManager.getDelegate(native_instance);
        if (delegate == null) {
            assert false;
            return 0;
        }

        return delegate.mStyle;
    }

    public static void setGammaForText(float blackGamma, float whiteGamma) {
        // This is for device testing only: pass
    }

    // ---- Private delegate/helper methods ----

    private Typeface_Delegate(String family, int style) {
        mFamily = family;
        mStyle = style;
    }

    private void init() {
        STYLE_BUFFER[0] = mStyle;
        Font font = sFontLoader.getFont(mFamily, STYLE_BUFFER);
        if (font != null) {
            List<Font> list = new ArrayList<Font>();
            list.add(font);
            list.addAll(sFontLoader.getFallBackFonts());
            mFonts = Collections.unmodifiableList(list);
            mStyle = STYLE_BUFFER[0];
        }
    }
}
+4 −5
Original line number Diff line number Diff line
@@ -31,13 +31,12 @@ import com.android.tools.layoutlib.create.MethodAdapter;
import com.android.tools.layoutlib.create.OverrideMethod;

import android.content.ClipData;
import android.content.ClipDescription;
import android.content.res.Configuration;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.graphics.Region;
import android.graphics.Typeface;
import android.graphics.Typeface_Delegate;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.Handler;
@@ -49,9 +48,9 @@ import android.util.DisplayMetrics;
import android.util.TypedValue;
import android.view.BridgeInflater;
import android.view.DragEvent;
import android.view.InputChannel;
import android.view.IWindow;
import android.view.IWindowSession;
import android.view.InputChannel;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.Surface;
@@ -220,7 +219,7 @@ public final class Bridge implements ILayoutBridge {
        // load the fonts.
        FontLoader fontLoader = FontLoader.create(fontOsLocation);
        if (fontLoader != null) {
            Typeface.init(fontLoader);
            Typeface_Delegate.init(fontLoader);
        } else {
            return false;
        }
+122 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2010 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.layoutlib.bridge;

import android.content.ContentProviderOperation;
import android.content.ContentProviderResult;
import android.content.ContentValues;
import android.content.IContentProvider;
import android.content.OperationApplicationException;
import android.content.res.AssetFileDescriptor;
import android.database.Cursor;
import android.database.CursorWindow;
import android.database.IBulkCursor;
import android.database.IContentObserver;
import android.net.Uri;
import android.os.Bundle;
import android.os.IBinder;
import android.os.ParcelFileDescriptor;
import android.os.RemoteException;

import java.io.FileNotFoundException;
import java.util.ArrayList;

/**
 * Mock implementation of {@link IContentProvider}.
 *
 * TODO: never return null when the method is not supposed to. Return fake data instead.
 */
public final class BridgeContentProvider implements IContentProvider {

    public ContentProviderResult[] applyBatch(ArrayList<ContentProviderOperation> arg0)
            throws RemoteException, OperationApplicationException {
        // TODO Auto-generated method stub
        return null;
    }

    public int bulkInsert(Uri arg0, ContentValues[] arg1) throws RemoteException {
        // TODO Auto-generated method stub
        return 0;
    }

    public IBulkCursor bulkQuery(Uri arg0, String[] arg1, String arg2, String[] arg3,
            String arg4, IContentObserver arg5, CursorWindow arg6) throws RemoteException {
        // TODO Auto-generated method stub
        return null;
    }

    public Bundle call(String arg0, String arg1, Bundle arg2) throws RemoteException {
        // TODO Auto-generated method stub
        return null;
    }

    public int delete(Uri arg0, String arg1, String[] arg2) throws RemoteException {
        // TODO Auto-generated method stub
        return 0;
    }

    public String getType(Uri arg0) throws RemoteException {
        // TODO Auto-generated method stub
        return null;
    }

    public Uri insert(Uri arg0, ContentValues arg1) throws RemoteException {
        // TODO Auto-generated method stub
        return null;
    }

    public AssetFileDescriptor openAssetFile(Uri arg0, String arg1) throws RemoteException,
            FileNotFoundException {
        // TODO Auto-generated method stub
        return null;
    }

    public ParcelFileDescriptor openFile(Uri arg0, String arg1) throws RemoteException,
            FileNotFoundException {
        // TODO Auto-generated method stub
        return null;
    }

    public Cursor query(Uri arg0, String[] arg1, String arg2, String[] arg3, String arg4)
            throws RemoteException {
        // TODO Auto-generated method stub
        return null;
    }

    public int update(Uri arg0, ContentValues arg1, String arg2, String[] arg3)
            throws RemoteException {
        // TODO Auto-generated method stub
        return 0;
    }

    public IBinder asBinder() {
        // TODO Auto-generated method stub
        return null;
    }

    public String[] getStreamTypes(Uri arg0, String arg1) throws RemoteException {
        // TODO Auto-generated method stub
        return null;
    }

    public AssetFileDescriptor openTypedAssetFile(Uri arg0, String arg1, Bundle arg2)
            throws RemoteException, FileNotFoundException {
        // TODO Auto-generated method stub
        return null;
    }

}
Loading