Kaydet (Commit) ae14df5b authored tarafından Tomaž Vajngerl's avatar Tomaž Vajngerl Kaydeden (comit) Jan Holesovsky

LOAndroid2: initial import of older Fennec version with LO changes

rebase on mozilla-central tag RELEASE_BASE_20120531
add LOEvent, LOThread, some LO icons

Change-Id: I0c3aba6d9715c60e32d8daa2002b4961eef476f0
üst 8339f8ab
.gradle
/local.properties
/.idea/workspace.xml
.DS_Store
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CompilerConfiguration">
<option name="DEFAULT_COMPILER" value="Javac" />
<resourceExtensions />
<wildcardResourcePatterns>
<entry name="!?*.java" />
<entry name="!?*.form" />
<entry name="!?*.class" />
<entry name="!?*.groovy" />
<entry name="!?*.scala" />
<entry name="!?*.flex" />
<entry name="!?*.kt" />
<entry name="!?*.clj" />
</wildcardResourcePatterns>
<annotationProcessing>
<profile default="true" name="Default" enabled="false">
<processorPath useClasspath="true" />
</profile>
</annotationProcessing>
</component>
</project>
<component name="CopyrightManager">
<settings default="" />
</component>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Encoding" useUTFGuessing="true" native2AsciiForPropertiesFiles="false" />
</project>
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="GradleSettings">
<option name="linkedExternalProjectsSettings">
<GradleProjectSettings>
<option name="distributionType" value="DEFAULT_WRAPPED" />
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="modules">
<set>
<option value="$PROJECT_DIR$" />
<option value="$PROJECT_DIR$/app" />
</set>
</option>
</GradleProjectSettings>
</option>
</component>
</project>
<component name="libraryTable">
<library name="appcompat-v7-19.1.0">
<CLASSES>
<root url="jar://$PROJECT_DIR$/build/intermediates/exploded-aar/com.android.support/appcompat-v7/19.1.0/classes.jar!/" />
<root url="file://$PROJECT_DIR$/build/intermediates/exploded-aar/com.android.support/appcompat-v7/19.1.0/res" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>
\ No newline at end of file
<component name="libraryTable">
<library name="support-v4-19.1.0">
<CLASSES>
<root url="jar://$USER_HOME$/Programs/android-sdk-linux/extras/android/m2repository/com/android/support/support-v4/19.1.0/support-v4-19.1.0.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES>
<root url="jar://$USER_HOME$/Programs/android-sdk-linux/extras/android/m2repository/com/android/support/support-v4/19.1.0/support-v4-19.1.0-sources.jar!/" />
</SOURCES>
</library>
</component>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="EntryPointsManager">
<entry_points version="2.0" />
</component>
<component name="ProjectInspectionProfilesVisibleTreeState">
<entry key="Project Default">
<profile-state>
<expanded-state>
<State>
<id />
</State>
</expanded-state>
<selected-state>
<State>
<id>Abstraction issues</id>
</State>
</selected-state>
</profile-state>
</entry>
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_6" assert-keyword="true" jdk-15="true" project-jdk-name="1.7" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/build/classes" />
</component>
<component name="masterDetails">
<states>
<state key="ScopeChooserConfigurable.UI">
<settings>
<splitter-proportions>
<option name="proportions">
<list>
<option value="0.2" />
</list>
</option>
</splitter-proportions>
</settings>
</state>
</states>
</component>
</project>
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/LOAndroid.iml" filepath="$PROJECT_DIR$/LOAndroid.iml" />
<module fileurl="file://$PROJECT_DIR$/app/app.iml" filepath="$PROJECT_DIR$/app/app.iml" />
</modules>
</component>
</project>
<component name="DependencyValidationManager">
<state>
<option name="SKIP_IMPORT_STATEMENTS" value="false" />
</state>
</component>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="" vcs="" />
</component>
</project>
<?xml version="1.0" encoding="UTF-8"?>
<module external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$" external.system.id="GRADLE" external.system.module.group="" external.system.module.version="unspecified" type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<excludeFolder url="file://$MODULE_DIR$/.gradle" />
</content>
<orderEntry type="jdk" jdkName="1.7" jdkType="JavaSDK" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>
<?xml version="1.0" encoding="UTF-8"?>
<module external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$/.." external.system.id="GRADLE" external.system.module.group="LOAndroid" external.system.module.version="unspecified" type="JAVA_MODULE" version="4">
<component name="FacetManager">
<facet type="android-gradle" name="Android-Gradle">
<configuration>
<option name="GRADLE_PROJECT_PATH" value=":app" />
</configuration>
</facet>
<facet type="android" name="Android">
<configuration>
<option name="SELECTED_BUILD_VARIANT" value="debug" />
<option name="ASSEMBLE_TASK_NAME" value="assembleDebug" />
<option name="COMPILE_JAVA_TASK_NAME" value="compileDebugJava" />
<option name="ASSEMBLE_TEST_TASK_NAME" value="assembleDebugTest" />
<option name="SOURCE_GEN_TASK_NAME" value="generateDebugSources" />
<option name="ALLOW_USER_CONFIGURATION" value="false" />
<option name="MANIFEST_FILE_RELATIVE_PATH" value="/src/main/AndroidManifest.xml" />
<option name="RES_FOLDER_RELATIVE_PATH" value="/src/main/res" />
<option name="RES_FOLDERS_RELATIVE_PATH" value="file://$MODULE_DIR$/src/main/res" />
<option name="ASSETS_FOLDER_RELATIVE_PATH" value="/src/main/assets" />
</configuration>
</facet>
</component>
<component name="NewModuleRootManager" inherit-compiler-output="false">
<output url="file://$MODULE_DIR$/build/intermediates/classes/debug" />
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/r/debug" isTestSource="false" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/aidl/debug" isTestSource="false" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/buildConfig/debug" isTestSource="false" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/rs/debug" isTestSource="false" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/rs/debug" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/r/test/debug" isTestSource="true" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/aidl/test/debug" isTestSource="true" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/buildConfig/test/debug" isTestSource="true" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/rs/test/debug" isTestSource="true" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/rs/test/debug" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/res" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/resources" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/aidl" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/assets" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/java" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/jni" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/rs" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/main/res" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/main/aidl" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/main/assets" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/main/jni" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/main/rs" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/res" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/resources" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/aidl" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/assets" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/java" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/jni" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/rs" isTestSource="true" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates" />
<excludeFolder url="file://$MODULE_DIR$/build/outputs" />
</content>
<orderEntry type="jdk" jdkName="Android API 19 Platform" jdkType="Android SDK" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" exported="" name="appcompat-v7-19.1.0" level="project" />
<orderEntry type="library" exported="" name="support-v4-19.1.0" level="project" />
</component>
</module>
apply plugin: 'android'
android {
compileSdkVersion 19
buildToolsVersion "19.1.0"
defaultConfig {
minSdkVersion 15
targetSdkVersion 19
versionCode 1
versionName "1.0"
}
buildTypes {
release {
runProguard false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:19.+'
}
# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in /home/quikee/Programs/android-sdk-linux/tools/proguard/proguard-android.txt
# You can edit the include path and order by changing the ProGuard
# include property in project.properties.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# Add any project specific keep options here:
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.libreoffice" >
<!-- App requires OpenGL ES 2.0 -->
<uses-feature android:glEsVersion="0x00020000" android:required="true" />
<application
android:allowBackup="true"
android:icon="@drawable/main"
android:label="@string/app_name"
android:hardwareAccelerated="true"
android:theme="@style/AppTheme" >
<activity
android:name="org.libreoffice.LibreOfficeMainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
package org.libreoffice;
import android.graphics.Rect;
import android.util.Log;
import org.mozilla.gecko.gfx.IntSize;
import org.mozilla.gecko.gfx.ViewportMetrics;
public class LOEvent {
public static final int SIZE_CHANGED = 1;
public static final int TILE_SIZE = 2;
public static final int VIEWPORT = 3;
public static final int DRAW = 4;
private ViewportMetrics mViewportMetrics;
public int mType;
private String mTypeString;
ViewportMetrics viewportMetrics;
public LOEvent(int type, int width, int height, int widthPixels, int heightPixels) {
mType = type;
mTypeString = "Size Changed";
}
public LOEvent(int type, IntSize tileSize) {
mType = type;
mTypeString = "Tile size";
}
public LOEvent(int type, ViewportMetrics viewportMetrics) {
mType = type;
mTypeString = "Viewport";
mViewportMetrics = viewportMetrics;
}
public LOEvent(int type, Rect rect) {
mType = type;
mTypeString = "Draw";
}
public static LOEvent draw(Rect rect) {
return new LOEvent(DRAW, rect);
}
public static LOEvent sizeChanged(int width, int height, int widthPixels, int heightPixels) {
return new LOEvent(SIZE_CHANGED, width, height, widthPixels, heightPixels);
}
public static LOEvent tileSize(IntSize tileSize) {
return new LOEvent(TILE_SIZE, tileSize);
}
public static LOEvent viewport(ViewportMetrics viewportMetrics) {
return new LOEvent(VIEWPORT, viewportMetrics);
}
public String getTypeString() {
return mTypeString;
}
public ViewportMetrics getViewport() {
return mViewportMetrics;
}
}
package org.libreoffice;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import org.mozilla.gecko.gfx.GeckoSoftwareLayerClient;
import org.mozilla.gecko.gfx.IntSize;
import org.mozilla.gecko.gfx.LayerController;
import org.mozilla.gecko.gfx.LayerView;
import java.nio.ByteBuffer;
public class LOKitShell {
private static final String LOGTAG = LOKitShell.class.getSimpleName();
public static int getDpi() {
return 96;
}
public static int getScreenDepth() {
return 24;
}
public static float computeRenderIntegrity() {
return 0.0f;
}
public static ByteBuffer allocateDirectBuffer(int size) {
if (size <= 0) {
throw new IllegalArgumentException("Invalid size " + size);
}
ByteBuffer directBuffer = ByteBuffer.allocateDirect(size);
//ByteBuffer directBuffer = nativeAllocateDirectBuffer(size);
if (directBuffer == null) {
throw new OutOfMemoryError("allocateDirectBuffer() returned null");
} else if (!directBuffer.isDirect()) {
throw new AssertionError("allocateDirectBuffer() did not return a direct buffer");
}
return directBuffer;
}
public static void freeDirectBuffer(ByteBuffer buffer) {
if (buffer == null) {
return;
}
if (!buffer.isDirect()) {
throw new IllegalArgumentException("buffer must be direct");
}
//nativeFreeDirectBuffer(buffer);
return ;
}
public static void bindWidgetTexture() {
}
public static void sendEvent(LOEvent event) {
Log.i(LOGTAG, "Event: " + event.getTypeString());
}
public static void runGecko(String apkPath, String args, String url, boolean restoreSession) {
// run gecko -- it will spawn its own thread
// GeckoAppShell.nativeInit();
Log.i(LOGTAG, "post native init");
// Tell Gecko where the target byte buffer is for rendering
//GeckoAppShell.setSoftwareLayerClient(GeckoApp.mAppContext.getSoftwareLayerClient());
Log.i(LOGTAG, "setSoftwareLayerClient called");
// First argument is the .apk path
String combinedArgs = apkPath + " -greomni " + apkPath;
if (args != null)
combinedArgs += " " + args;
if (url != null)
combinedArgs += " -remote " + url;
if (restoreSession)
combinedArgs += " -restoresession";
DisplayMetrics metrics = new DisplayMetrics();
LibreOfficeMainActivity.mAppContext.getWindowManager().getDefaultDisplay().getMetrics(metrics);
combinedArgs += " -width " + metrics.widthPixels + " -height " + metrics.heightPixels;
LibreOfficeMainActivity.mAppContext.runOnUiThread(new Runnable() {
public void run() {
geckoLoaded();
}
});
//LOKitShell.nativeRun(combinedArgs);
}
// Called on the UI thread after Gecko loads.
private static void geckoLoaded() {
/*final LayerController layerController = LibreOfficeMainActivity.mAppContext.getLayerController();
LayerView v = layerController.getView();
mInputConnection = GeckoInputConnection.create(v);
v.setInputConnectionHandler(mInputConnection);
layerController.setOnTouchListener(new View.OnTouchListener() {
public boolean onTouch(View view, MotionEvent event) {
if (event == null)
return true;
GeckoAppShell.sendEventToGecko(new GeckoEvent(event));
return true;
}
});
layerController.notifyLayerClientOfGeometryChange();*/
}
}
package org.libreoffice;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.JsonWriter;
import org.mozilla.gecko.gfx.ViewportMetrics;
import java.io.IOException;
import java.io.StringWriter;
import java.nio.ByteBuffer;
import java.nio.ShortBuffer;
import java.util.Arrays;
import java.util.Random;
import java.util.concurrent.ConcurrentLinkedQueue;
public class LOKitThread extends Thread {
private static final String LOGTAG = "GeckoThread";
public ConcurrentLinkedQueue<LOEvent> gEvents = new ConcurrentLinkedQueue<LOEvent>();
private ViewportMetrics mViewportMetrics;
private Random rand = new Random();
LOKitThread() {
}
private void draw() throws InterruptedException {
final LibreOfficeMainActivity application = LibreOfficeMainActivity.mAppContext;
Bitmap bitmap = application.getSoftwareLayerClient().getLayerController().getDrawable16("dummy_page");
bitmap = convert(bitmap, Bitmap.Config.RGB_565);
application.getSoftwareLayerClient().beginDrawing(bitmap.getWidth(), bitmap.getHeight());
//application.getSoftwareLayerClient().beginDrawing(500,500);
ByteBuffer buffer = application.getSoftwareLayerClient().getBuffer();
bitmap.copyPixelsToBuffer(buffer.asIntBuffer());
/*short mainColor16 = convertTo16Bit(rand.nextInt());
short[] mainPattern = new short[500];
Arrays.fill(mainPattern, mainColor16);
buffer.rewind();
ShortBuffer shortBuffer = buffer.asShortBuffer();
for (int i = 0; i < 500; i++) {
shortBuffer.put(mainPattern);
}*/
StringWriter stringWriter = new StringWriter();
try {
JsonWriter writer = new JsonWriter(stringWriter);
writer.beginObject();
if (mViewportMetrics == null) {
writer.name("x").value(0);
writer.name("y").value(0);
writer.name("width").value(bitmap.getWidth());
writer.name("height").value(bitmap.getHeight());
writer.name("pageWidth").value(1000);
writer.name("pageHeight").value(5000);
writer.name("offsetX").value(0);
writer.name("offsetY").value(0);
writer.name("zoom").value(1.0);
writer.name("allowZoom").value(true);
} else {
writer.name("x").value(mViewportMetrics.getOrigin().x);
writer.name("y").value(mViewportMetrics.getOrigin().y);
writer.name("width").value(mViewportMetrics.getSize().width);
writer.name("height").value(mViewportMetrics.getSize().height);
writer.name("pageWidth").value(mViewportMetrics.getPageSize().width);
writer.name("pageHeight").value(mViewportMetrics.getPageSize().height);
writer.name("offsetX").value(mViewportMetrics.getViewportOffset().x);
writer.name("offsetY").value(mViewportMetrics.getViewportOffset().y);
writer.name("zoom").value(mViewportMetrics.getZoomFactor());
writer.name("allowZoom").value(mViewportMetrics.getAllowZoom());
}
writer.name("backgroundColor").value("rgb(255,255,255)");
writer.endObject();
writer.close();
} catch (IOException ex) {
}
application.getSoftwareLayerClient().endDrawing(0, 0, bitmap.getWidth(), bitmap.getHeight(), stringWriter.toString(), false);
//application.getSoftwareLayerClient().endDrawing(0, 0, 500, 500, stringWriter.toString(), false);
application.runOnUiThread(new Runnable() {
@Override
public void run() {
application.getSoftwareLayerClient().handleMessage("Viewport:UpdateLater", null);
}
});
}
private short convertTo16Bit(int color) {
int r = Color.red(color) >> 3, g = Color.green(color) >> 2, b = Color.blue(color) >> 3;
int c = ((r << 11) | (g << 5) | b);
// Swap endianness.
return (short) ((c >> 8) | ((c & 0xff) << 8));
}
private Bitmap convert(Bitmap bitmap, Bitmap.Config config) {
Bitmap convertedBitmap = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), config);
Canvas canvas = new Canvas(convertedBitmap);
Paint paint = new Paint();
paint.setColor(Color.BLACK);
canvas.drawBitmap(bitmap, 0, 0, paint);
return convertedBitmap;
}
public void run() {
try {
boolean drawn = false;
while (true) {
if (!gEvents.isEmpty()) {
processEvent(gEvents.poll());
} else {
if(!drawn) {
draw();
drawn = true;
}
Thread.sleep(100L);
}
}
} catch (InterruptedException ex) {
}
}
private void processEvent(LOEvent event) throws InterruptedException {
switch (event.mType) {
case LOEvent.VIEWPORT:
mViewportMetrics = event.getViewport();
break;
case LOEvent.DRAW:
draw();
break;
case LOEvent.SIZE_CHANGED:
break;
}
}
}
package org.libreoffice;
import android.app.Activity;
import android.os.Bundle;
import android.os.SystemClock;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import org.mozilla.gecko.gfx.GeckoSoftwareLayerClient;
import org.mozilla.gecko.gfx.LayerController;
import org.mozilla.gecko.gfx.LayerView;
public class LibreOfficeMainActivity extends Activity {
private static final String LOGTAG = "LibreOfficeMainActivity";
private LinearLayout mMainLayout;
private RelativeLayout mGeckoLayout;
private static LayerController mLayerController;
private static GeckoSoftwareLayerClient mSoftwareLayerClient;
private static LOKitThread sLOKitThread;
public static LibreOfficeMainActivity mAppContext;
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
public DisplayMetrics getDisplayMetrics() {
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
return metrics;
}
/**
* Called when the activity is first created.
*/
@Override
public void onCreate(Bundle savedInstanceState) {
mAppContext = this;
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.w(LOGTAG, "zerdatime " + SystemClock.uptimeMillis() + " - onCreate");
setContentView(R.layout.activity_main);
// setup gecko layout
mGeckoLayout = (RelativeLayout) findViewById(R.id.gecko_layout);
mMainLayout = (LinearLayout) findViewById(R.id.main_layout);
if (mLayerController == null) {
mLayerController = new LayerController(this);
mSoftwareLayerClient = new GeckoSoftwareLayerClient(this);
mLayerController.setLayerClient(mSoftwareLayerClient);
mGeckoLayout.addView(mLayerController.getView(), 0);
}
mLayerController.notifyLayerClientOfGeometryChange();
sLOKitThread = new LOKitThread();
sLOKitThread.start();
Log.w(LOGTAG, "zerdatime " + SystemClock.uptimeMillis() + " - UI almost up");
}
public static GeckoSoftwareLayerClient getSoftwareLayerClient() {
return mSoftwareLayerClient;
}
}
\ No newline at end of file
/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (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.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Android code.
*
* The Initial Developer of the Original Code is Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2009-2010
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Sriram Ramasubramanian <sriram@mozilla.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
package org.mozilla.gecko;
import org.json.JSONObject;
public interface GeckoEventListener {
public void handleMessage(String event, JSONObject message);
}
/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (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.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Android code.
*
* The Initial Developer of the Original Code is Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2009-2010
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Patrick Walton <pcwalton@mozilla.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
package org.mozilla.gecko.gfx;
import android.graphics.Bitmap;
import org.libreoffice.LOKitShell;
import java.nio.ByteBuffer;
//import org.mozilla.gecko.GeckoAppShell;
/**
* A Cairo image that simply saves a buffer of pixel data.
*/
public class BufferedCairoImage extends CairoImage {
private ByteBuffer mBuffer;
private IntSize mSize;
private int mFormat;
private boolean mNeedToFreeBuffer = false;
/**
* Creates a buffered Cairo image from a byte buffer.
*/
public BufferedCairoImage(ByteBuffer inBuffer, int inWidth, int inHeight, int inFormat) {
mBuffer = inBuffer;
mSize = new IntSize(inWidth, inHeight);
mFormat = inFormat;
}
/**
* Creates a buffered Cairo image from an Android bitmap.
*/
public BufferedCairoImage(Bitmap bitmap) {
mFormat = CairoUtils.bitmapConfigToCairoFormat(bitmap.getConfig());
mSize = new IntSize(bitmap.getWidth(), bitmap.getHeight());
mNeedToFreeBuffer = true;
// XXX Why is this * 4? Shouldn't it depend on mFormat?
mBuffer = /*GeckoAppShell*/LOKitShell.allocateDirectBuffer(mSize.getArea() * 4);
bitmap.copyPixelsToBuffer(mBuffer.asIntBuffer());
}
protected void finalize() throws Throwable {
try {
if (mNeedToFreeBuffer && mBuffer != null)
/*GeckoAppShell*/ LOKitShell.freeDirectBuffer(mBuffer);
mNeedToFreeBuffer = false;
mBuffer = null;
} finally {
super.finalize();
}
}
@Override
public ByteBuffer getBuffer() {
return mBuffer;
}
@Override
public IntSize getSize() {
return mSize;
}
@Override
public int getFormat() {
return mFormat;
}
}
/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (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.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Android code.
*
* The Initial Developer of the Original Code is Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2009-2010
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Patrick Walton <pcwalton@mozilla.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
package org.mozilla.gecko.gfx;
import javax.microedition.khronos.opengles.GL10;
/** Information needed to render Cairo bitmaps using OpenGL ES. */
public class CairoGLInfo {
public final int internalFormat;
public final int format;
public final int type;
public CairoGLInfo(int cairoFormat) {
switch (cairoFormat) {
case CairoImage.FORMAT_ARGB32:
internalFormat = format = GL10.GL_RGBA; type = GL10.GL_UNSIGNED_BYTE;
break;
case CairoImage.FORMAT_RGB24:
internalFormat = format = GL10.GL_RGB; type = GL10.GL_UNSIGNED_BYTE;
break;
case CairoImage.FORMAT_RGB16_565:
internalFormat = format = GL10.GL_RGB; type = GL10.GL_UNSIGNED_SHORT_5_6_5;
break;
case CairoImage.FORMAT_A8:
case CairoImage.FORMAT_A1:
throw new RuntimeException("Cairo FORMAT_A1 and FORMAT_A8 unsupported");
default:
throw new RuntimeException("Unknown Cairo format");
}
}
}
/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (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.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Android code.
*
* The Initial Developer of the Original Code is Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2009-2010
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Patrick Walton <pcwalton@mozilla.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
package org.mozilla.gecko.gfx;
import java.nio.ByteBuffer;
/*
* A bitmap with pixel data in one of the formats that Cairo understands.
*/
public abstract class CairoImage {
public abstract ByteBuffer getBuffer();
public abstract IntSize getSize();
public abstract int getFormat();
public static final int FORMAT_INVALID = -1;
public static final int FORMAT_ARGB32 = 0;
public static final int FORMAT_RGB24 = 1;
public static final int FORMAT_A8 = 2;
public static final int FORMAT_A1 = 3;
public static final int FORMAT_RGB16_565 = 4;
}
/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (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.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Android code.
*
* The Initial Developer of the Original Code is Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2009-2010
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Patrick Walton <pcwalton@mozilla.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
package org.mozilla.gecko.gfx;
import org.mozilla.gecko.gfx.CairoImage;
import android.graphics.Bitmap;
import javax.microedition.khronos.opengles.GL10;
/**
* Utility methods useful when displaying Cairo bitmaps using OpenGL ES.
*/
public class CairoUtils {
private CairoUtils() { /* Don't call me. */ }
public static int bitsPerPixelForCairoFormat(int cairoFormat) {
switch (cairoFormat) {
case CairoImage.FORMAT_A1: return 1;
case CairoImage.FORMAT_A8: return 8;
case CairoImage.FORMAT_RGB16_565: return 16;
case CairoImage.FORMAT_RGB24: return 24;
case CairoImage.FORMAT_ARGB32: return 32;
default:
throw new RuntimeException("Unknown Cairo format");
}
}
public static int bitmapConfigToCairoFormat(Bitmap.Config config) {
if (config == null)
return CairoImage.FORMAT_ARGB32; /* Droid Pro fix. */
switch (config) {
case ALPHA_8: return CairoImage.FORMAT_A8;
case ARGB_4444: throw new RuntimeException("ARGB_444 unsupported");
case ARGB_8888: return CairoImage.FORMAT_ARGB32;
case RGB_565: return CairoImage.FORMAT_RGB16_565;
default: throw new RuntimeException("Unknown Skia bitmap config");
}
}
public static Bitmap.Config cairoFormatTobitmapConfig(int format) {
switch (format) {
case CairoImage.FORMAT_A8: return Bitmap.Config.ALPHA_8;
case CairoImage.FORMAT_ARGB32: return Bitmap.Config.ARGB_8888;
case CairoImage.FORMAT_RGB16_565: return Bitmap.Config.RGB_565;
default:
throw new RuntimeException("Unknown CairoImage format");
}
}
}
/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (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.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Android code.
*
* The Initial Developer of the Original Code is Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2012
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Patrick Walton <pcwalton@mozilla.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
package org.mozilla.gecko.gfx;
import org.libreoffice.LOKitShell;
//import org.mozilla.gecko.GeckoAppShell;
import android.graphics.Color;
import java.nio.ByteBuffer;
import java.nio.ShortBuffer;
import java.util.Arrays;
/** A Cairo image that displays a tinted checkerboard. */
public class CheckerboardImage extends CairoImage {
// The width and height of the checkerboard tile.
private static final int SIZE = 16;
// The pixel format of the checkerboard tile.
private static final int FORMAT = CairoImage.FORMAT_RGB16_565;
// The color to mix in to tint the background color.
private static final int TINT_COLOR = Color.GRAY;
// The amount to mix in.
private static final float TINT_OPACITY = 0.4f;
private ByteBuffer mBuffer;
private int mMainColor;
private boolean mShowChecks;
/** Creates a new checkerboard image. */
public CheckerboardImage() {
int bpp = CairoUtils.bitsPerPixelForCairoFormat(FORMAT);
mBuffer = /*GeckoAppShell*/LOKitShell.allocateDirectBuffer(SIZE * SIZE * bpp / 8);
update(true, Color.WHITE);
}
/** Returns the current color of the checkerboard. */
public int getColor() {
return mMainColor;
}
/** Returns whether or not we are currently showing checks on the checkerboard. */
public boolean getShowChecks() {
return mShowChecks;
}
/** Updates the checkerboard image. If showChecks is true, then create a
checkerboard image that is tinted to the color. Otherwise just return a flat
image of the color. */
public void update(boolean showChecks, int color) {
mMainColor = color;
mShowChecks = showChecks;
short mainColor16 = convertTo16Bit(mMainColor);
mBuffer.rewind();
ShortBuffer shortBuffer = mBuffer.asShortBuffer();
if (!mShowChecks) {
short color16 = convertTo16Bit(mMainColor);
short[] fillBuffer = new short[SIZE];
Arrays.fill(fillBuffer, color16);
for (int i = 0; i < SIZE; i++) {
shortBuffer.put(fillBuffer);
}
return;
}
short tintColor16 = convertTo16Bit(tint(mMainColor));
short[] mainPattern = new short[SIZE / 2], tintPattern = new short[SIZE / 2];
Arrays.fill(mainPattern, mainColor16);
Arrays.fill(tintPattern, tintColor16);
// The checkerboard pattern looks like this:
//
// +---+---+
// | N | T | N = normal
// +---+---+ T = tinted
// | T | N |
// +---+---+
for (int i = 0; i < SIZE / 2; i++) {
shortBuffer.put(mainPattern);
shortBuffer.put(tintPattern);
}
for (int i = SIZE / 2; i < SIZE; i++) {
shortBuffer.put(tintPattern);
shortBuffer.put(mainPattern);
}
}
// Tints the given color appropriately and returns the tinted color.
private int tint(int color) {
float negTintOpacity = 1.0f - TINT_OPACITY;
float r = Color.red(color) * negTintOpacity + Color.red(TINT_COLOR) * TINT_OPACITY;
float g = Color.green(color) * negTintOpacity + Color.green(TINT_COLOR) * TINT_OPACITY;
float b = Color.blue(color) * negTintOpacity + Color.blue(TINT_COLOR) * TINT_OPACITY;
return Color.rgb(Math.round(r), Math.round(g), Math.round(b));
}
// Converts a 32-bit ARGB color to 16-bit R5G6B5, truncating values and discarding the alpha
// channel.
private short convertTo16Bit(int color) {
int r = Color.red(color) >> 3, g = Color.green(color) >> 2, b = Color.blue(color) >> 3;
int c = ((r << 11) | (g << 5) | b);
// Swap endianness.
return (short)((c >> 8) | ((c & 0xff) << 8));
}
@Override
protected void finalize() throws Throwable {
try {
if (mBuffer != null) {
/*GeckoAppShell*/LOKitShell.freeDirectBuffer(mBuffer);
}
} finally {
super.finalize();
}
}
@Override
public ByteBuffer getBuffer() {
return mBuffer;
}
@Override
public IntSize getSize() {
return new IntSize(SIZE, SIZE);
}
@Override
public int getFormat() {
return FORMAT;
}
}
/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (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.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Android code.
*
* The Initial Developer of the Original Code is Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2009-2010
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Patrick Walton <pcwalton@mozilla.com>
* Chris Lord <chrislord.net@gmail.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
package org.mozilla.gecko.gfx;
import org.mozilla.gecko.util.FloatUtils;
import org.json.JSONException;
import org.json.JSONObject;
public class FloatSize {
public final float width, height;
public FloatSize(FloatSize size) { width = size.width; height = size.height; }
public FloatSize(IntSize size) { width = size.width; height = size.height; }
public FloatSize(float aWidth, float aHeight) { width = aWidth; height = aHeight; }
public FloatSize(JSONObject json) {
try {
width = (float)json.getDouble("width");
height = (float)json.getDouble("height");
} catch (JSONException e) {
throw new RuntimeException(e);
}
}
@Override
public String toString() {
return "(" + width + "," + height + ")";
}
public boolean isPositive() {
return (width > 0 && height > 0);
}
public boolean fuzzyEquals(FloatSize size) {
return (FloatUtils.fuzzyEquals(size.width, width) &&
FloatUtils.fuzzyEquals(size.height, height));
}
public FloatSize scale(float factor) {
return new FloatSize(width * factor, height * factor);
}
/*
* Returns the size that represents a linear transition between this size and `to` at time `t`,
* which is on the scale [0, 1).
*/
public FloatSize interpolate(FloatSize to, float t) {
return new FloatSize(FloatUtils.interpolate(width, to.width, t),
FloatUtils.interpolate(height, to.height, t));
}
}
package org.mozilla.gecko.gfx;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputConnection;
import android.view.KeyEvent;
public interface InputConnectionHandler
{
InputConnection onCreateInputConnection(EditorInfo outAttrs);
boolean onKeyPreIme(int keyCode, KeyEvent event);
boolean onKeyDown(int keyCode, KeyEvent event);
boolean onKeyLongPress(int keyCode, KeyEvent event);
boolean onKeyMultiple(int keyCode, int repeatCount, KeyEvent event);
boolean onKeyUp(int keyCode, KeyEvent event);
}
/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (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.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Android code.
*
* The Initial Developer of the Original Code is Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2009-2010
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Patrick Walton <pcwalton@mozilla.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
package org.mozilla.gecko.gfx;
import org.mozilla.gecko.gfx.FloatSize;
import org.json.JSONException;
import org.json.JSONObject;
import java.lang.Math;
public class IntSize {
public final int width, height;
public IntSize(IntSize size) { width = size.width; height = size.height; }
public IntSize(int inWidth, int inHeight) { width = inWidth; height = inHeight; }
public IntSize(FloatSize size) {
width = Math.round(size.width);
height = Math.round(size.height);
}
public IntSize(JSONObject json) {
try {
width = json.getInt("width");
height = json.getInt("height");
} catch (JSONException e) {
throw new RuntimeException(e);
}
}
public int getArea() {
return width * height;
}
public boolean equals(IntSize size) {
return ((size.width == width) && (size.height == height));
}
public boolean isPositive() {
return (width > 0 && height > 0);
}
@Override
public String toString() { return "(" + width + "," + height + ")"; }
public IntSize scale(float factor) {
return new IntSize(Math.round(width * factor),
Math.round(height * factor));
}
/* Returns the power of two that is greater than or equal to value */
public static int nextPowerOfTwo(int value) {
// code taken from http://acius2.blogspot.com/2007/11/calculating-next-power-of-2.html
if (0 == value--) {
return 1;
}
value = (value >> 1) | value;
value = (value >> 2) | value;
value = (value >> 4) | value;
value = (value >> 8) | value;
value = (value >> 16) | value;
return value + 1;
}
public IntSize nextPowerOfTwo() {
return new IntSize(nextPowerOfTwo(width), nextPowerOfTwo(height));
}
}
/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (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.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Android code.
*
* The Initial Developer of the Original Code is Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2009-2010
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Patrick Walton <pcwalton@mozilla.com>
* Chris Lord <chrislord.net@gmail.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
package org.mozilla.gecko.gfx;
import android.graphics.Point;
import android.graphics.PointF;
import android.graphics.RectF;
import android.graphics.Region;
import android.util.Log;
import java.util.concurrent.locks.ReentrantLock;
import javax.microedition.khronos.opengles.GL10;
import org.mozilla.gecko.util.FloatUtils;
public abstract class Layer {
private final ReentrantLock mTransactionLock;
private boolean mInTransaction;
private Point mNewOrigin;
private float mNewResolution;
private LayerView mView;
protected Point mOrigin;
protected float mResolution;
public Layer() {
mTransactionLock = new ReentrantLock();
mOrigin = new Point(0, 0);
mResolution = 1.0f;
}
/**
* Updates the layer. This returns false if there is still work to be done
* after this update.
*/
public final boolean update(GL10 gl, RenderContext context) {
if (mTransactionLock.isHeldByCurrentThread()) {
throw new RuntimeException("draw() called while transaction lock held by this " +
"thread?!");
}
if (mTransactionLock.tryLock()) {
try {
return performUpdates(gl, context);
} finally {
mTransactionLock.unlock();
}
}
return false;
}
/** Subclasses override this function to draw the layer. */
public abstract void draw(RenderContext context);
/** Subclasses override this function to provide access to the size of the layer. */
public abstract IntSize getSize();
/** Given the intrinsic size of the layer, returns the pixel boundaries of the layer rect. */
protected RectF getBounds(RenderContext context, FloatSize size) {
float scaleFactor = context.zoomFactor / mResolution;
float x = mOrigin.x * scaleFactor, y = mOrigin.y * scaleFactor;
float width = size.width * scaleFactor, height = size.height * scaleFactor;
return new RectF(x, y, x + width, y + height);
}
/**
* Returns the region of the layer that is considered valid. The default
* implementation of this will return the bounds of the layer, but this
* may be overridden.
*/
public Region getValidRegion(RenderContext context) {
return new Region(RectUtils.round(getBounds(context, new FloatSize(getSize()))));
}
/**
* Call this before modifying the layer. Note that, for TileLayers, "modifying the layer"
* includes altering the underlying CairoImage in any way. Thus you must call this function
* before modifying the byte buffer associated with this layer.
*
* This function may block, so you should never call this on the main UI thread.
*/
public void beginTransaction(LayerView aView) {
if (mTransactionLock.isHeldByCurrentThread())
throw new RuntimeException("Nested transactions are not supported");
mTransactionLock.lock();
mView = aView;
mInTransaction = true;
mNewResolution = mResolution;
}
public void beginTransaction() {
beginTransaction(null);
}
/** Call this when you're done modifying the layer. */
public void endTransaction() {
if (!mInTransaction)
throw new RuntimeException("endTransaction() called outside a transaction");
mInTransaction = false;
mTransactionLock.unlock();
if (mView != null)
mView.requestRender();
}
/** Returns true if the layer is currently in a transaction and false otherwise. */
protected boolean inTransaction() {
return mInTransaction;
}
/** Returns the current layer origin. */
public Point getOrigin() {
return mOrigin;
}
/** Sets the origin. Only valid inside a transaction. */
public void setOrigin(Point newOrigin) {
if (!mInTransaction)
throw new RuntimeException("setOrigin() is only valid inside a transaction");
mNewOrigin = newOrigin;
}
/** Returns the current layer's resolution. */
public float getResolution() {
return mResolution;
}
/**
* Sets the layer resolution. This value is used to determine how many pixels per
* device pixel this layer was rendered at. This will be reflected by scaling by
* the reciprocal of the resolution in the layer's transform() function.
* Only valid inside a transaction. */
public void setResolution(float newResolution) {
if (!mInTransaction)
throw new RuntimeException("setResolution() is only valid inside a transaction");
mNewResolution = newResolution;
}
/**
* Subclasses may override this method to perform custom layer updates. This will be called
* with the transaction lock held. Subclass implementations of this method must call the
* superclass implementation. Returns false if there is still work to be done after this
* update is complete.
*/
protected boolean performUpdates(GL10 gl, RenderContext context) {
if (mNewOrigin != null) {
mOrigin = mNewOrigin;
mNewOrigin = null;
}
if (mNewResolution != 0.0f) {
mResolution = mNewResolution;
mNewResolution = 0.0f;
}
return true;
}
public static class RenderContext {
public final RectF viewport;
public final FloatSize pageSize;
public final float zoomFactor;
public RenderContext(RectF aViewport, FloatSize aPageSize, float aZoomFactor) {
viewport = aViewport;
pageSize = aPageSize;
zoomFactor = aZoomFactor;
}
public boolean fuzzyEquals(RenderContext other) {
if (other == null) {
return false;
}
return RectUtils.fuzzyEquals(viewport, other.viewport)
&& pageSize.fuzzyEquals(other.pageSize)
&& FloatUtils.fuzzyEquals(zoomFactor, other.zoomFactor);
}
}
}
/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (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.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Android code.
*
* The Initial Developer of the Original Code is Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2009-2010
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Patrick Walton <pcwalton@mozilla.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
package org.mozilla.gecko.gfx;
/**
* A layer client provides tiles and manages other information used by the layer controller.
*/
public abstract class LayerClient {
private LayerController mLayerController;
public abstract void geometryChanged();
public abstract void viewportSizeChanged();
protected abstract void render();
public LayerController getLayerController() {
return mLayerController;
}
public void setLayerController(LayerController layerController) {
mLayerController = layerController;
}
/**
* A utility function for calling Layer.beginTransaction with the
* appropriate LayerView.
*/
public void beginTransaction(Layer aLayer) {
if (mLayerController != null) {
LayerView view = mLayerController.getView();
if (view != null) {
aLayer.beginTransaction(view);
return;
}
}
aLayer.beginTransaction();
}
// Included for symmetry.
public void endTransaction(Layer aLayer) {
aLayer.endTransaction();
}
}
/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (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.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Android code.
*
* The Initial Developer of the Original Code is Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2009-2010
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Patrick Walton <pcwalton@mozilla.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
package org.mozilla.gecko.gfx;
import org.mozilla.gecko.gfx.FloatSize;
import org.mozilla.gecko.gfx.InputConnectionHandler;
import org.mozilla.gecko.gfx.LayerController;
import org.mozilla.gecko.ui.SimpleScaleGestureDetector;
import android.content.Context;
import android.opengl.GLSurfaceView;
import android.view.GestureDetector;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputConnection;
import android.util.Log;
import java.util.LinkedList;
/**
* A view rendered by the layer compositor.
*
* This view delegates to LayerRenderer to actually do the drawing. Its role is largely that of a
* mediator between the LayerRenderer and the LayerController.
*/
public class LayerView extends GLSurfaceView {
private Context mContext;
private LayerController mController;
private InputConnectionHandler mInputConnectionHandler;
private LayerRenderer mRenderer;
private GestureDetector mGestureDetector;
private SimpleScaleGestureDetector mScaleGestureDetector;
private long mRenderTime;
private boolean mRenderTimeReset;
private static String LOGTAG = "GeckoLayerView";
/* List of events to be processed if the page does not prevent them. Should only be touched on the main thread */
private LinkedList<MotionEvent> mEventQueue = new LinkedList<MotionEvent>();
public LayerView(Context context, LayerController controller) {
super(context);
mContext = context;
mController = controller;
mRenderer = new LayerRenderer(this);
setRenderer(mRenderer);
setRenderMode(RENDERMODE_WHEN_DIRTY);
mGestureDetector = new GestureDetector(context, controller.getGestureListener());
mScaleGestureDetector =
new SimpleScaleGestureDetector(controller.getScaleGestureListener());
mGestureDetector.setOnDoubleTapListener(controller.getDoubleTapListener());
mInputConnectionHandler = null;
setFocusable(true);
setFocusableInTouchMode(true);
}
private void addToEventQueue(MotionEvent event) {
MotionEvent copy = MotionEvent.obtain(event);
mEventQueue.add(copy);
}
public void processEventQueue() {
MotionEvent event = mEventQueue.poll();
while(event != null) {
processEvent(event);
event = mEventQueue.poll();
}
}
public void clearEventQueue() {
mEventQueue.clear();
}
@Override
public boolean onTouchEvent(MotionEvent event) {
if (mController.onTouchEvent(event)) {
addToEventQueue(event);
return true;
}
return processEvent(event);
}
private boolean processEvent(MotionEvent event) {
if (mGestureDetector.onTouchEvent(event))
return true;
mScaleGestureDetector.onTouchEvent(event);
if (mScaleGestureDetector.isInProgress())
return true;
mController.getPanZoomController().onTouchEvent(event);
return true;
}
public LayerController getController() { return mController; }
/** The LayerRenderer calls this to indicate that the window has changed size. */
public void setViewportSize(IntSize size) {
mController.setViewportSize(new FloatSize(size));
}
public void setInputConnectionHandler(InputConnectionHandler handler) {
mInputConnectionHandler = handler;
}
@Override
public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
if (mInputConnectionHandler != null)
return mInputConnectionHandler.onCreateInputConnection(outAttrs);
return null;
}
@Override
public boolean onKeyPreIme(int keyCode, KeyEvent event) {
if (mInputConnectionHandler != null)
return mInputConnectionHandler.onKeyPreIme(keyCode, event);
return false;
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (mInputConnectionHandler != null)
return mInputConnectionHandler.onKeyDown(keyCode, event);
return false;
}
@Override
public boolean onKeyLongPress(int keyCode, KeyEvent event) {
if (mInputConnectionHandler != null)
return mInputConnectionHandler.onKeyLongPress(keyCode, event);
return false;
}
@Override
public boolean onKeyMultiple(int keyCode, int repeatCount, KeyEvent event) {
if (mInputConnectionHandler != null)
return mInputConnectionHandler.onKeyMultiple(keyCode, repeatCount, event);
return false;
}
@Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
if (mInputConnectionHandler != null)
return mInputConnectionHandler.onKeyUp(keyCode, event);
return false;
}
@Override
public void requestRender() {
super.requestRender();
synchronized(this) {
if (!mRenderTimeReset) {
mRenderTimeReset = true;
mRenderTime = System.nanoTime();
}
}
}
public void addLayer(Layer layer) {
mRenderer.addLayer(layer);
}
public void removeLayer(Layer layer) {
mRenderer.removeLayer(layer);
}
/**
* Returns the time elapsed between the first call of requestRender() after
* the last call of getRenderTime(), in nanoseconds.
*/
public long getRenderTime() {
synchronized(this) {
mRenderTimeReset = false;
return System.nanoTime() - mRenderTime;
}
}
public int getMaxTextureSize() {
return mRenderer.getMaxTextureSize();
}
}
/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (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.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Android code.
*
* The Initial Developer of the Original Code is Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2009-2010
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Patrick Walton <pcwalton@mozilla.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
package org.mozilla.gecko.gfx;
import org.mozilla.gecko.gfx.FloatSize;
import android.graphics.PointF;
import android.graphics.RectF;
import android.opengl.GLES11;
import android.opengl.GLES11Ext;
import android.util.Log;
import javax.microedition.khronos.opengles.GL10;
import java.nio.FloatBuffer;
/**
* Encapsulates the logic needed to draw a nine-patch bitmap using OpenGL ES.
*
* For more information on nine-patch bitmaps, see the following document:
* http://developer.android.com/guide/topics/graphics/2d-graphics.html#nine-patch
*/
public class NinePatchTileLayer extends TileLayer {
private static final int PATCH_SIZE = 16;
private static final int TEXTURE_SIZE = 48;
public NinePatchTileLayer(CairoImage image) {
super(false, image);
}
@Override
public void draw(RenderContext context) {
if (!initialized())
return;
GLES11.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA);
GLES11.glEnable(GL10.GL_BLEND);
try {
GLES11.glBindTexture(GL10.GL_TEXTURE_2D, getTextureID());
drawPatches(context);
} finally {
GLES11.glDisable(GL10.GL_BLEND);
}
}
private void drawPatches(RenderContext context) {
/*
* We divide the nine-patch bitmap up as follows:
*
* +---+---+---+
* | 0 | 1 | 2 |
* +---+---+---+
* | 3 | | 4 |
* +---+---+---+
* | 5 | 6 | 7 |
* +---+---+---+
*/
FloatSize size = context.pageSize;
float width = size.width, height = size.height;
drawPatch(context, 0, 0, /* 0 */
0.0f, 0.0f, PATCH_SIZE, PATCH_SIZE);
drawPatch(context, PATCH_SIZE, 0, /* 1 */
PATCH_SIZE, 0.0f, width, PATCH_SIZE);
drawPatch(context, PATCH_SIZE * 2, 0, /* 2 */
PATCH_SIZE + width, 0.0f, PATCH_SIZE, PATCH_SIZE);
drawPatch(context, 0, PATCH_SIZE, /* 3 */
0.0f, PATCH_SIZE, PATCH_SIZE, height);
drawPatch(context, PATCH_SIZE * 2, PATCH_SIZE, /* 4 */
PATCH_SIZE + width, PATCH_SIZE, PATCH_SIZE, height);
drawPatch(context, 0, PATCH_SIZE * 2, /* 5 */
0.0f, PATCH_SIZE + height, PATCH_SIZE, PATCH_SIZE);
drawPatch(context, PATCH_SIZE, PATCH_SIZE * 2, /* 6 */
PATCH_SIZE, PATCH_SIZE + height, width, PATCH_SIZE);
drawPatch(context, PATCH_SIZE * 2, PATCH_SIZE * 2, /* 7 */
PATCH_SIZE + width, PATCH_SIZE + height, PATCH_SIZE, PATCH_SIZE);
}
private void drawPatch(RenderContext context, int textureX, int textureY, float tileX,
float tileY, float tileWidth, float tileHeight) {
int[] cropRect = { textureX, textureY + PATCH_SIZE, PATCH_SIZE, -PATCH_SIZE };
GLES11.glTexParameteriv(GL10.GL_TEXTURE_2D, GLES11Ext.GL_TEXTURE_CROP_RECT_OES, cropRect,
0);
RectF viewport = context.viewport;
float viewportHeight = viewport.height();
float drawX = tileX - viewport.left - PATCH_SIZE;
float drawY = viewportHeight - (tileY + tileHeight - viewport.top - PATCH_SIZE);
GLES11Ext.glDrawTexfOES(drawX, drawY, 0.0f, tileWidth, tileHeight);
}
}
/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (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.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Android code.
*
* The Initial Developer of the Original Code is Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2011
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Kartikaya Gupta <kgupta@mozilla.com>
* Chris Lord <chrislord.net@gmail.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
package org.mozilla.gecko.gfx;
import java.util.ArrayList;
import java.util.List;
import android.os.SystemClock;
import android.util.Log;
public class PanningPerfAPI {
private static final String LOGTAG = "GeckoPanningPerfAPI";
// make this large enough to avoid having to resize the frame time
// list, as that may be expensive and impact the thing we're trying
// to measure.
private static final int EXPECTED_FRAME_COUNT = 2048;
private static boolean mRecordingFrames = false;
private static List<Long> mFrameTimes;
private static long mFrameStartTime;
private static boolean mRecordingCheckerboard = false;
private static List<Float> mCheckerboardAmounts;
private static long mCheckerboardStartTime;
public static void startFrameTimeRecording() {
if (mRecordingFrames) {
Log.e(LOGTAG, "Error: startFrameTimeRecording() called while already recording!");
return;
}
mRecordingFrames = true;
if (mFrameTimes == null) {
mFrameTimes = new ArrayList<Long>(EXPECTED_FRAME_COUNT);
} else {
mFrameTimes.clear();
}
mFrameStartTime = SystemClock.uptimeMillis();
}
public static List<Long> stopFrameTimeRecording() {
if (!mRecordingFrames) {
Log.e(LOGTAG, "Error: stopFrameTimeRecording() called when not recording!");
return null;
}
mRecordingFrames = false;
return mFrameTimes;
}
public static void recordFrameTime() {
// this will be called often, so try to make it as quick as possible
if (mRecordingFrames) {
mFrameTimes.add(SystemClock.uptimeMillis() - mFrameStartTime);
}
}
public static boolean isRecordingCheckerboard() {
return mRecordingCheckerboard;
}
public static void startCheckerboardRecording() {
if (mRecordingCheckerboard) {
Log.e(LOGTAG, "Error: startCheckerboardRecording() called while already recording!");
return;
}
mRecordingCheckerboard = true;
if (mCheckerboardAmounts == null) {
mCheckerboardAmounts = new ArrayList<Float>(EXPECTED_FRAME_COUNT);
} else {
mCheckerboardAmounts.clear();
}
mCheckerboardStartTime = SystemClock.uptimeMillis();
}
public static List<Float> stopCheckerboardRecording() {
if (!mRecordingCheckerboard) {
Log.e(LOGTAG, "Error: stopCheckerboardRecording() called when not recording!");
return null;
}
mRecordingCheckerboard = false;
return mCheckerboardAmounts;
}
public static void recordCheckerboard(float amount) {
// this will be called often, so try to make it as quick as possible
if (mRecordingCheckerboard) {
mCheckerboardAmounts.add(amount);
}
}
}
\ No newline at end of file
/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (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.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Android code.
*
* The Initial Developer of the Original Code is Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2011
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Kartikaya Gupta <kgupta@mozilla.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
package org.mozilla.gecko.gfx;
import android.graphics.Point;
import android.graphics.PointF;
import android.util.FloatMath;
import org.json.JSONObject;
import org.json.JSONException;
import org.mozilla.gecko.util.FloatUtils;
import java.lang.Math;
public final class PointUtils {
public static PointF add(PointF one, PointF two) {
return new PointF(one.x + two.x, one.y + two.y);
}
public static PointF subtract(PointF one, PointF two) {
return new PointF(one.x - two.x, one.y - two.y);
}
public static PointF scale(PointF point, float factor) {
return new PointF(point.x * factor, point.y * factor);
}
public static Point round(PointF point) {
return new Point(Math.round(point.x), Math.round(point.y));
}
/* Returns a new point that is a linear interpolation between start and end points. weight conrols the weighting
* of each of the original points (weight = 1 returns endPoint, weight = 0 returns startPoint)
*/
public static PointF interpolate(PointF startPoint, PointF endPoint, float weight) {
float x = FloatUtils.interpolate(startPoint.x, endPoint.x, weight);
float y = FloatUtils.interpolate(startPoint.y, endPoint.y, weight);
return new PointF(x, y);
}
/* Computes the magnitude of the given vector. */
public static float distance(PointF point) {
return (float)Math.sqrt(point.x * point.x + point.y * point.y);
}
/** Computes the scalar distance between two points. */
public static float distance(PointF one, PointF two) {
return PointF.length(one.x - two.x, one.y - two.y);
}
public static JSONObject toJSON(PointF point) throws JSONException {
// Ensure we put ints, not longs, because Gecko message handlers call getInt().
int x = Math.round(point.x);
int y = Math.round(point.y);
JSONObject json = new JSONObject();
json.put("x", x);
json.put("y", y);
return json;
}
}
/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (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.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Android code.
*
* The Initial Developer of the Original Code is Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2011
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Kartikaya Gupta <kgupta@mozilla.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
package org.mozilla.gecko.gfx;
import org.mozilla.gecko.util.FloatUtils;
import android.graphics.Rect;
import android.graphics.RectF;
import org.json.JSONException;
import org.json.JSONObject;
public final class RectUtils {
public static Rect create(JSONObject json) {
try {
int x = json.getInt("x");
int y = json.getInt("y");
int width = json.getInt("width");
int height = json.getInt("height");
return new Rect(x, y, x + width, y + height);
} catch (JSONException e) {
throw new RuntimeException(e);
}
}
public static Rect contract(Rect rect, int lessWidth, int lessHeight) {
float halfLessWidth = lessWidth / 2.0f;
float halfLessHeight = lessHeight / 2.0f;
return new Rect(Math.round(rect.left + halfLessWidth),
Math.round(rect.top + halfLessHeight),
Math.round(rect.right - halfLessWidth),
Math.round(rect.bottom - halfLessHeight));
}
public static RectF contract(RectF rect, float lessWidth, float lessHeight) {
float halfLessWidth = lessWidth / 2;
float halfLessHeight = lessHeight / 2;
return new RectF(rect.left + halfLessWidth,
rect.top + halfLessHeight,
rect.right - halfLessWidth,
rect.bottom - halfLessHeight);
}
public static RectF expand(RectF rect, float moreWidth, float moreHeight) {
float halfMoreWidth = moreWidth / 2;
float halfMoreHeight = moreHeight / 2;
return new RectF(rect.left - halfMoreWidth,
rect.top - halfMoreHeight,
rect.right + halfMoreWidth,
rect.bottom + halfMoreHeight);
}
public static RectF intersect(RectF one, RectF two) {
float left = Math.max(one.left, two.left);
float top = Math.max(one.top, two.top);
float right = Math.min(one.right, two.right);
float bottom = Math.min(one.bottom, two.bottom);
return new RectF(left, top, Math.max(right, left), Math.max(bottom, top));
}
public static RectF scale(RectF rect, float scale) {
float x = rect.left * scale;
float y = rect.top * scale;
return new RectF(x, y,
x + (rect.width() * scale),
y + (rect.height() * scale));
}
public static Rect round(RectF rect) {
return new Rect(Math.round(rect.left), Math.round(rect.top),
Math.round(rect.right), Math.round(rect.bottom));
}
public static IntSize getSize(Rect rect) {
return new IntSize(rect.width(), rect.height());
}
/*
* Returns the rect that represents a linear transition between `from` and `to` at time `t`,
* which is on the scale [0, 1).
*/
public static RectF interpolate(RectF from, RectF to, float t) {
return new RectF(FloatUtils.interpolate(from.left, to.left, t),
FloatUtils.interpolate(from.top, to.top, t),
FloatUtils.interpolate(from.right, to.right, t),
FloatUtils.interpolate(from.bottom, to.bottom, t));
}
public static boolean fuzzyEquals(RectF a, RectF b) {
return FloatUtils.fuzzyEquals(a.top, b.top)
&& FloatUtils.fuzzyEquals(a.left, b.left)
&& FloatUtils.fuzzyEquals(a.right, b.right)
&& FloatUtils.fuzzyEquals(a.bottom, b.bottom);
}
}
/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (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.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Android code.
*
* The Initial Developer of the Original Code is Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2011
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Kartikaya Gupta <kgupta@mozilla.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
package org.mozilla.gecko.gfx;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PointF;
import android.graphics.PorterDuff;
import android.graphics.Rect;
import android.graphics.RectF;
import android.opengl.GLES11;
import android.opengl.GLES11Ext;
import android.util.Log;
import java.nio.ByteBuffer;
import javax.microedition.khronos.opengles.GL10;
import org.libreoffice.LOKitShell;
import org.mozilla.gecko.util.FloatUtils;
//import org.mozilla.gecko.GeckoAppShell;
/**
* Draws a small rect. This is scaled to become a scrollbar.
*/
public class ScrollbarLayer extends TileLayer {
public static final long FADE_DELAY = 500; // milliseconds before fade-out starts
private static final float FADE_AMOUNT = 0.03f; // how much (as a percent) the scrollbar should fade per frame
private static final int PADDING = 1; // gap between scrollbar and edge of viewport
private static final int BAR_SIZE = 12;
private static final int CAP_RADIUS = (BAR_SIZE / 2);
private static final int[] CROPRECT_MIDPIXEL = new int[] { CAP_RADIUS, CAP_RADIUS, 1, 1 };
private static final int[] CROPRECT_TOPCAP = new int[] { 0, CAP_RADIUS, BAR_SIZE, -CAP_RADIUS };
private static final int[] CROPRECT_BOTTOMCAP = new int[] { 0, BAR_SIZE, BAR_SIZE, -CAP_RADIUS };
private static final int[] CROPRECT_LEFTCAP = new int[] { 0, BAR_SIZE, CAP_RADIUS, -BAR_SIZE };
private static final int[] CROPRECT_RIGHTCAP = new int[] { CAP_RADIUS, BAR_SIZE, CAP_RADIUS, -BAR_SIZE };
private final boolean mVertical;
private final ByteBuffer mBuffer;
private final Bitmap mBitmap;
private final Canvas mCanvas;
private float mOpacity;
private boolean mFinalized = false;
private ScrollbarLayer(CairoImage image, boolean vertical, ByteBuffer buffer) {
super(false, image);
mVertical = vertical;
mBuffer = buffer;
IntSize size = image.getSize();
mBitmap = Bitmap.createBitmap(size.width, size.height, Bitmap.Config.ARGB_8888);
mCanvas = new Canvas(mBitmap);
}
protected void finalize() throws Throwable {
try {
if (!mFinalized && mBuffer != null)
/*GeckoAppShell*/ LOKitShell.freeDirectBuffer(mBuffer);
mFinalized = true;
} finally {
super.finalize();
}
}
public static ScrollbarLayer create(boolean vertical) {
// just create an empty image for now, it will get drawn
// on demand anyway
int imageSize = IntSize.nextPowerOfTwo(BAR_SIZE);
ByteBuffer buffer = /*GeckoAppShell*/LOKitShell.allocateDirectBuffer(imageSize * imageSize * 4);
CairoImage image = new BufferedCairoImage(buffer, imageSize, imageSize, CairoImage.FORMAT_ARGB32);
return new ScrollbarLayer(image, vertical, buffer);
}
/**
* Decrease the opacity of the scrollbar by one frame's worth.
* Return true if the opacity was decreased, or false if the scrollbars
* are already fully faded out.
*/
public boolean fade() {
if (FloatUtils.fuzzyEquals(mOpacity, 0.0f)) {
return false;
}
beginTransaction();
try {
setOpacity(Math.max(mOpacity - FADE_AMOUNT, 0.0f));
invalidate();
} finally {
endTransaction();
}
return true;
}
/**
* Restore the opacity of the scrollbar to fully opaque.
* Return true if the opacity was changed, or false if the scrollbars
* are already fully opaque.
*/
public boolean unfade() {
if (FloatUtils.fuzzyEquals(mOpacity, 1.0f)) {
return false;
}
beginTransaction();
try {
setOpacity(1.0f);
invalidate();
} finally {
endTransaction();
}
return true;
}
private void setOpacity(float opacity) {
mOpacity = opacity;
Paint foregroundPaint = new Paint();
foregroundPaint.setAntiAlias(true);
foregroundPaint.setStyle(Paint.Style.FILL);
// use a (a,r,g,b) color of (127,0,0,0), and multiply the alpha by mOpacity for fading
foregroundPaint.setColor(Color.argb(Math.round(mOpacity * 127), 0, 0, 0));
mCanvas.drawColor(Color.argb(0, 0, 0, 0), PorterDuff.Mode.CLEAR);
mCanvas.drawCircle(CAP_RADIUS, CAP_RADIUS, CAP_RADIUS, foregroundPaint);
mBitmap.copyPixelsToBuffer(mBuffer.asIntBuffer());
}
@Override
public void draw(RenderContext context) {
if (!initialized())
return;
try {
GLES11.glEnable(GL10.GL_BLEND);
GLES11.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA);
Rect rect = RectUtils.round(mVertical ? getVerticalRect(context) : getHorizontalRect(context));
GLES11.glBindTexture(GL10.GL_TEXTURE_2D, getTextureID());
float viewHeight = context.viewport.height();
// for the body of the scrollbar, we take a 1x1 pixel from the center of the image
// and scale it to become the bar
GLES11.glTexParameteriv(GL10.GL_TEXTURE_2D, GLES11Ext.GL_TEXTURE_CROP_RECT_OES, CROPRECT_MIDPIXEL, 0);
GLES11Ext.glDrawTexfOES(rect.left, viewHeight - rect.bottom, 0.0f, rect.width(), rect.height());
if (mVertical) {
// top endcap
GLES11.glTexParameteriv(GL10.GL_TEXTURE_2D, GLES11Ext.GL_TEXTURE_CROP_RECT_OES, CROPRECT_TOPCAP, 0);
GLES11Ext.glDrawTexfOES(rect.left, viewHeight - rect.top, 0.0f, BAR_SIZE, CAP_RADIUS);
// bottom endcap
GLES11.glTexParameteriv(GL10.GL_TEXTURE_2D, GLES11Ext.GL_TEXTURE_CROP_RECT_OES, CROPRECT_BOTTOMCAP, 0);
GLES11Ext.glDrawTexfOES(rect.left, viewHeight - (rect.bottom + CAP_RADIUS), 0.0f, BAR_SIZE, CAP_RADIUS);
} else {
// left endcap
GLES11.glTexParameteriv(GL10.GL_TEXTURE_2D, GLES11Ext.GL_TEXTURE_CROP_RECT_OES, CROPRECT_LEFTCAP, 0);
GLES11Ext.glDrawTexfOES(rect.left - CAP_RADIUS, viewHeight - rect.bottom, 0.0f, CAP_RADIUS, BAR_SIZE);
// right endcap
GLES11.glTexParameteriv(GL10.GL_TEXTURE_2D, GLES11Ext.GL_TEXTURE_CROP_RECT_OES, CROPRECT_RIGHTCAP, 0);
GLES11Ext.glDrawTexfOES(rect.right, viewHeight - rect.bottom, 0.0f, CAP_RADIUS, BAR_SIZE);
}
} finally {
GLES11.glDisable(GL10.GL_BLEND);
}
}
private RectF getVerticalRect(RenderContext context) {
RectF viewport = context.viewport;
FloatSize pageSize = context.pageSize;
float barStart = (viewport.height() * viewport.top / pageSize.height) + CAP_RADIUS;
float barEnd = (viewport.height() * viewport.bottom / pageSize.height) - CAP_RADIUS;
if (barStart > barEnd) {
float middle = (barStart + barEnd) / 2.0f;
barStart = barEnd = middle;
}
float right = viewport.width() - PADDING;
return new RectF(right - BAR_SIZE, barStart, right, barEnd);
}
private RectF getHorizontalRect(RenderContext context) {
RectF viewport = context.viewport;
FloatSize pageSize = context.pageSize;
float barStart = (viewport.width() * viewport.left / pageSize.width) + CAP_RADIUS;
float barEnd = (viewport.width() * viewport.right / pageSize.width) - CAP_RADIUS;
if (barStart > barEnd) {
float middle = (barStart + barEnd) / 2.0f;
barStart = barEnd = middle;
}
float bottom = viewport.height() - PADDING;
return new RectF(barStart, bottom - BAR_SIZE, barEnd, bottom);
}
}
/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (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.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Android code.
*
* The Initial Developer of the Original Code is Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2009-2010
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Patrick Walton <pcwalton@mozilla.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
package org.mozilla.gecko.gfx;
import org.mozilla.gecko.gfx.CairoImage;
import org.mozilla.gecko.gfx.IntSize;
import org.mozilla.gecko.gfx.LayerController;
import org.mozilla.gecko.gfx.TileLayer;
import android.graphics.PointF;
import android.graphics.RectF;
import android.opengl.GLES11;
import android.opengl.GLES11Ext;
import android.util.Log;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import javax.microedition.khronos.opengles.GL10;
/**
* Encapsulates the logic needed to draw a single textured tile.
*
* TODO: Repeating textures really should be their own type of layer.
*/
public class SingleTileLayer extends TileLayer {
public SingleTileLayer(CairoImage image) { this(false, image); }
public SingleTileLayer(boolean repeat, CairoImage image) {
super(repeat, image);
}
@Override
public void draw(RenderContext context) {
// mTextureIDs may be null here during startup if Layer.java's draw method
// failed to acquire the transaction lock and call performUpdates.
if (!initialized())
return;
GLES11.glBindTexture(GL10.GL_TEXTURE_2D, getTextureID());
RectF bounds;
int[] cropRect;
IntSize size = getSize();
RectF viewport = context.viewport;
if (repeats()) {
bounds = new RectF(0.0f, 0.0f, viewport.width(), viewport.height());
int width = Math.round(viewport.width());
int height = Math.round(-viewport.height());
cropRect = new int[] { 0, size.height, width, height };
} else {
bounds = getBounds(context, new FloatSize(size));
cropRect = new int[] { 0, size.height, size.width, -size.height };
}
GLES11.glTexParameteriv(GL10.GL_TEXTURE_2D, GLES11Ext.GL_TEXTURE_CROP_RECT_OES, cropRect,
0);
float height = bounds.height();
float left = bounds.left - viewport.left;
float top = viewport.height() - (bounds.top + height - viewport.top);
GLES11Ext.glDrawTexfOES(left, top, 0.0f, bounds.width(), height);
}
}
/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (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.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Android code.
*
* The Initial Developer of the Original Code is Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2009-2010
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Patrick Walton <pcwalton@mozilla.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
package org.mozilla.gecko.gfx;
//import org.mozilla.gecko.GeckoAppShell;
import org.libreoffice.LOKitShell;
import org.mozilla.gecko.gfx.BufferedCairoImage;
import org.mozilla.gecko.gfx.CairoImage;
import org.mozilla.gecko.gfx.IntSize;
import org.mozilla.gecko.gfx.SingleTileLayer;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Typeface;
import android.util.Log;
import java.nio.ByteBuffer;
import java.nio.IntBuffer;
/**
* Draws text on a layer. This is used for the frame rate meter.
*/
public class TextLayer extends SingleTileLayer {
private final ByteBuffer mBuffer;
private final IntSize mSize;
private boolean mFinalized = false;
/*
* This awkward pattern is necessary due to Java's restrictions on when one can call superclass
* constructors.
*/
private TextLayer(ByteBuffer buffer, BufferedCairoImage image, IntSize size, String text) {
super(false, image);
mBuffer = buffer;
mSize = size;
renderText(text);
}
protected void finalize() throws Throwable {
try {
if (!mFinalized && mBuffer != null)
/*GeckoAppShell*/ LOKitShell.freeDirectBuffer(mBuffer);
mFinalized = true;
} finally {
super.finalize();
}
}
public static TextLayer create(IntSize size, String text) {
ByteBuffer buffer = /*GeckoAppShell*/LOKitShell.allocateDirectBuffer(size.width * size.height * 4);
BufferedCairoImage image = new BufferedCairoImage(buffer, size.width, size.height,
CairoImage.FORMAT_ARGB32);
return new TextLayer(buffer, image, size, text);
}
public void setText(String text) {
renderText(text);
invalidate();
}
private void renderText(String text) {
Bitmap bitmap = Bitmap.createBitmap(mSize.width, mSize.height, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
Paint textPaint = new Paint();
textPaint.setAntiAlias(true);
textPaint.setColor(Color.WHITE);
textPaint.setFakeBoldText(true);
textPaint.setTextSize(18.0f);
textPaint.setTypeface(Typeface.DEFAULT_BOLD);
float width = textPaint.measureText(text) + 18.0f;
Paint backgroundPaint = new Paint();
backgroundPaint.setColor(Color.argb(127, 0, 0, 0));
canvas.drawRect(0.0f, 0.0f, width, 18.0f + 6.0f, backgroundPaint);
canvas.drawText(text, 6.0f, 18.0f, textPaint);
bitmap.copyPixelsToBuffer(mBuffer.asIntBuffer());
}
}
/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (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.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Android code.
*
* The Initial Developer of the Original Code is Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2009-2010
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* James Willcox <jwillcox@mozilla.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
package org.mozilla.gecko.gfx;
import android.opengl.GLES10;
import java.util.Stack;
public class TextureGenerator {
private static final int MIN_TEXTURES = 5;
private static TextureGenerator sSharedInstance;
private Stack<Integer> mTextureIds;
private TextureGenerator() { mTextureIds = new Stack<Integer>(); }
public static TextureGenerator get() {
if (sSharedInstance == null)
sSharedInstance = new TextureGenerator();
return sSharedInstance;
}
public synchronized int take() {
if (mTextureIds.empty())
return 0;
return (int)mTextureIds.pop();
}
public synchronized void fill() {
int[] textures = new int[1];
while (mTextureIds.size() < MIN_TEXTURES) {
GLES10.glGenTextures(1, textures, 0);
mTextureIds.push(textures[0]);
}
}
}
/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (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.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Android code.
*
* The Initial Developer of the Original Code is Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2009-2010
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Patrick Walton <pcwalton@mozilla.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
package org.mozilla.gecko.gfx;
import javax.microedition.khronos.opengles.GL10;
import java.util.ArrayList;
/** Manages a list of dead tiles, so we don't leak resources. */
public class TextureReaper {
private static TextureReaper sSharedInstance;
private ArrayList<Integer> mDeadTextureIDs;
private TextureReaper() { mDeadTextureIDs = new ArrayList<Integer>(); }
public static TextureReaper get() {
if (sSharedInstance == null)
sSharedInstance = new TextureReaper();
return sSharedInstance;
}
public void add(int[] textureIDs) {
for (int textureID : textureIDs)
add(textureID);
}
public void add(int textureID) {
mDeadTextureIDs.add(textureID);
}
public void reap(GL10 gl) {
int[] deadTextureIDs = new int[mDeadTextureIDs.size()];
for (int i = 0; i < deadTextureIDs.length; i++)
deadTextureIDs[i] = mDeadTextureIDs.get(i);
mDeadTextureIDs.clear();
gl.glDeleteTextures(deadTextureIDs.length, deadTextureIDs, 0);
}
}
/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (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.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Android code.
*
* The Initial Developer of the Original Code is Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2009-2010
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* James Willcox <jwillcox@mozilla.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
package org.mozilla.gecko.gfx;
import org.libreoffice.LOKitShell;
import org.mozilla.gecko.gfx.LayerController;
import org.mozilla.gecko.gfx.SingleTileLayer;
//import org.mozilla.gecko.GeckoAppShell;
import android.opengl.GLES11;
import android.opengl.GLES11Ext;
import android.graphics.RectF;
import android.util.Log;
import javax.microedition.khronos.opengles.GL10;
/**
* Encapsulates the logic needed to draw the single-tiled Gecko texture
*/
public class WidgetTileLayer extends Layer {
private static final String LOGTAG = "WidgetTileLayer";
private int[] mTextureIDs;
private CairoImage mImage;
public WidgetTileLayer(CairoImage image) {
mImage = image;
}
protected boolean initialized() { return mTextureIDs != null; }
@Override
public IntSize getSize() { return mImage.getSize(); }
protected void bindAndSetGLParameters() {
GLES11.glBindTexture(GL10.GL_TEXTURE_2D, mTextureIDs[0]);
GLES11.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_NEAREST);
GLES11.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);
}
@Override
protected void finalize() throws Throwable {
if (mTextureIDs != null)
TextureReaper.get().add(mTextureIDs);
}
@Override
protected boolean performUpdates(GL10 gl, RenderContext context) {
super.performUpdates(gl, context);
if (mTextureIDs == null) {
mTextureIDs = new int[1];
GLES11.glGenTextures(1, mTextureIDs, 0);
}
bindAndSetGLParameters();
/*GeckoAppShell*/LOKitShell.bindWidgetTexture();
return true;
}
@Override
public void draw(RenderContext context) {
// mTextureIDs may be null here during startup if Layer.java's draw method
// failed to acquire the transaction lock and call performUpdates.
if (!initialized())
return;
GLES11.glBindTexture(GL10.GL_TEXTURE_2D, mTextureIDs[0]);
RectF bounds;
int[] cropRect;
IntSize size = getSize();
RectF viewport = context.viewport;
bounds = getBounds(context, new FloatSize(size));
cropRect = new int[] { 0, size.height, size.width, -size.height };
bounds.offset(-viewport.left, -viewport.top);
GLES11.glTexParameteriv(GL10.GL_TEXTURE_2D, GLES11Ext.GL_TEXTURE_CROP_RECT_OES, cropRect,
0);
float top = viewport.height() - (bounds.top + bounds.height());
// There may be errors from a previous GL call, so clear them first because
// we want to check for one below
while (GLES11.glGetError() != GLES11.GL_NO_ERROR);
GLES11Ext.glDrawTexfOES(bounds.left, top, 0.0f, bounds.width(), bounds.height());
int error = GLES11.glGetError();
if (error != GLES11.GL_NO_ERROR) {
Log.i(LOGTAG, "Failed to draw texture: " + error);
}
}
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment