How to draw text on Android with SKIA?

2,249 views
Skip to first unread message

Hsu France

unread,
Jan 18, 2012, 5:33:08 AM1/18/12
to skia-d...@googlegroups.com
Dears,

We have a project to port GStreamer into Android (froyo).
When we work on porting pango related plugins (including Pango, cairo, fontconfig, ...), the pipeline will seg-fault (subsink is one element in our project):
gst-launch filesrc location=/media/movie.srt ! subparse ! textrender ! subsink 
Seg-fault happened after (or at?) pango/fontconfig reading configuration file and font file.

I can't fix the seg-fault and can't find more information about running Pango on Android.
But there are many information said Android uses Skia to render texts.
Therefore, we try to modify our subsink to render text with skia, like this:
gst-launch filesrc location=/media/movie.srt ! subparse ! subsink  


Sorry for such long description.
Our question is how use skia draw text on android?

We try to use skia to draw something (a rectangle or some text) on the Android desktop, but nothing displayed.
Like this:
---------------------- 
SkBitmap bitmap;
bitmap.setConfig(SkBitmap::kARGB_8888_Config, 200, 200);
bitmap.allocPixels();

SkCanvas canvas(new SkDevice(bitmap));
SkPaint paint;          

SkRect r;

paint.setARGB(255, 255, 0, 0);
r.set(25, 25, 145, 145);
canvas.drawRect(r, paint);

paint.setARGB(255, 0, 255, 0);
r.offset(20, 20);
canvas.drawRect(r, paint);

paint.setARGB(255, 0, 0, 255);
r.offset(20, 20);
canvas.drawRect(r, paint);

canvas.drawText("Hello, World", 4*sizeof(char), 200, 100 , paint);
----------------------
Should we also use sufaceflinger to prepare a surface and post raw data of Skia bitmap to this surface?
How could we get the raw data from Skia bitmap?

One of our reference: gstreamer surface flinger sink -- http://gitorious.org/rowboat/external-gst-plugins-android/trees/e8a8f34

Thank you.
France Hsu

Mike Reed

unread,
Jan 18, 2012, 8:04:13 AM1/18/12
to skia-d...@googlegroups.com
The last line is possibly wrong:

        drawText(text, byte_length, x, y, paint)

You should pass strlen("Hello, World") for the 2nd parameter to see all of the text.
Your X coordinate is 200, which will start the text at the right edge of your canvas, so I expect nothing will show up.

Try this

paint.setAntiAlias(true);
const char* s = "Hello, World";
canvas.drawText(s, strlen(s), 20, 100, paint);

France Hsu

--
You received this message because you are subscribed to the Google Groups "skia-discuss" group.
To view this discussion on the web visit https://groups.google.com/d/msg/skia-discuss/-/2wuLWVPcLEEJ.
To post to this group, send email to skia-d...@googlegroups.com.
To unsubscribe from this group, send email to skia-discuss...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/skia-discuss?hl=en.

Hsu France

unread,
Jan 18, 2012, 9:41:44 PM1/18/12
to skia-d...@googlegroups.com
Hi! Mike,

Thanks.

The argument of drawText is wrong, but it might not be the root cause of no output.
(I've fixed it, of course)
Before drawText, the rectangle of canvas.drawRect(r, paint); also doesn't show.

In my expectation, the rectangles and text I draw will appear at top of android desktop.
Is it correct?


France

Ryan Statzer

unread,
Jan 19, 2012, 12:18:44 AM1/19/12
to skia-d...@googlegroups.com
Are you getting any output on the screen at all from Skia?

If I'm not mistaken, drawing to the screen from C++ (in Android) requires minimal use of OpenGL, at the very least to place your bitmap on the screen. I could be wrong here though as my only experience with Skia is using the GPU drawing side, which obviously requires OpenGL.

--
You received this message because you are subscribed to the Google Groups "skia-discuss" group.
To view this discussion on the web visit https://groups.google.com/d/msg/skia-discuss/-/6j4cQZ5tAKIJ.

Hsu France

unread,
Jan 19, 2012, 3:47:27 AM1/19/12
to skia-d...@googlegroups.com
Hi! rstat1,

I have the same idea with you.
Because the project "gstreamer surface flinger sink" (http://gitorious.org/rowboat/external-gst-plugins-android/trees/e8a8f34) can draw something on Android desktop with surface flinger correctly, I try to get raw data from SkBitmap and post to ISurface (by modifying the surfaceflinger sink).

My modification is as following (the blue part):
------------------
bitmap.lockPixels();
memcpy (static_cast<unsigned char *>(videodev->frame_heap->base()) + videodev->frame_offset[videodev->buf_index],  bitmap.getPixels(), bitmap.getSize());
bitmap.unlockPixels(); 
videodev->isurface->postBuffer(videodev->frame_offset[videodev->buf_index]);
------------------ 
I can see a doted line shown, but they are not my expectation (some rectangles and the text "Hello, World").
Does bitmap.getPixels() get the bitmap raw data (in ARGB)?
Or, how can I get the raw data?

France


Hsu France

unread,
Jan 19, 2012, 3:58:23 AM1/19/12
to skia-d...@googlegroups.com
My modification is as the attached pictures.
IMG_0537.JPG
IMG_0538.JPG

Derek

unread,
Jan 19, 2012, 8:55:20 AM1/19/12
to skia-d...@googlegroups.com
One problem you are probably experiencing is that the Android font code in Skia's trunk has been updated to work with their new font system in Android 4.0 (IceCreamSandwich). This change is not backwards compatible with previous versions of Android.  Therefore, at a minimum, to draw fonts on Froyo using Skia's trunk you will need to use an older version of SkFontHost_android.cpp that interacts with the old android font system pre-ICS.  Alternatively, you can roll back Skia's trunk to a revision that uses the old font system and give that a go

Hsu France

unread,
Feb 8, 2012, 11:16:55 PM2/8/12
to skia-d...@googlegroups.com
Sorry for late reply.

Our Skia version matches the Android we used (Froyo).
Since job rearrangement, I stop to find the solution on using Skia APIs.

But I have another idea about this problem.
Is it better that the gstreamer subtitle sink sends the text to APP, and APP draws the text out?
(Originally, we wish that the gstreamer subtitle sink can use Skia APIs to draw text out directly.)
(The gstreamer player is a media player service called by media framework)

France

Hsu France

unread,
Feb 22, 2012, 9:38:22 PM2/22/12
to skia-d...@googlegroups.com
Hi!

I'm going back to the road of using skia to render text.
Based on the surfaceflingersink project, I add a text code to draw something with skia, and post to android surface:
------------------------------
SkBitmap bitmap;
bitmap.setConfig(SkBitmap::kRGB_565_Config, 320, 320);

bitmap.allocPixels();

SkCanvas canvas(new SkDevice(bitmap));

SkPaint paint;
paint.setARGB(255, 255, 0, 0);
paint.setStyle (SkPaint::kFill_Style);

SkRect r;
r.set(25, 25, 145, 145);
canvas.drawRect(r, paint);

if (++videodev->buf_index == MAX_FRAME_BUFFERS)  videodev->buf_index = 0;

memcpy ( static_cast<unsigned char *>(videodev->frame_heap->base()) + videodev->frame_offset[videodev->buf_index], bitmap.getPixels(), bitmap.getSize());
videodev->isurface->postBuffer(videodev->frame_offset[videodev->buf_index]);
------------------------------------

Some strange blue dots appeared, not my expected red rectangle.
I add the code to save the bitmap ito png file:
------------------------------------
SkImageEncoder::EncodeFile("/media/snapshot.png", bitmap, SkImageEncoder::kPNG_Type, 100);
------------------------------------
The png file is correctly displayed.

Is bitmap.getPixels() the correct method to get the bitmap raw data?

Another question is, does the surface config affect the final output?
------------------------------------
videodev->surface = videoClient->createSurface (pid, 0, width, height, PIXEL_FORMAT_RGB_565, 0x00000200 | 0x00000000); //SurfaceComposer::ePushBuffers || ISurfaceComposer::eFXSurfaceNormal
------------------------------------

I've changed the config of surface and bitmap both to PIXEL_FORMAT_RGBA_8888 and kARGB_8888_Config, but the output is  still wrong, only the bg color of png becomes white from black.

Joe Droider

unread,
Dec 5, 2013, 12:27:11 AM12/5/13
to skia-d...@googlegroups.com
Hi
I am looking for a similar solution. I have a native OpenGL app. I want to render text. Trying to do this using GL seems pretty cumbersome.
I like to use Skia for text rendering and draw the canvas on  EGL surface.

I am wondering if you were able to find a solution to your problem.

Derek Sollenberger

unread,
Dec 5, 2013, 8:33:01 AM12/5/13
to skia-d...@googlegroups.com
If you are drawing on devices that are newer than Android 4.0 then Skia should work for that without any special modifications.  If you need to draw text on older devices then it can still work as long as you provide the font to get the data from.  The requirement for 4.0 and newer is because on older devices we don't have support for finding the system font files in our code base anymore.


--
You received this message because you are subscribed to the Google Groups "skia-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to skia-discuss...@googlegroups.com.

To post to this group, send email to skia-d...@googlegroups.com.

Ngoc Dao

unread,
Dec 9, 2013, 2:18:01 AM12/9/13
to skia-d...@googlegroups.com
Can you give a code snippet example that shows how to "provide the font to get the data from"?
Thanks.

Derek Sollenberger

unread,
Dec 9, 2013, 8:49:12 AM12/9/13
to skia-d...@googlegroups.com
Look at SkTypeface.h.  The simplest snippet I can give is...

SkTypeface* tf = SkTypeface::CreateFromFile("/my/font/file.ttf");
SkPaint p;
p.setTypeface(tf);

Mike Reed

unread,
Dec 9, 2013, 8:50:33 AM12/9/13
to skia-d...@googlegroups.com
be sure to unref tf when you're done with it.
Reply all
Reply to author
Forward
0 new messages