customdrawn-android: Finishes the initial implementation of text rendering, it works ok for a very initial support. Improves the AlphaBlend method in TLazCanvas to be more optimized and support a custom source position.

git-svn-id: trunk@34138 -
This commit is contained in:
sekelsenmat 2011-12-12 21:10:18 +00:00
parent 2b4adf30f7
commit 446ffaa84b
6 changed files with 47 additions and 32 deletions

View File

@ -81,6 +81,7 @@ public class LCLActivity extends Activity
{
Paint localpaint = new Paint();
Rect localbounds = new Rect();
localpaint.setTextSize(18);
localpaint.getTextBounds(lcltext, 0, lcltext.length(), localbounds);
lclwidth = localbounds.width();
lclheight = localbounds.height();
@ -93,7 +94,11 @@ public class LCLActivity extends Activity
lclbitmap = Bitmap.createBitmap(lclwidth, lclheight, Bitmap.Config.ARGB_8888);
Canvas localcanvas = new Canvas(lclbitmap);
Paint localpaint = new Paint();
localcanvas.drawText(lcltext, 0, 0, localpaint);
localpaint.setColor(Color.BLACK);
localpaint.setTextSize(18);
localpaint.setFlags(Paint.ANTI_ALIAS_FLAG);
localcanvas.drawColor(Color.TRANSPARENT); // TRANSPARENT
localcanvas.drawText(lcltext, 0, lclheight, localpaint);
}
// LCLType definitions
@ -172,6 +177,7 @@ public class LCLActivity extends Activity
public int lclbutton2;
public int lclbutton3;
public Bitmap lclbitmap;
public int lcltextsize;
static
{

View File

@ -31,4 +31,8 @@
{$endif}
{$endif}
// Default options for various backends
{$ifdef CD_Android}
{$define CD_UseNativeText}
{$endif}

View File

@ -86,7 +86,8 @@ procedure HideForm(ACDForm: TCDNonNativeForm);
procedure UpdateControlLazImageAndCanvas(var AImage: TLazIntfImage;
var ACanvas: TLazCanvas; AWidth, AHeight: Integer; AFormat: TUpdateLazImageFormat;
AData: Pointer = nil; AForceUpdate: Boolean = False; AFreeImageOnUpdate: Boolean = True);
AData: Pointer = nil; AForceUpdate: Boolean = False;
AFreeImageOnUpdate: Boolean = True; ADataOwner: Boolean = True);
procedure DrawFormBackground(var AImage: TLazIntfImage; var ACanvas: TLazCanvas);
procedure RenderChildWinControls(var AImage: TLazIntfImage;
var ACanvas: TLazCanvas; ACDControlsList: TFPList);
@ -219,7 +220,8 @@ end;
// If AForceUpdate=True then it will update even if the width and height remain the same
procedure UpdateControlLazImageAndCanvas(var AImage: TLazIntfImage;
var ACanvas: TLazCanvas; AWidth, AHeight: Integer; AFormat: TUpdateLazImageFormat;
AData: Pointer = nil; AForceUpdate: Boolean = False; AFreeImageOnUpdate: Boolean = True);
AData: Pointer = nil; AForceUpdate: Boolean = False;
AFreeImageOnUpdate: Boolean = True; ADataOwner: Boolean = True);
var
lRawImage: TRawImage;
lPixelSize: Byte;
@ -269,7 +271,7 @@ begin
end;
AImage := TLazIntfImage.Create(AWidth, AHeight);
AImage.SetRawImage(lRawImage);
AImage.SetRawImage(lRawImage, ADataOwner);
if (ACanvas <> nil) then ACanvas.Free;
ACanvas := TLazCanvas.Create(AImage);

View File

@ -2175,7 +2175,7 @@ function TCDWidgetSet.ExtTextOut(DC: HDC; X, Y: Integer; Options: Longint;
B: Boolean; }
begin
{$ifdef VerboseCDWinAPI}
WriteLn('[WinAPI ExtTextOut]');
DebugLn('[WinAPI ExtTextOut]');
{$endif}
Result := False;

View File

@ -2186,7 +2186,6 @@ var
lCanvas: TLazCanvas = nil;
lWidth, lHeight: jint;
lDestCanvas: TLazCanvas;
lDestX, lDestY: Integer;
begin
{$ifdef VerboseCDText}
DebugLn(Format(':>[WinAPI ExtTextOut] DC=%x javaEnvRef=%x Str=%s X=%d Y=%d',
@ -2203,8 +2202,6 @@ begin
if not IsValidDC(DC) then Exit;
lDestCanvas := TLazCanvas(DC);
lDestX := X + lDestCanvas.BaseWindowOrg.X;
lDestY := Y + lDestCanvas.BaseWindowOrg.Y;
if (javaEnvRef = nil) then Exit;
@ -2224,8 +2221,8 @@ begin
lHeight := javaEnvRef^^.GetLongField(javaEnvRef, javaActivityObject, javaField_lclheight);
{$ifdef VerboseCDText}
DebugLn(Format(':[WinAPI ExtTextOut] lDestX=%d lDestY=%d lWidth=%d lHeight=%d',
[lDestX, lDestY, lWidth, lHeight]));
DebugLn(Format(':[WinAPI ExtTextOut] lWidth=%d lHeight=%d',
[lWidth, lHeight]));
{$endif}
// ---------------------------
@ -2236,20 +2233,17 @@ begin
AndroidBitmap_lockPixels(javaEnvRef, lJavaBitmap, @pixels);
// Prepare the non-native image and canvas
UpdateControlLazImageAndCanvas(lImage, lCanvas, lWidth, lHeight, clfRGBA32, pixels, True, False);
UpdateControlLazImageAndCanvas(lImage, lCanvas, lWidth, lHeight, clfRGBA32, pixels, True, False, False);
{$ifdef VerboseCDText}DebugLn(':[WinAPI ExtTextOut] Before CanvasCopyRect');{$endif}
// Execute the copy
lDestCanvas.CanvasCopyRect(lCanvas, lDestX, lDestY, 0, 0, lWidth, lHeight); // try also AlphaBlend
lDestCanvas.AlphaBlend(lCanvas, X, Y, 0, 0, lWidth, lHeight);
{$ifdef VerboseCDText}DebugLn(':[WinAPI ExtTextOut] After CanvasCopyRect');{$endif}
// Release the bitmap lock
AndroidBitmap_unlockPixels(javaEnvRef, lJavaBitmap);
{$ifdef VerboseCDText}DebugLn(':[WinAPI ExtTextOut] After AndroidBitmap_unlockPixels');{$endif}
lCanvas.Free;
{$ifdef VerboseCDText}DebugLn(':[WinAPI ExtTextOut] B');{$endif}
//lImage.Free;
lImage.Free;
{$ifdef VerboseCDText}DebugLn(':[WinAPI ExtTextOut] C');{$endif}
// Release the bitmap lock
AndroidBitmap_unlockPixels(javaEnvRef, lJavaBitmap);
{$ifdef VerboseCDText}
DebugLn(':<[WinAPI ExtTextOut]');

View File

@ -392,48 +392,57 @@ end;
procedure TLazCanvas.AlphaBlend(ASource: TLazCanvas;
const ADestX, ADestY, ASourceX, ASourceY, ASourceWidth, ASourceHeight: Integer);
var
x, y, CurX, CurY: Integer;
x, y, CurDestX, CurDestY, CurSrcX, CurSrcY: Integer;
MaskValue, InvMaskValue: Word;
CurColor: TFPColor;
CurColor, SrcColor: TFPColor;
lDrawWidth, lDrawHeight: Integer;
begin
// Take care not to draw outside the destination area
lDrawWidth := Min(Self.Width - ADestX, ASource.Width);
lDrawHeight := Min(Self.Height - ADestY, ASource.Height);
lDrawWidth := Min(Self.Width - ADestX, ASource.Width - ASourceX);
lDrawHeight := Min(Self.Height - ADestY, ASource.Height - ASourceY);
lDrawWidth := Min(lDrawWidth, ASourceWidth);
lDrawHeight := Min(lDrawHeight, ASourceHeight);
//DebugLn(Format('[TLazCanvas.AlphaBlend] lDrawWidth=%d lDrawHeight=%d',
// [lDrawWidth, lDrawHeight]));
for y := 0 to lDrawHeight - 1 do
begin
for x := 0 to lDrawWidth - 1 do
begin
CurX := ADestX + x;
CurY := ADestY + y;
CurDestX := ADestX + x;
CurDestY := ADestY + y;
CurSrcX := ASourceX + x;
CurSrcY := ASourceY + y;
// Never draw outside the destination
if (CurX < 0) or (CurY < 0) then Continue;
if (CurDestX < 0) or (CurDestY < 0) then Continue;
MaskValue := ASource.Colors[x, y].alpha;
MaskValue := ASource.Colors[CurSrcX, CurSrcY].alpha;
InvMaskValue := $FFFF - MaskValue;
if MaskValue = $FFFF then
begin
Self.Colors[CurX, CurY] := ASource.Colors[x, y];
Self.Colors[CurDestX, CurDestY] := ASource.Colors[CurSrcX, CurSrcY];
end
else if MaskValue > $00 then
begin
CurColor := Self.Colors[CurX, CurY];
CurColor := Self.Colors[CurDestX, CurDestY];
SrcColor := ASource.Colors[CurSrcX, CurSrcY];
CurColor.Red := Round(
CurColor.Red * InvMaskValue / $FFFF +
ASource.Colors[x, y].Red * MaskValue / $FFFF);
SrcColor.Red * MaskValue / $FFFF);
CurColor.Green := Round(
CurColor.Green * InvMaskValue / $FFFF +
ASource.Colors[x, y].Green * MaskValue / $FFFF);
SrcColor.Green * MaskValue / $FFFF);
CurColor.Blue := Round(
CurColor.Blue * InvMaskValue / $FFFF +
ASource.Colors[x, y].Blue * MaskValue / $FFFF);
SrcColor.Blue * MaskValue / $FFFF);
Self.Colors[CurX, CurY] := CurColor;
CurColor.alpha := alphaOpaque;
Self.Colors[CurDestX, CurDestY] := CurColor;
end;
end;
end;