customdrawn-android: Starts implementing text metrics

git-svn-id: trunk@33908 -
This commit is contained in:
sekelsenmat 2011-12-02 16:37:19 +00:00
parent 367f5ec871
commit 066a73b5a2
8 changed files with 114 additions and 67 deletions

View File

@ -50,20 +50,36 @@ public class LCLActivity extends Activity
{
super.onCreate(savedInstanceState);
// TextView tv = new TextView(this);
// tv.setText( Integer.toString(intFromJNI()) );
// setContentView(tv);
LCLSurface lclsurface = new LCLSurface(this);
setContentView(lclsurface);
lclsurface.postInvalidate();
// Tell the LCL that an OnCreate has happened and what is our instance
LCLOnCreate(this);
}
// JNI table of functions
// JNI table of Pascal functions
public native int LCLDrawToBitmap(int width, int height, Bitmap bitmap);
public native int LCLOnTouch(float x, float y, int action);
public native int LCLOnCreate(LCLActivity lclactivity);
// Functions exported to the Pascal side
// input: String lcltext
// output: int lclwidth, int lclheight
public void LCLDoGetTextBounds()
{
Paint paint = new Paint();
Rect bounds = new Rect();
paint.getTextBounds(lcltext, 0, lcltext.length(), bounds);
lclwidth = bounds.width();
lclheight = bounds.height();
}
// Fields exported to the Pascal side for easier data communication
public String lcltext;
public int lclwidth;
public int lclheight;
public long nativeCodeLoaded=0;
static
{
try

View File

@ -16,6 +16,7 @@ uses
exports
Java_com_pascal_lclproject_LCLActivity_LCLOnTouch name 'Java_com_pascal_lcltest_LCLActivity_LCLOnTouch',
Java_com_pascal_lclproject_LCLActivity_LCLDrawToBitmap name 'Java_com_pascal_lcltest_LCLActivity_LCLDrawToBitmap',
Java_com_pascal_lclproject_LCLActivity_LCLOnCreate name 'Java_com_pascal_lcltest_LCLActivity_LCLOnCreate',
JNI_OnLoad name 'JNI_OnLoad',
JNI_OnUnload name 'JNI_OnUnload';
{$endif}

View File

@ -31,7 +31,7 @@ object Form1: TForm1
object ProgressBar1: TProgressBar
Left = 72
Height = 20
Top = 72
Top = 80
Width = 140
Position = 60
TabOrder = 2
@ -44,4 +44,12 @@ object Form1: TForm1
Position = 0
TabOrder = 3
end
object CheckBox1: TCheckBox
Left = 72
Height = 21
Top = 48
Width = 94
Caption = 'CheckBox1'
TabOrder = 4
end
end

View File

@ -16,6 +16,7 @@ type
TForm1 = class(TForm)
Arrow1: TArrow;
Button1: TButton;
CheckBox1: TCheckBox;
ProgressBar1: TProgressBar;
TrackBar1: TTrackBar;
procedure Arrow1Click(Sender: TObject);

View File

@ -148,7 +148,7 @@ type va_list=pointer;
PPJavaVM=^PJavaVM;
PJavaVM=^JavaVM;
JNINativeInterface={$ifdef packedrecords}packed{$endif} record
JNINativeInterface= record
reserved0:pointer;
reserved1:pointer;
reserved2:pointer;
@ -513,9 +513,9 @@ function JNI_GetCreatedJavaVMs(vm:PPJavaVM;ASize:jsize;p:Pjsize):jint;{$ifdef ms
* called by JNI, not provided by JNI.
*)
var
{var
curVM:PJavaVM=nil;
curEnv:PJNIEnv=nil;
curEnv:PJNIEnv=nil;}
(*
function JNI_OnLoad(vm:PJavaVM;reserved:pointer):jint;{$ifdef mswindows}stdcall;{$else}cdecl;{$endif}
@ -523,7 +523,7 @@ procedure JNI_OnUnload(vm:PJavaVM;reserved:pointer);{$ifdef mswindows}stdcall;{$
*)
implementation
function JNI_OnLoad(vm:PJavaVM;reserved:pointer):jint;{$ifdef mswindows}stdcall;{$else}cdecl;{$endif}
(*function JNI_OnLoad(vm:PJavaVM;reserved:pointer):jint;{$ifdef mswindows}stdcall;{$else}cdecl;{$endif}
begin
curVM:=vm;
result:=JNI_VERSION_1_6;
@ -531,7 +531,7 @@ end;
procedure JNI_OnUnload(vm:PJavaVM;reserved:pointer);{$ifdef mswindows}stdcall;{$else}cdecl;{$endif}
begin
end;
end;*)
end.

View File

@ -201,16 +201,27 @@ function WindowProc(Window: HWnd; Msg: UInt; WParam: Windows.WParam;
function Java_com_pascal_lclproject_LCLActivity_LCLOnTouch(env:PJNIEnv;this:jobject; x, y: single; action: jint): jint; cdecl;
function Java_com_pascal_lclproject_LCLActivity_LCLDrawToBitmap(
env:PJNIEnv;this:jobject; width, height: jint; abitmap: jobject): jint; cdecl;
function Java_com_pascal_lclproject_LCLActivity_LCLOnCreate(
env:PJNIEnv; this:jobject; alclactivity: jobject): jint; cdecl;
function JNI_OnLoad(vm:PJavaVM;reserved:pointer):jint; cdecl;
procedure JNI_OnUnload(vm:PJavaVM;reserved:pointer); cdecl;
var
curVM: PJavaVM=nil;
curEnv: PJNIEnv=nil;
curJavaClass: JClass = nil;
curJavaObject: jobject = nil;
nativeCodeLoaded:JfieldID=nil;
eventResult: Integer = 0;
javaVMRef: PJavaVM=nil;
javaEnvRef: PJNIEnv=nil;
javaActivityClass: JClass = nil;
javaActivityObject: jobject = nil;
// Fields of our Activity
javaField_lcltext: JfieldID=nil;
javaField_lclwidth: JfieldID=nil;
javaField_lclheight: JfieldID=nil;
// Methods of our Activity
javaMethod_LCLDoGetTextBounds: jmethodid = nil;
// This is utilized to store the information such as invalidate requests in events
eventResult: jint;
{$endif}
implementation

View File

@ -18,16 +18,6 @@
*****************************************************************************
}
{function Java_com_pascal_lclproject_LCLActivity_stringFromJNI(env:PJNIEnv;this:jobject):jstring; cdecl;
var x:single;
begin
__android_log_write(ANDROID_LOG_INFO,'nativetest','Java_com_bero_nativetest_Main_stringFromJNI entered');
curEnv^.SetLongField(curEnv,curClass,nativeCodeLoaded,1);
x:=8;
result:=env^.NewStringUTF(env,pchar('Hello from native free pascal code by BeRo to the java world on the android platform ! '+floattostr(x*0.5)));
__android_log_write(ANDROID_LOG_INFO,'nativetest','Java_com_bero_nativetest_Main_stringFromJNI exited');
end;}
const
ACTION_DOWN = 0;
ACTION_UP = 1;
@ -39,15 +29,10 @@ var
lTarget: TWinControl;
lEventPos: TPoint;
begin
eventResult := 0;
{$ifdef VerboseCDEvents}
__android_log_write(ANDROID_LOG_INFO,'lclapp',PChar(Format('LCLOnTouch called x=%f y=%f action=%d', [x, y, action])));
{$endif}
{ curJavaClass := env^^.GetObjectClass(env, this);
__android_log_write(ANDROID_LOG_INFO,'nativetest','LCLOnTouch after GetObjectClass');}
curJavaObject := this;
curEnv := env;
eventResult := 0;
lCurForm := GetCurrentForm();
lTarget := FindControlWhichReceivedEvent(lCurForm.LCLForm, lCurForm.Children, Round(X), Round(Y));
@ -68,6 +53,7 @@ begin
ACTION_MOVE: LCLSendMouseMoveMsg(lTarget, lEventPos.X, lEventPos.Y, []);
end;
// This sends messages like Invalidate requests
Result := eventResult;
end;
@ -122,6 +108,13 @@ begin
AndroidBitmap_unlockPixels(env, abitmap);
end;
function Java_com_pascal_lclproject_LCLActivity_LCLOnCreate(
env:PJNIEnv; this:jobject; alclactivity: jobject): jint; cdecl;
begin
Result := 0;
javaActivityObject := alclactivity;
end;
const NativeMethods: array[0..1] of JNINativeMethod=
((name:'LCLDrawToBitmap';
signature:'(IILandroid/graphics/Bitmap;)I';
@ -133,47 +126,52 @@ const NativeMethods: array[0..1] of JNINativeMethod=
function JNI_OnLoad(vm:PJavaVM;reserved:pointer):jint; cdecl;
begin
curVM:=vm;
javaVMRef := vm;
__android_log_write(ANDROID_LOG_INFO, 'lclapp', 'JNI_OnLoad called');
__android_log_write(ANDROID_LOG_INFO, 'lclapp', PChar(Format('CurVM=%x', [PtrInt(CurVM)])));
__android_log_write(ANDROID_LOG_INFO, 'lclapp', PChar(Format('CurVM^=%x', [PtrInt(CurVM^)])));
__android_log_write(ANDROID_LOG_INFO, 'lclapp', PChar(Format('CurVM^^.reserved0=%x', [PtrInt(CurVM^^.reserved0)])));
__android_log_write(ANDROID_LOG_INFO, 'lclapp', PChar(Format('CurVM^^.GetEnv=%x', [PtrInt(Pointer(@CurVM^^.GetEnv))])));
{ __android_log_write(ANDROID_LOG_INFO, 'lclapp', PChar(Format('vm=%x', [PtrInt(vm)])));
__android_log_write(ANDROID_LOG_INFO, 'lclapp', PChar(Format('vm^=%x', [PtrInt(vm^)])));
__android_log_write(ANDROID_LOG_INFO, 'lclapp', PChar(Format('vm^^.reserved0=%x', [PtrInt(vm^^.reserved0)])));
__android_log_write(ANDROID_LOG_INFO, 'lclapp', PChar(Format('vm^^.GetEnv=%x', [PtrInt(Pointer(@vm^^.GetEnv))]))); }
{
vm^^.GetEnv crashes HTC Wildfire, Alcatel and the Emulator if you don't build your project with -CpARMV6
see: http://groups.google.com/group/android-ndk/browse_thread/thread/ba542483f062a828/ef9077617794e0f5
}
if vm^^.GetEnv(curVM,@curEnv,JNI_VERSION_1_4)<>JNI_OK then
if vm^^.GetEnv(vm,@javaEnvRef,JNI_VERSION_1_4)<>JNI_OK then
begin
__android_log_write(ANDROID_LOG_FATAL, 'lclapp', 'curVM^.GetEnv failed');
result:=JNI_ERR;
exit;
Exit(JNI_ERR);
end;
__android_log_write(ANDROID_LOG_INFO,'lclapp','Reading curClass');
curJavaClass:=curEnv^^.FindClass(curEnv,'com/pascal/lcltest/LCLActivity');
if not assigned(curJavaClass) then
// Find our activity class
__android_log_write(ANDROID_LOG_INFO,'lclapp','Reading our Activity Class');
javaActivityClass := javaEnvRef^^.FindClass(javaEnvRef,'com/pascal/lcltest/LCLActivity');
if not assigned(javaActivityClass) then
begin
__android_log_write(ANDROID_LOG_FATAL, 'lclapp', 'curEnv^.FindClass failed');
result:=JNI_ERR;
exit;
end;
if curEnv^^.RegisterNatives(curEnv, curJavaClass, @NativeMethods[0],length(NativeMethods))<0 then
begin
__android_log_write(ANDROID_LOG_FATAL, 'lclapp', 'curEnv^.RegisterNatives failed');
result:=JNI_ERR;
exit;
__android_log_write(ANDROID_LOG_FATAL, 'lclapp', 'javaEnvRef^.FindClass failed');
Exit(JNI_ERR);
end;
nativeCodeLoaded:=curEnv^^.GetFieldID(curEnv, curJavaClass, 'nativeCodeLoaded','J');
if not assigned(nativeCodeLoaded) then
// Register Pascal exported calls
if javaEnvRef^^.RegisterNatives(javaEnvRef, javaActivityClass, @NativeMethods[0],length(NativeMethods))<0 then
begin
__android_log_write(ANDROID_LOG_FATAL, 'lclapp', 'curEnv^.GetFieldID failed');
result:=JNI_ERR;
exit;
__android_log_write(ANDROID_LOG_FATAL, 'lclapp', 'javaEnvRef^.RegisterNatives failed');
Exit(JNI_ERR);
end;
// Read all field IDs
JavaField_lcltext := javaEnvRef^^.GetFieldID(javaEnvRef, javaActivityClass, 'lcltext', 'Ljava/lang/String;');
JavaField_lclwidth := javaEnvRef^^.GetFieldID(javaEnvRef, javaActivityClass, 'lclwidth', 'I');
JavaField_lclheight := javaEnvRef^^.GetFieldID(javaEnvRef, javaActivityClass, 'lclheight', 'I');
if not assigned(JavaField_lcltext) then
begin
__android_log_write(ANDROID_LOG_FATAL, 'lclapp', 'javaEnvRef^.GetFieldID failed for lcltext');
Exit(JNI_ERR);
end;
// Read all method IDs
javaMethod_LCLDoGetTextBounds := javaEnvRef^^.GetMethodID(javaEnvRef, javaActivityClass, 'LCLDoGetTextBounds', '()V');
result:=JNI_VERSION_1_4;// 1_6 is another option
end;

View File

@ -4085,21 +4085,33 @@ end;*)
Returns: Nothing
------------------------------------------------------------------------------}
function TCDWidgetSet.GetTextExtentPoint(DC: HDC; Str: PChar; Count: Integer; var Size: TSize): Boolean;
{var
WideStr: WideString;
QtDC: TQtDeviceContext absolute DC;}
var
lJavaString: jstring;
begin
{$ifdef VerboseCDWinAPI}
DebugLn('[WinAPI GetTextExtentPoint]');
{$ifdef VerboseCDText}
DebugLn(Format('[WinAPI GetTextExtentPoint] DC=%x javaEnvRef=%x', [DC, PtrInt(javaEnvRef)]));
{$endif}
Result := False;
if not IsValidDC(DC) then Exit;
{ WideStr := GetUtf8String(Str);
Size.cx := QtDC.Metrics.width(@WideStr, Count);
Size.cy := QtDC.Metrics.height;}
if (javaEnvRef = nil) then Exit;
// Prepare the input
lJavaString :=javaEnvRef^^.NewStringUTF(javaEnvRef, Str);
javaEnvRef^^.SetObjectField(javaEnvRef, javaActivityObject, JavaField_lcltext, lJavaString);
// Call the method
javaEnvRef^^.CallVoidMethod(javaEnvRef, javaActivityObject, javaMethod_LCLDoGetTextBounds);
// Read the output
Size.cx := javaEnvRef^^.GetLongField(javaEnvRef, javaActivityObject, javaField_lclwidth);
Size.cy := javaEnvRef^^.GetLongField(javaEnvRef, javaActivityObject, javaField_lclheight);
{$ifdef VerboseCDText}
DebugLn(Format('[WinAPI GetTextExtentPoint] Size=%d, %d', [Size.cx, Size.cy]));
{$endif}
Result := True;
end;