mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-04-13 17:59:32 +02:00
customdrawn-android: Starts implementing text metrics
git-svn-id: trunk@33908 -
This commit is contained in:
parent
367f5ec871
commit
066a73b5a2
@ -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
|
||||
|
@ -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}
|
||||
|
@ -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
|
||||
|
@ -16,6 +16,7 @@ type
|
||||
TForm1 = class(TForm)
|
||||
Arrow1: TArrow;
|
||||
Button1: TButton;
|
||||
CheckBox1: TCheckBox;
|
||||
ProgressBar1: TProgressBar;
|
||||
TrackBar1: TTrackBar;
|
||||
procedure Arrow1Click(Sender: TObject);
|
||||
|
@ -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.
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user