can't render text in cairo - cairo

I am new to cairo and I have read the tutorials/documentation on its website.
Now I can make lines, rectangles, and basically I can render images but not text.
I am using the following code
cairo_select_font_face (cr, "monospace", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAl);
cairo_set_font_size (cr, 14);
cairo_set_source_rgb (cr, 1, 1, 1);
cairo_move_to (cr, 50, 50);
cairo_show_text (cr, "Print Something");
Can anyone please point to my mistake?

Same answer as on the cairo mailing list (where it seems to have been lost somewhere):
You aren't doing anything wrong (well, perhaps using the toy text API, but that should still work) and your code works fine for me. Here is the full code that I tested with:
#include <cairo.h>
int main()
{
cairo_surface_t *surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 200, 200);
cairo_t *cr = cairo_create(surface);
cairo_surface_destroy(surface);
/* Fill everything with white */
cairo_set_source_rgb(cr, 1, 1, 1);
cairo_paint(cr);
/* Draw some text */
cairo_select_font_face (cr, "monospace", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL);
cairo_set_font_size (cr, 14);
cairo_set_source_rgb (cr, 0, 0, 0);
cairo_move_to (cr, 0, 50);
cairo_show_text (cr, "Print Something");
cairo_surface_write_to_png(cairo_get_target(cr), "out.png");
cairo_destroy(cr);
return 0;
}

Related

Running SDL/OpenGLES application on a specific DISPLAY in XServer

I am trying to port an application to an embedded system that I am trying to design. The embedded system is Raspberry Pi Zero W - based, and uses a custom Yocto build.
The application to be ported is written with SDL / OpenGLES to my understanding. I have a hard time understanding how to make a connection similar to the following depiction:
SDL APP -----> XServer ($DISPLAY) -------> Framebuffer /dev/fb1 ($FRAMEBUFFER)
System has two displays: One HDMI on /dev/fb0 and One TFT on /dev/fb1. I am trying to run the SDL application on TFT. The following are the steps I do:
First, start an XServer on DISPLAY=:1 that is connected to /dev/fb1:
FRAMEBUFFER=/dev/fb1 xinit /etc/X11/Xsession -- /usr/bin/Xorg :1 -br -pn -nolisten tcp -dpi 100
The first step seems like it's working. I can see LXDE booting up on my TFT screen. Checking the display, I get the correct display resolution:
~/projects# DISPLAY=:1 xrandr -q
xrandr: Failed to get size of gamma for output default
Screen 0: minimum 320 x 240, current 320 x 240, maximum 320 x 240
default connected 320x240+0+0 0mm x 0mm
320x240 0.00*
Second, I would like to start SDL-written application using x11. I am thinking that should work in seeing the application on the TFT. In order to do so, I try:
SDL_VIDEODRIVER=x11 SDL_WINDOWID=1 DISPLAY=:1 ./SDL_App
No matter which display number I choose, it starts on my HDMI display and not on the TFT. So now I am thinking the person who wrote the application hardcoded somethings in the application code:
void init_ogl(void)
{
int32_t success = 0;
EGLBoolean result;
EGLint num_config;
static EGL_DISPMANX_WINDOW_T nativewindow;
DISPMANX_ELEMENT_HANDLE_T dispman_element;
DISPMANX_DISPLAY_HANDLE_T dispman_display;
DISPMANX_UPDATE_HANDLE_T dispman_update;
VC_DISPMANX_ALPHA_T alpha;
VC_RECT_T dst_rect;
VC_RECT_T src_rect;
static const EGLint attribute_list[] =
{
EGL_RED_SIZE, 8,
EGL_GREEN_SIZE, 8,
EGL_BLUE_SIZE, 8,
EGL_ALPHA_SIZE, 8,
EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
EGL_NONE
};
EGLConfig config;
// Get an EGL display connection
display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
assert(display!=EGL_NO_DISPLAY);
// Initialize the EGL display connection
result = eglInitialize(display, NULL, NULL);
assert(EGL_FALSE != result);
// Get an appropriate EGL frame buffer configuration
result = eglChooseConfig(display, attribute_list, &config, 1, &num_config);
assert(EGL_FALSE != result);
// Create an EGL rendering context
context = eglCreateContext(display, config, EGL_NO_CONTEXT, NULL);
assert(context!=EGL_NO_CONTEXT);
// Create an EGL window surface
success = graphics_get_display_size( 0 /* LCD */ , &screen_width, &screen_height);
printf ("Screen width= %d\n", screen_width);
printf ("Screen height= %d\n", screen_height);
assert( success >= 0 );
int32_t zoom = screen_width / GAMEBOY_WIDTH;
int32_t zoom2 = screen_height / GAMEBOY_HEIGHT;
if (zoom2 < zoom)
zoom = zoom2;
int32_t display_width = GAMEBOY_WIDTH * zoom;
int32_t display_height = GAMEBOY_HEIGHT * zoom;
int32_t display_offset_x = (screen_width / 2) - (display_width / 2);
int32_t display_offset_y = (screen_height / 2) - (display_height / 2);
dst_rect.x = 0;
dst_rect.y = 0;
dst_rect.width = screen_width;
dst_rect.height = screen_height;
src_rect.x = 0;
src_rect.y = 0;
src_rect.width = screen_width << 16;
src_rect.height = screen_height << 16;
dispman_display = vc_dispmanx_display_open( 0 /* LCD */ );
dispman_update = vc_dispmanx_update_start( 0 );
alpha.flags = DISPMANX_FLAGS_ALPHA_FIXED_ALL_PIXELS;
alpha.opacity = 255;
alpha.mask = 0;
dispman_element = vc_dispmanx_element_add ( dispman_update, dispman_display,
0/*layer*/, &dst_rect, 0/*src*/,
&src_rect, DISPMANX_PROTECTION_NONE, &alpha, 0/*clamp*/, DISPMANX_NO_ROTATE/*transform*/);
nativewindow.element = dispman_element;
nativewindow.width = screen_width;
nativewindow.height = screen_height;
vc_dispmanx_update_submit_sync( dispman_update );
surface = eglCreateWindowSurface( display, config, &nativewindow, NULL );
assert(surface != EGL_NO_SURFACE);
// Connect the context to the surface
result = eglMakeCurrent(display, surface, surface, context);
assert(EGL_FALSE != result);
eglSwapInterval(display, 1);
glGenTextures(1, &theGBTexture);
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, theGBTexture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, (GLvoid*) NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrthof(0.0f, screen_width, screen_height, 0.0f, -1.0f, 1.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glViewport(0.0f, 0.0f, screen_width, screen_height);
quadVerts[0] = display_offset_x;
quadVerts[1] = display_offset_y;
quadVerts[2] = display_offset_x + display_width;
quadVerts[3] = display_offset_y;
quadVerts[4] = display_offset_x + display_width;
quadVerts[5] = display_offset_y + display_height;
quadVerts[6] = display_offset_x;
quadVerts[7] = display_offset_y + display_height;
glVertexPointer(2, GL_SHORT, 0, quadVerts);
glEnableClientState(GL_VERTEX_ARRAY);
glTexCoordPointer(2, GL_FLOAT, 0, kQuadTex);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glClear(GL_COLOR_BUFFER_BIT);
}
void init_sdl(void)
{
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_GAMECONTROLLER) < 0)
{
Log("SDL Error Init: %s", SDL_GetError());
}
theWindow = SDL_CreateWindow("Gearboy", 0, 0, 0, 0, 0);
if (theWindow == NULL)
{
Log("SDL Error Video: %s", SDL_GetError());
}
...
}
At first glance, I discovered two lines: vc_dispmanx_display_open( 0 /* LCD */ ); and graphics_get_display_size( 0 /* LCD */ , &screen_width, &screen_height);. I tried changing the display parameter to 1, thinking that it refers to DISPLAY=:1, but it did not do anything. I added logs for screen resolution, and I get 1920x1080, which is the resolution of the HDMI display. I think there must be something with the EGL portion of the code that I'm missing. What should I do right now? Is my logic fair enough or am I missing something?
Any requirements, please let me know. Any guidance regarding the issue is much appreciated.
EDIT: I saw that some people use the following, but raspberry pi zero can not find EGL/eglvivante.h for fb functions so I am unable to compile it:
int fbnum = 1; // fbnum is an integer for /dev/fb1 fbnum = 1
EGLNativeDisplayType native_display = fbGetDisplayByIndex(fbnum);
EGLNativeWindowType native_window = fbCreateWindow(native_display, 0, 0, 0, 0);
display = eglGetDisplay(native_display);

Using textscan in Matlab to handle data not properly formatted data

I'm using textscan to import data. I can get to it successfully import properly formatted data. I can't get it to properly handle data that isn't properly formatted. Below is the format of the data.
JeB2021Da 12-13 and stuff, 1, 1, 0, 1, 0, 1, 1, 1, 3, 1, 99, 0, 0, 0,
JoB2021Ha 12-13 and stuff, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 99, 2, 1, 0,
JoP2021Co 12-13 and stuff, not enough samples
MaA2021Be 12-13 and stuff, 1, 1, 0, 0, 0, 1, 1, 0, 1, 0, 99, 1, 0, 0,
MaA2021Ma 12-13 and stuff, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 99, 1, 0, 0,
How would I handle the data that is, not enough samples? Because currently the data structures don't line up. The data structures that are being produced are 17 x 1 and 16 x 14. I'd like to import the string as it is in the data. So not enough samples would be imported. Below is the code that I'm using.
fid = fopen('./file.txt','r');
fmt = ['%s %d %d %d %d %d %d %d %d %d %d %d %d %d %d'];
d = textscan(fid, fmt, 'CollectOutput', 1,'Delimiter',',','headerLines', 1, 'EmptyValue', 0);
I'm trying to handle it with the EmptyValue flag but it's not working. Any help is greatly appreciated.
I am not sure what exactly you mean by I'd like to import the string as it is in the data, or more exactly where you would like to have that string stored.
But about just reading your data as a whole you can use the 'TreatAsEmpty' argument:
d = textscan(fid, fmt, 'CollectOutput', 1,'Delimiter',',','headerLines', 1,'TreatAsEmpty','not enough samples');
Then you can modify the input further by looking for the rows in the imported data array that solely consist of zeros.

GTK3 - Create image object from stock

I want to create a grid which displays error message if the file does not exist:
/* size */
s = get_file_size(recording->filename);
if (s > 0) {
size = g_format_size_full(s, G_FORMAT_SIZE_LONG_FORMAT);
gtk_label_set_text(GTK_LABEL(size_lbl), size);
gtk_widget_hide(error)
g_free(size);
} else {
size = g_strdup(_("Import Errors"));
gtk_widget_show(error)
}
in gtk grid cannot set type of "error" element to display message as in screen shot:
grid = gtk_grid_new();
gtk_grid_set_row_spacing(GTK_GRID(grid), 6);
gtk_grid_set_column_spacing(GTK_GRID(grid), 15);
gtk_container_set_border_width(GTK_CONTAINER(grid), 6);
s_lbl = gtk_label_new(Size:);
size_lbl = gtk_label_new("");
error = ?
error_pixmap = gtk_image_new_from_stock(GTK_STOCK_DIALOG_ERROR, GTK_ICON_SIZE_SMALL_TOOLBAR);
gtk_container_add(GTK_CONTAINER(error), error_pixmap);
gtk_grid_attach(GTK_GRID(grid), s_lbl, 0, 0, 1, 1);
gtk_grid_attach(GTK_GRID(grid), error, 1, 0, 1, 1);
gtk_grid_attach(GTK_GRID(grid), size_lbl, 2, 0, 1, 1);
For any help, thanks.
Screen shot:
[Size]:
Use a GtkBox with GTK_ORIENTATION_HORIZONTAL, or an adjoining cell in the GtkGrid.

glDrawElements VAO/VBO crash on iOS

I am creating a batching class that uses VAOs and VBOs to manage meshes. However, when attempting to use glDrawElements, I get EXEC_BAD_ACCESS and GL_INVALID_OPERATION when binding back to my VAO. Here is the code:
glGenVertexArraysOES(1, &arrayID);
glBindVertexArrayOES(arrayID); // Bind INTO VAO, opening state
// Load shaders and textures and bind them using glUseProgram etc.
glGenBuffers(1, &vboID);
glBindBuffer(GL_ARRAY_BUFFER, vboID);
glGenBuffers(1, &indexID);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexID);
glBindVertexArrayOES(0); // Bind AWAY from VAO, saving state
Glfloat data[length];
glBindVertexArrayOES(arrayID); // Bind INTO VAO, open state
unsigned int glfloatsize = sizeof(GLfloat);
unsigned int stride = kStride * glfloatsize;
// Fill Vertex information
glBufferData(GL_ARRAY_BUFFER, vertCount * glfloatsize * kStride, NULL, GL_STATIC_DRAW);
glBufferSubData(GL_ARRAY_BUFFER, 0, vertCount * glfloatsize * kStride, data);
glEnableVertexAttribArray(kPositionLocation);
glVertexAttribPointer(kPositionLocation, 3, GL_FLOAT, GL_FALSE, stride, BUFFER_OFFSET(0));
glEnableVertexAttribArray(kNormalLocation);
glVertexAttribPointer(kNormalLocation, 3, GL_FLOAT, GL_FALSE, stride, BUFFER_OFFSET(3));
glEnableVertexAttribArray(kColorLocation);
glVertexAttribPointer(kColorLocation, 4, GL_FLOAT, GL_FALSE, stride, BUFFER_OFFSET(6));
glClientActiveTexture(GL_TEXTURE0);
glEnableVertexAttribArray(kTextureLocation);
glVertexAttribPointer(kTextureLocation, 2, GL_FLOAT, GL_FALSE, stride, BUFFER_OFFSET(10));
// Fill Index information
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indexCount * sizeof(GLushort), NULL, GL_STATIC_DRAW);
glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, indexCount * sizeof(GLushort), index);
glBindVertexArrayOES(0); // Bind AWAY from VAO, saving state
// DO OTHER STUFF
/** RENDER (EXPLODES WITH EXEC_BAD_ACCESS) **/
glBindVertexArrayOES(arrayID);
glDrawElements(renderMode, indexCount, GL_UNSIGNED_SHORT, 0);
glBindVertexArrayOES(0);
/** RENDER (WORKS CORRECTLY [index is a scoped array of GLushorts that are uploaded to the VBO above...]) **/
glBindVertexArrayOES(arrayID);
glDrawElements(renderMode, indexCount, GL_UNSIGNED_SHORT, index);
glBindVertexArrayOES(0);
Any idea why I am receiving EXEC_BAD_ACCESS when attempting to use a GL_ELEMENT_ARRAY_BUFFER VBO?
Are you sure that following statements are true?
all OpenGL function doesn't set error - call glGetError after EACH of glXYZ function and check the result.
kStride >= 24
length == vertCount * kStride
index array has indexCount elements with GLushort type
all elements of index array has value less than vertCount value
there are no other glEnableVertexAttribArray calls

Postive/Negative Chart in Google Visualization API

I need to generate a chart like this one:
Specifically, I want to show both a positive value and a negative value for a time period (could be an hour, minute, etc.) and display it like this.
I could have sworn I saw something like this on the Google Visualization API Gallery the other day, but I can't find it now, and am not even sure what this kind of chart is called.
First, do you know what this kind of chart is called so I can possibly find documentation? Second, is there any way to implement such a chart with the Google Visualization API? If not, is there another common charting solution for web that I can achieve this with?
Thank you for your time.
This is called a "Stacked Bar Chart", and can indeed be created with the Google Visualisation API.
Simply use the "isStacked" property (described here; http://code.google.com/apis/visualization/documentation/gallery/barchart.html).
Here's some sample code (based off the default bar chart example provided by Google and updated to show the use of isStacked and some sample data from your example);
function drawVisualization() {
var data = new google.visualization.DataTable();
data.addColumn('string', 'Month');
data.addColumn('number');
data.addColumn('number');
data.addRows(12);
data.setCell(0, 0, 'January');
data.setCell(1, 0, 'February');
data.setCell(2, 0, 'March');
data.setCell(3, 0, 'April');
data.setCell(4, 0, 'May');
data.setCell(5, 0, 'June');
data.setCell(6, 0, 'July');
data.setCell(7, 0, 'August');
data.setCell(8, 0, 'September');
data.setCell(9, 0, 'October');
data.setCell(10, 0, 'November');
data.setCell(11, 0, 'December');
data.setCell(0, 1, 19);
data.setCell(1, 1, 18);
data.setCell(2, 1, 20);
data.setCell(3, 1, 19);
data.setCell(4, 1, 18);
data.setCell(5, 1, 20);
data.setCell(6, 1, 19);
data.setCell(7, 1, 18);
data.setCell(8, 1, 20);
data.setCell(9, 1, 19);
data.setCell(10, 1, 18);
data.setCell(11, 1, 20);
data.setCell(0, 2, -12);
data.setCell(1, 2, -13);
data.setCell(2, 2, -11);
data.setCell(3, 2, -12);
data.setCell(4, 2, -13);
data.setCell(5, 2, -11);
data.setCell(6, 2, -12);
data.setCell(7, 2, -13);
data.setCell(8, 2, -11);
data.setCell(9, 2, -12);
data.setCell(10, 2, -13);
data.setCell(11, 2, -11);
data.setCell(0, 2, -12);
data.setCell(1, 2, -13);
data.setCell(2, 2, -11);
// Create and draw the visualization.
new google.visualization.ColumnChart(document.getElementById('visualization')).
draw(data,
{title:"S&P 500 Up/Down Performance Since 1980",
width:600, height:400,
isStacked:"true",
legend:"none" }
);
}
And the results...
Use ColumnChart instead of BarChart:
var chart = new google.visualization.ColumnChart(document.getElementById('chart_div'));
https://jsfiddle.net/0rrar9oq/16