#include "stdafx.h" #include "newfont.h" /* class's property: font_glyph_t *glyphs;//store the glyphs class's function: newFont();//constructer ~newFont();//disconstructer cairo_status_t test_draw (cairo_font_face_t *font_face,cairo_t *cr,const char text[]);//draw text in font_face cairo_status_t test_user_font_face_create (cairo_font_face_t **out,list temp_glyphs);//define font_face according to temp_glyphs */ static cairo_user_data_key_t newfont_face_glyphs_key; newFont::newFont() { this->glyphs=NULL; } newFont::~newFont() { if (this->glyphs==NULL) { delete this->glyphs; } } static cairo_status_t newfont_scaled_font_init (cairo_scaled_font_t *scaled_font, cairo_t *cr, cairo_font_extents_t *metrics) { metrics->ascent = .75; metrics->descent = .25; return CAIRO_STATUS_SUCCESS; } static cairo_status_t newfont_scaled_font_unicode_to_glyph (cairo_scaled_font_t *scaled_font, unsigned long unicode, unsigned long *glyph) { font_glyph_t *glyphs = (font_glyph_t *)cairo_font_face_get_user_data (cairo_scaled_font_get_font_face (scaled_font), &newfont_face_glyphs_key); int i; for (i = 0; glyphs[i].ucs4 !=(unsigned long)(-1); i++) { if (glyphs[i].ucs4 == unicode) { *glyph = i; return CAIRO_STATUS_SUCCESS; } else { continue; } } /* Not found. Default to glyph 0 */ return CAIRO_STATUS_SUCCESS; } static cairo_status_t newfont_scaled_font_render_glyph (cairo_scaled_font_t *scaled_font, unsigned long glyph, cairo_t *cr, cairo_text_extents_t *metrics) { font_glyph_t *glyphs = (font_glyph_t *)cairo_font_face_get_user_data (cairo_scaled_font_get_font_face (scaled_font), &newfont_face_glyphs_key); list onefontdata; metrics->x_advance = glyphs[glyph].width / 4.0; //onefontdata store the glyphs of one unicode onefontdata = glyphs[glyph].datas; list::iterator iter_onefont=onefontdata.begin(); for (; iter_onefont!=onefontdata.end(); iter_onefont++) { double curx=0,cury=0; int dx,dy,dx1,dy1,dx2,dy2,dx3,dy3; switch ((*iter_onefont).type) { case COMMAND: switch((*iter_onefont).data) { case MOVETO_4: dy=((*(--iter_onefont)).data); cairo_rel_move_to(cr,0,dy); iter_onefont++; break; case LINETO_5: dy=((*(--iter_onefont)).data); dx=((*(--iter_onefont)).data); cairo_rel_line_to(cr,dx,dy); iter_onefont++; iter_onefont++; break; case LINETO_6: dx=((*(--iter_onefont)).data); cairo_rel_line_to(cr,dx,0); iter_onefont++; break; case LINETO_7: dy=((*(--iter_onefont)).data); cairo_rel_line_to(cr,0,dy); iter_onefont++; break; case CURVETO_8: dy3=((*(--iter_onefont)).data); dx3=((*(--iter_onefont)).data); dy2=((*(--iter_onefont)).data); dx2=((*(--iter_onefont)).data); dy1=((*(--iter_onefont)).data); dx1=((*(--iter_onefont)).data); cairo_rel_curve_to(cr,dx1,dy1,dx1+dx2,dy1+dy2,dx1+dx2+dx3,dy1+dy2+dy3); iter_onefont++; iter_onefont++; iter_onefont++; iter_onefont++; iter_onefont++; iter_onefont++; break; case MOVETO_9: cairo_move_to(cr,curx,cury); break; case MOVETO_13: dy=((*(--iter_onefont)).data); dx=((*(--iter_onefont)).data); cairo_move_to(cr,dy,dx); iter_onefont++; iter_onefont++; break; case MOVETO_21: dy=((*(--iter_onefont)).data); dx=((*(--iter_onefont)).data); cairo_rel_move_to(cr,dx,dy); iter_onefont++; iter_onefont++; break; case MOVETO_22: dx=((*(--iter_onefont)).data); cairo_rel_move_to(cr,dx,0); iter_onefont++; break; case CURVETO_30: dx1=0; dy3=0; dx3=((*(--iter_onefont)).data); dy2=((*(--iter_onefont)).data); dx2=((*(--iter_onefont)).data); dy1=((*(--iter_onefont)).data); cairo_rel_curve_to(cr,dx1,dy1,dx1+dx2,dy1+dy2,dx1+dx2+dx3,dy1+dy2+dy3); iter_onefont++; iter_onefont++; iter_onefont++; iter_onefont++; break; case CURVETO_31: dy1=0; dx3=0; dy3=((*(--iter_onefont)).data); dy2=((*(--iter_onefont)).data); dx2=((*(--iter_onefont)).data); dx1=((*(--iter_onefont)).data); cairo_rel_curve_to(cr,dx1,dy1,dx1+dx2,dy1+dy2,dx1+dx2+dx3,dy1+dy2+dy3); iter_onefont++; iter_onefont++; iter_onefont++; iter_onefont++; break; case STROKE: cairo_new_sub_path (cr); break; case CLOSE: cairo_get_current_point (cr, &curx, &cury); cairo_close_path (cr); break; default: break; } } cairo_stroke (cr); } return CAIRO_STATUS_SUCCESS; } //out is font_face and temp_glyph_i is a list which store the data of glyphs cairo_status_t newFont::test_user_font_face_create (cairo_font_face_t **out,list temp_glyph_t) { //converse list(temp_glyph_t) to arry(this->glyphs) this->glyphs=new font_glyph_t[temp_glyph_t.size()]; list::iterator glyphsiter=temp_glyph_t.begin(); for (int i=0;glyphsiter!=temp_glyph_t.end();glyphsiter++,i++) { glyphs[i].ucs4=(*glyphsiter).ucs4; glyphs[i].width=(*glyphsiter).width; list datas_temp=(*glyphsiter).datas; list::iterator datas_temp_iter=datas_temp.begin(); for (;datas_temp_iter!=datas_temp.end();datas_temp_iter++) { //glyphs[i].datas=new list(); // glyphs[i].datas.clear(); glyphs[i].datas.push_back(*datas_temp_iter); } } cairo_font_face_t *user_font_face; cairo_status_t status; user_font_face = cairo_user_font_face_create (); status = cairo_font_face_set_user_data (user_font_face, &newfont_face_glyphs_key, (void*) this->glyphs, NULL); cairo_user_font_face_set_init_func (user_font_face, newfont_scaled_font_init); cairo_user_font_face_set_render_glyph_func (user_font_face, newfont_scaled_font_render_glyph); cairo_user_font_face_set_unicode_to_glyph_func (user_font_face, newfont_scaled_font_unicode_to_glyph); if (status) { cairo_font_face_destroy (user_font_face); return status; } *out = user_font_face; return CAIRO_STATUS_SUCCESS; } //text is the data which used to printf cairo_status_t newFont::test_draw (cairo_font_face_t *font_face,cairo_t *cr,const char text[]) { cairo_font_extents_t font_extents; cairo_text_extents_t extents; cairo_set_font_face(cr,font_face); cairo_set_font_size (cr, TEXT_SIZE); cairo_font_extents (cr, &font_extents); cairo_text_extents (cr, text, &extents); cairo_set_source_rgb (cr, 0, 0, 1); cairo_move_to (cr, BORDER, BORDER + font_extents.ascent); cairo_show_text (cr, text); return CAIRO_STATUS_SUCCESS ; }