int main( ) { static char svg_buf[MAX_SVG]; ssize_t read_ret; size_t read_pos = 0; /* slurp input */ while (read_pos < MAX_SVG) { read_ret = read(STDIN_FILENO, svg_buf + read_pos, MAX_SVG - read_pos); if (read_ret < 0) { perror("read"); exit(1); } else if (read_ret == 0) { break; } else { read_pos += read_ret; } } /* create SVG frame */ RawFrame *svg = RsvgFrame::render_svg(svg_buf, read_pos); /* dump raw BGRAn8 video to stdout */ fprintf(stderr, "w=%d h=%d\n", svg->w( ), svg->h( )); svg->write_to_fd(STDOUT_FILENO); }
RawFrame *FreetypeFont::render_string(const char *string) { int x; RawFrame *ret; FT_GlyphSlot slot = face->glyph; FT_Bool use_kerning = FT_HAS_KERNING(face); FT_UInt glyph_index, previous; uint8_t *glyph_scanline; x = 0; previous = 0; /* first compute the size of the resulting image */ const char *scan_ptr = string; while (*scan_ptr != '\0') { glyph_index = FT_Get_Char_Index(face, *scan_ptr); scan_ptr++; if (use_kerning && previous != 0 && glyph_index != 0) { FT_Vector delta; FT_Get_Kerning(face, previous, glyph_index, FT_KERNING_DEFAULT, &delta); x += delta.x / 64; } FTCHK(FT_Load_Glyph(face, glyph_index, FT_LOAD_DEFAULT)); x += slot->advance.x / 64; previous = glyph_index; } /* initialize a raw frame */ ret = new RawFrame(x, _h, RawFrame::BGRAn8); /* second pass: draw it */ scan_ptr = string; int xd = 0; previous = 0; uint8_t *dest_scanline = ret->data( ); for (unsigned int i = 0; i < ret->size( ); i += 4) { dest_scanline[i] = bb; dest_scanline[i+1] = gb; dest_scanline[i+2] = rb; dest_scanline[i+3] = ab; } while (*scan_ptr != '\0') { glyph_index = FT_Get_Char_Index(face, *scan_ptr); scan_ptr++; if (use_kerning && previous != 0 && glyph_index != 0) { FT_Vector delta; FT_Get_Kerning(face, previous, glyph_index, FT_KERNING_DEFAULT, &delta); xd += delta.x / 64; } FTCHK(FT_Load_Glyph(face, glyph_index, FT_LOAD_RENDER)); //int yd = -(slot->bitmap_top); int yd = _baseline - slot->bitmap_top; for (unsigned int y = 0; y < slot->bitmap.rows && yd < _h; y++, yd++) { if (yd >= 0) { glyph_scanline = ((uint8_t *)slot->bitmap.buffer) + slot->bitmap.pitch * y; dest_scanline = ret->scanline(yd) + 4*xd; int xd2 = xd; for (unsigned int x = 0; x < slot->bitmap.width && xd2 < ret->w( ); x++, xd2++) { dest_scanline[0] = (bf * glyph_scanline[x] + bb * (255 - glyph_scanline[x])) / 255; dest_scanline[1] = (gf * glyph_scanline[x] + gb * (255 - glyph_scanline[x])) / 255; dest_scanline[2] = (rf * glyph_scanline[x] + rb * (255 - glyph_scanline[x])) / 255; dest_scanline[3] = (af * glyph_scanline[x] + ab * (255 - glyph_scanline[x])) / 255; dest_scanline += 4; } } } xd += slot->advance.x / 64; previous = glyph_index; } return ret; }