int main(void) { PDF *p; int font, count; p = PDF_new(); /* open new PDF file */ if (PDF_open_file(p, "output.pdf") == -1) { fprintf(stderr, "Error: cannot open PDF file hello_c.pdf.\n"); exit(2); } PDF_set_info(p, "Creator", "hello.c"); PDF_set_info(p, "Author", "Thomas Merz"); PDF_set_info(p, "Title", "Hello, world (C)!"); font = PDF_findfont(p, "Helvetica-Bold", "host", 0); for(count = 0; count < 10000; count++){ PDF_begin_page(p, a4_width, a4_height); /* start a new page */ PDF_setfont(p, font, 24); PDF_set_text_pos(p, 10, 10); PDF_show(p, "x"); PDF_end_page(p); /* close page */ } PDF_close(p); /* close PDF document */ exit(0); }
int PDFWriter::FindFont(char* fontName, bool embed, font_encoding encoding) { static Font* cache = NULL; if (cache && cache->encoding == encoding && strcmp(cache->name.String(), fontName) == 0) return cache->font; REPORT(kDebug, fPage, "FindFont %s", fontName); Font *f = NULL; const int n = fFontCache.CountItems(); for (int i = 0; i < n; i++) { f = fFontCache.ItemAt(i); if (f->encoding == encoding && strcmp(f->name.String(), fontName) == 0) { cache = f; return f->font; } } if (embed) embed = EmbedFont(fontName); BString s; const char* encoding_name; if (encoding < user_defined_encoding_start) { encoding_name = encoding_names[encoding]; } else { s = "user"; s << (int)(encoding - user_defined_encoding_start); encoding_name = s.String(); } REPORT(kDebug, fPage, "Create new font, %sembed, encoding %s", embed ? "" : "do not ", encoding_name); int font = PDF_findfont(fPdf, fontName, encoding_name, embed); if (font != -1) { REPORT(kDebug, fPage, "font created"); cache = new Font(fontName, font, encoding); fFontCache.AddItem(cache); } else { REPORT(kError, fPage, "Could not create font '%s': %s", fontName, PDF_get_errmsg(fPdf)); } return font; }
int main(void) { PDF *p; int font; p = PDF_new(); /* open new PDF file */ if (PDF_open_file(p, "hello_c.pdf") == -1) { fprintf(stderr, "Error: cannot open PDF file hello_c.pdf.\n"); exit(2); } PDF_set_info(p, "Creator", "hello.c"); PDF_set_info(p, "Author", "Thomas Merz"); PDF_set_info(p, "Title", "Hello, world (C)!"); PDF_begin_page(p, a4_width, a4_height); /* start a new page */ font = PDF_findfont(p, "Helvetica-Bold", "default", 0); if (font == -1) { fprintf(stderr, "Couldn't set font!\n"); exit(3); } PDF_setfont(p, font, 24); PDF_set_text_pos(p, 50, 700); PDF_show(p, "Hello, world!"); PDF_continue_text(p, "(says C)"); PDF_end_page(p); /* close page */ PDF_close(p); /* close PDF document */ exit(0); }
void PDFWriter::DrawChar(uint16 unicode, const char* utf8, int16 size) { // try to convert from utf8 to MacRoman encoding schema... int32 srcLen = size; int32 destLen = 1; char dest[3] = "\0\0"; int32 state = 0; bool embed = true; font_encoding encoding = macroman_encoding; char fontName[B_FONT_FAMILY_LENGTH+B_FONT_STYLE_LENGTH+1]; if (convert_from_utf8(B_MAC_ROMAN_CONVERSION, utf8, &srcLen, dest, &destLen, &state, 0) != B_OK || dest[0] == 0) { // could not convert to MacRoman font_encoding fenc; uint16 index = 0; uint8 enc; GetFontName(&fState->beFont, fontName); embed = EmbedFont(fontName); REPORT(kDebug, -1, "find_encoding unicode %d\n", (int)unicode); if (find_encoding(unicode, enc, index)) { // is code point in the Adobe Glyph List? // Note if rendering the glyphs only would be desired, we could // always use the second method below (MakeUserDefinedEncoding), // but extracting text from the generated PDF would be almost // impossible (OCR!) REPORT(kDebug, -1, "encoding for %x -> %d %d", unicode, (int)enc, (int)index); // use one of the user pre-defined encodings if (fState->beFont.FileFormat() == B_TRUETYPE_WINDOWS) { encoding = font_encoding(enc + tt_encoding0); } else { encoding = font_encoding(enc + t1_encoding0); } *dest = index; } else if (embed) { // if the font is embedded, create a user defined encoding at runtime uint8 index; MakeUserDefinedEncoding(unicode, enc, index); *dest = index; encoding = font_encoding(user_defined_encoding_start + enc); } else if (find_in_cid_tables(unicode, fenc, index, fFontSearchOrder)) { // font is not embedded use one of the CJK fonts for substitution REPORT(kDebug, -1, "cid table %d index = %d", (int)fenc, (int)index); dest[0] = unicode / 256; dest[1] = unicode % 256; destLen = 2; encoding = fenc; embed = false; } else { static bool found = false; REPORT(kDebug, -1, "encoding for %x not found!", (int)unicode); if (!found) { found = true; REPORT(kError, fPage, "Could not find an encoding for character " "with unicode %d! Message is not repeated for other unicode " "values.", (int)unicode); } *dest = 0; // paint a box (is 0 a box in MacRoman) or return; // simply skip character } } else { REPORT(kDebug, -1, "macroman srcLen=%d destLen=%d dest= %d %d!", srcLen, destLen, (int)dest[0], (int)dest[1]); } // Note we have to build the user defined encoding before it is used in // PDF_find_font! if (!MakesPDF()) return; int font; GetFontName(&fState->beFont, fontName, embed, encoding); font = FindFont(fontName, embed, encoding); if (font < 0) { REPORT(kWarning, fPage, "**** PDF_findfont(%s) failed, back to default " "font", fontName); font = PDF_findfont(fPdf, "Helvetica", "macroman", 0); } fState->font = font; uint16 face = fState->beFont.Face(); PDF_set_parameter(fPdf, "underline", (face & B_UNDERSCORE_FACE) != 0 ? "true" : "false"); PDF_set_parameter(fPdf, "strikeout", (face & B_STRIKEOUT_FACE) != 0 ? "true" : "false"); PDF_set_value(fPdf, "textrendering", (face & B_OUTLINED_FACE) != 0 ? 1 : 0); PDF_setfont(fPdf, fState->font, scale(fState->beFont.Size())); const float x = tx(fState->penX); const float y = ty(fState->penY); const float rotation = fState->beFont.Rotation(); const bool rotate = rotation != 0.0; if (rotate) { PDF_save(fPdf); PDF_translate(fPdf, x, y); PDF_rotate(fPdf, rotation); PDF_set_text_pos(fPdf, 0, 0); } else PDF_set_text_pos(fPdf, x, y); PDF_show2(fPdf, dest, destLen); if (rotate) { PDF_restore(fPdf); } }