/* * Function : libaroma_font * Return Value: byte * Descriptions: load new font */ byte libaroma_font( byte fontid, LIBAROMA_STREAMP stream) { if (!stream) { ALOGW("libaroma_font stream not found"); return 0; } if (fontid >= _LIBAROMA_FONT_MAX_FACE) { ALOGW("libaroma_font fontid(%i)>=%i", fontid, _LIBAROMA_FONT_MAX_FACE); return 0; } /* thread safe */ _libaroma_font_lock(1); /* load face */ FT_Face tmp_face; if (FT_New_Memory_Face(_libaroma_font_instance, stream->data, stream->size, 0, &tmp_face) == 0) { /* set default face size */ int def_size = libaroma_font_size_px(2); if (FT_Set_Pixel_Sizes(tmp_face, 0, def_size) == 0) { /* save it */ libaroma_font_free(fontid); _libaroma_font_faces[fontid].size = def_size; _libaroma_font_faces[fontid].id = fontid; _libaroma_font_faces[fontid].face = tmp_face; _libaroma_font_faces[fontid].stream = stream; _libaroma_font_faces[fontid].cache = libaroma_iarray(libaroma_font_freecache_cb); /* force ucs2 */ libaroma_font_set_ucs2(_libaroma_font_faces[fontid].face); /* init harfbuzz */ _libaroma_font_hb_init(fontid); /* unlock */ _libaroma_font_lock(0); ALOGV("font loaded %ibytes (%s)", stream->size, stream->uri); return 1; } else { ALOGW("libaroma_font libaroma_font_set_size error"); FT_Done_Face(tmp_face); } } else { ALOGW("libaroma_font FT_New_Memory_Face Error"); libaroma_stream_close(stream); } _libaroma_font_lock(0); return 0; } /* End of libaroma_font */
/* * Function : libaroma_font_free * Return Value: byte * Descriptions: free loaded font */ byte libaroma_font_free( byte fontid) { if (fontid >= _LIBAROMA_FONT_MAX_FACE) { ALOGW("libaroma_font_free fontid(%i)>=%i", fontid, _LIBAROMA_FONT_MAX_FACE); return 0; } _libaroma_font_lock(1); #ifndef LIBAROMA_CONFIG_TEXT_NOHARFBUZZ /* Free Harfbuzz Font */ if (_libaroma_font_faces[fontid].hb_font != NULL) { _libaroma_font_hb_free(fontid); _libaroma_font_faces[fontid].hb_font = NULL; } #endif /* Free Freetype Font Face */ if (_libaroma_font_faces[fontid].face != NULL) { FT_Done_Face(_libaroma_font_faces[fontid].face); _libaroma_font_faces[fontid].face = NULL; } /* Free Cache */ if (_libaroma_font_faces[fontid].cache != NULL) { libaroma_iarray_free(_libaroma_font_faces[fontid].cache); _libaroma_font_faces[fontid].cache = NULL; } /* Free Stream */ if (_libaroma_font_faces[fontid].stream != NULL) { libaroma_stream_close(_libaroma_font_faces[fontid].stream); _libaroma_font_faces[fontid].stream = NULL; } _libaroma_font_lock(0); return 1; } /* End of libaroma_font_free */
LIBAROMA_CANVASP libaroma_svg_ex( LIBAROMA_STREAMP stream, byte freeStream, byte use_px) { LIBAROMA_CANVASP cv = NULL; if (!stream) { return NULL; } char * data = libaroma_stream_to_string(stream,0); if (data){ NSVGimage *image = NULL; if (!use_px){ image=nsvgParse(data, "dp", ((float) libaroma_fb()->dpi)); } else{ image=nsvgParse(data, "px", ((float) libaroma_fb()->dpi)); } free(data); if (image == NULL) { ALOGW("libaroma_svg: Could not open SVG image."); goto exit; } NSVGrasterizer *rast =nsvgCreateRasterizer(); if (rast == NULL) { printf("libaroma_svg: Could not init rasterizer."); nsvgDelete(image); goto exit; } if (!use_px){ cv = libaroma_canvas_ex(libaroma_dp(image->width),libaroma_dp(image->height),1); } else{ cv = libaroma_canvas_ex(image->width,image->height,1); } libaroma_canvas_setcolor(cv,0,0); nsvgRasterize(rast,image,0,0,1,cv); nsvgDelete(image); nsvgDeleteRasterizer(rast); } exit: if (freeStream) { libaroma_stream_close(stream); } return cv; }
/* * Function : libaroma_stream_to_string * Return Value: char * * Descriptions: convert stream to string */ char * libaroma_stream_to_string( LIBAROMA_STREAMP a, byte free) { if (!a) { return NULL; } char * txt = malloc(a->size + 1); memcpy(txt, a->data, a->size); txt[a->size] = 0; if (free) { libaroma_stream_close(a); } return txt; } /* End of libaroma_stream_to_string */
/* * Function : libaroma_png_ex * Return Value: LIBAROMA_CANVASP * Descriptions: read png - extended */ LIBAROMA_CANVASP libaroma_png_ex( LIBAROMA_STREAMP stream, byte freeStream, byte hicolor) { if (!stream) { return NULL; } /* init adapter */ _LIBAROMA_PNG_ADAPTERP adapter = (_LIBAROMA_PNG_ADAPTERP) malloc(sizeof(_LIBAROMA_PNG_ADAPTER)); if (!adapter) { if (freeStream){ libaroma_stream_close(stream); } ALOGW("libaroma_png_ex cannot allocating adapter"); return NULL; } adapter->data = stream->data; adapter->n = stream->size; adapter->p = 0; /* png structures */ png_structp png_ptr = NULL; png_infop info_ptr = NULL; volatile LIBAROMA_CANVASP cv = NULL; byte header[8]; /* headers */ memcpy(header, adapter->data, sizeof(header)); adapter->p += sizeof(header); /* compare signature */ if (png_sig_cmp(header, 0, sizeof(header))) { ALOGW("libaroma_png_ex signature error"); goto exit; } /* read structure */ png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if (!png_ptr) { ALOGW("libaroma_png_ex png_ptr is invalid"); goto exit; } /* info structure */ info_ptr = png_create_info_struct(png_ptr); if (!info_ptr) { ALOGW("libaroma_png_ex info_ptr is invalid"); goto exit; } /* jmp */ if (setjmp(png_jmpbuf(png_ptr))) { ALOGW("libaroma_png_ex jmp error"); goto exit; } /* callback */ png_set_read_fn(png_ptr, adapter, _libaroma_png_reader); png_set_sig_bytes(png_ptr, sizeof(header)); png_read_info(png_ptr, info_ptr); /* check color */ int bit_depth = png_get_bit_depth(png_ptr, info_ptr); int color_type = png_get_color_type(png_ptr, info_ptr); int channels = png_get_channels(png_ptr, info_ptr); if ((color_type == PNG_COLOR_TYPE_GRAY)|| (color_type == PNG_COLOR_TYPE_GRAY_ALPHA)){ png_set_gray_to_rgb(png_ptr); png_read_update_info(png_ptr, info_ptr); } else if (color_type == PNG_COLOR_TYPE_PALETTE) { png_set_palette_to_rgb(png_ptr); png_read_update_info(png_ptr, info_ptr); } else if (!((bit_depth == 8 && ( (channels == 3 && color_type == PNG_COLOR_TYPE_RGB) || (channels == 4 && color_type == PNG_COLOR_TYPE_RGBA) )) || (channels == 1 && color_type == PNG_COLOR_TYPE_PALETTE) )) { ALOGW("libaroma_png_ex mode not supported (c:%i, t:%i, d:%i)", channels, color_type, bit_depth); goto exit; } /* init main info */ int pcv_w = png_get_image_width(png_ptr, info_ptr); int pcv_h = png_get_image_height(png_ptr, info_ptr); int pcv_c = png_get_channels(png_ptr, info_ptr); /* verbose */ ALOGV("load png \"%s\" (%ix%ix%i)", stream->uri, pcv_w, pcv_h, pcv_c); /* new canvas */ cv = libaroma_canvas_new( pcv_w, pcv_h, (pcv_c==4)?1:0, hicolor); if (!cv) { ALOGW("libaroma_png_ex cannot create canvas"); goto exit; } /* switch to abgr */ if (pcv_c == 4) { png_set_bgr(png_ptr); } /* read row size*/ int row_sz = (int) png_get_rowbytes(png_ptr, info_ptr); /* loop */ int y, x; if (pcv_c == 4) { int z; png_bytep row_data = (png_bytep) malloc(row_sz); if (hicolor) { for (y = 0; y < pcv_h; ++y) { int ypos = (y * cv->l); wordp line = cv->data + ypos; bytep alph = cv->alpha + ypos; bytep hicl = cv->hicolor + ypos; png_read_row(png_ptr, row_data, NULL); for (x = 0, z = pcv_w * pcv_c; x < z; x += 4) { *line++ = libaroma_rgb( row_data[x + 2], row_data[x + 1], row_data[x]); *hicl++ = libaroma_color_left( row_data[x + 2], row_data[x + 1], row_data[x]); *alph++ = row_data[x + 3]; } } } else { for (y = 0; y < pcv_h; ++y) { int ypos = (y * cv->l); wordp line = cv->data + ypos; bytep alph = cv->alpha + ypos; png_read_row(png_ptr, row_data, NULL); libaroma_dither_line(y, pcv_w, line, (dwordp) row_data); for (x = 0, z = pcv_w * pcv_c; x < z; x += 4) { *alph++ = row_data[x + 3]; } } } free(row_data); } else if (pcv_c == 3) { int z; png_bytep row_data = (png_bytep) malloc(row_sz); if (hicolor) { for (y = 0; y < pcv_h; ++y) { wordp line = cv->data + (y * cv->l); bytep hicl = cv->hicolor + (y * cv->l); png_read_row(png_ptr, row_data, NULL); for (x = 0, z = pcv_w * pcv_c; x < z; x += 3) { *line++ = libaroma_rgb(row_data[x], row_data[x + 1], row_data[x + 2]); *hicl++ = libaroma_color_left( row_data[x + 2], row_data[x + 1], row_data[x]); } } } else { for (y = 0; y < pcv_h; ++y) { wordp line = cv->data + (y * cv->l); png_read_row(png_ptr, row_data, NULL); libaroma_dither_24to16(y, pcv_w, line, row_data); /* for (x = 0, z = pcv_w * pcv_c; x < z; x += 3) { *line++ = libaroma_dither_rgb( x, y, row_data[x + 2], row_data[x + 1], row_data[x]); }*/ } } free(row_data); } exit: png_destroy_read_struct(&png_ptr, &info_ptr, NULL); if (freeStream) { libaroma_stream_close(stream); } free(adapter); return cv; } /* End of libaroma_png_ex */