static void setup_fontparameters(PDF pdf, internal_font_number f, int ex_glyph) { float slant, extend, squeeze, expand, scale = 1.0; float u = 1.0; pdfstructure *p = pdf->pstruct; if ((font_format(f) == opentype_format || (font_format(f) == type1_format && font_encodingbytes(f) == 2)) && font_units_per_em(f) > 0) u = font_units_per_em(f) / 1000.0; pdf->f_cur = f; p->f_pdf = pdf_set_font(pdf, f); p->fs.m = i64round(font_size(f) / u / by_one_bp * ten_pow[p->fs.e]); slant = font_slant(f) / 1000.0; extend = font_extend(f) / 1000.0; squeeze = font_squeeze(f) / 1000.0; expand = 1.0 + (ex_glyph/1) / 1000.0; /*tex The |-1| makes less corrections inside |[]TJ|: */ p->tj_delta.e = p->cw.e - 1; /*tex There is no need to be more precise than \TEX\ (1sp). */ while (p->tj_delta.e > 0 && (double) font_size(f) / ten_pow[p->tj_delta.e + e_tj] < 0.5) { /*tex This happens for very tiny fonts. */ p->tj_delta.e--; } p->tm[0].m = i64round(scale * expand * extend * ten_pow[p->tm[0].e]); p->tm[2].m = i64round(slant * ten_pow[p->tm[2].e]); p->tm[3].m = i64round(scale * squeeze * ten_pow[p->tm[3].e]); p->k2 = ten_pow[e_tj + p->cw.e] * scale / (ten_pow[p->pdf.h.e] * pdf2double(p->fs) * pdf2double(p->tm[0])); /*tex We keep track of the state of ex. */ p->cur_ex = ex_glyph ; p->need_width = font_width(f); p->need_mode = font_mode(f); }
int main(int argc, char *argv[]) { struct pdf_info info = {.creator = "My software", .producer = "My software", .title = "My document", .author = "My name", .subject = "My subject"}; struct pdf_doc *pdf = pdf_create(PDF_A4_WIDTH, PDF_A4_HEIGHT, &info); int i; int height; int bm; int err; /* Unused */ (void)argc; (void)argv; if (!pdf) { fprintf(stderr, "Unable to create PDF\n"); return -1; } if (pdf_width(pdf) != PDF_A4_WIDTH || pdf_height(pdf) != PDF_A4_HEIGHT) { fprintf(stderr, "PDF Size mismatch: %dx%d\n", pdf_width(pdf), pdf_height(pdf)); return -1; } i = pdf_get_font_text_width(pdf, "Times-BoldItalic", "foo", 14); if (i < 18) { fprintf(stderr, "Font width invalid: %d\n", i); return -1; } /* These calls should fail, since we haven't added a page yet */ if (pdf_add_ppm(pdf, NULL, 10, 10, 20, 30, "data/teapot.ppm") >= 0) return -1; if (pdf_add_jpeg(pdf, NULL, 100, 500, 50, 150, "data/penguin.jpg") >= 0) return -1; if (pdf_add_text(pdf, NULL, "Page One", 10, 20, 30, PDF_RGB(0xff, 0, 0)) >= 0) return -1; if (pdf_add_bookmark(pdf, NULL, -1, "Another Page") >= 0) return -1; if (!pdf_get_err(pdf, &err)) return -1; pdf_clear_err(pdf); /* From now on, we shouldn't see any errors */ pdf_set_font(pdf, "Times-BoldItalic"); pdf_append_page(pdf); height = pdf_add_text_wrap( pdf, NULL, "This is a great big long string that I hope will wrap properly " "around several lines.\nThere are some odd length " "linesthatincludelongwords to check the justification. " "I've put some embedded line breaks in to " "see how it copes with them. Hopefully it all works properly.\n\n\n" "We even include multiple breaks\n" "thisisanenourmouswordthatwillneverfitandwillhavetobecut", 16, 60, 800, PDF_RGB(0, 0, 0), 300, PDF_ALIGN_JUSTIFY); pdf_add_rectangle(pdf, NULL, 58, 800 + 16, 304, -height, 2, PDF_RGB(0, 0, 0)); pdf_add_ppm(pdf, NULL, 10, 10, 20, 30, "data/teapot.ppm"); pdf_add_jpeg_data(pdf, NULL, 100, 500, 50, 150, data_penguin_jpg, data_penguin_jpg_len); pdf_add_barcode(pdf, NULL, PDF_BARCODE_128A, 50, 300, 200, 50, "Code128", PDF_RGB(0, 0, 0)); pdf_add_barcode(pdf, NULL, PDF_BARCODE_39, 50, 400, 400, 50, "CODE39", PDF_RGB(0, 0, 0)); pdf_add_text(pdf, NULL, "Page One", 10, 20, 30, PDF_RGB(0xff, 0, 0)); pdf_add_text(pdf, NULL, "PjGQji", 18, 20, 130, PDF_RGB(0, 0xff, 0xff)); pdf_add_line(pdf, NULL, 10, 24, 100, 24, 4, PDF_RGB(0xff, 0, 0)); pdf_add_circle(pdf, NULL, 100, 240, 50, 5, PDF_RGB(0xff, 0, 0), PDF_TRANSPARENT); pdf_add_ellipse(pdf, NULL, 100, 240, 40, 30, 2, PDF_RGB(0xff, 0xff, 0), PDF_RGB(0, 0, 0)); pdf_add_rectangle(pdf, NULL, 150, 150, 100, 100, 4, PDF_RGB(0, 0, 0xff)); pdf_add_filled_rectangle(pdf, NULL, 150, 450, 100, 100, 4, PDF_RGB(0, 0xff, 0)); pdf_add_text(pdf, NULL, "This should be transparent", 20, 160, 500, PDF_ARGB(0x80, 0, 0, 0)); int p1X[] = {200, 200, 300, 300}; int p1Y[] = {200, 300, 200, 300}; pdf_add_polygon(pdf, NULL, p1X, p1Y, 4, 4, PDF_RGB(0xaa, 0xff, 0xee)); int p2X[] = {400, 400, 500, 500}; int p2Y[] = {400, 500, 400, 500}; pdf_add_filled_polygon(pdf, NULL, p2X, p2Y, 4, 4, PDF_RGB(0xff, 0x77, 0x77)); pdf_add_text(pdf, NULL, "", 20, 20, 30, PDF_RGB(0, 0, 0)); pdf_add_text(pdf, NULL, "Date (YYYY-MM-DD):", 20, 220, 30, PDF_RGB(0, 0, 0)); pdf_add_bookmark(pdf, NULL, -1, "First page"); pdf_append_page(pdf); pdf_add_text(pdf, NULL, "Page Two", 10, 20, 30, PDF_RGB(0, 0, 0)); pdf_add_text(pdf, NULL, "This is some weird text () \\ # : - Wi-Fi", 10, 50, 60, PDF_RGB(0, 0, 0)); pdf_add_text( pdf, NULL, "Control characters ( ) < > [ ] { } / % \n \r \t \b \f ending", 10, 50, 45, PDF_RGB(0, 0, 0)); pdf_add_text(pdf, NULL, "Special characters: €ÜŽžŠšÁáüöäÄÜÖß", 10, 50, 15, PDF_RGB(0, 0, 0)); pdf_add_text(pdf, NULL, "This one has a new line in it\nThere it was", 10, 50, 80, PDF_RGB(0, 0, 0)); pdf_add_text( pdf, NULL, "This is a really long line that will go off the edge of the screen, " "because it is so long. I like long text. The quick brown fox jumped " "over the lazy dog. The quick brown fox jumped over the lazy dog", 10, 100, 100, PDF_RGB(0, 0, 0)); pdf_set_font(pdf, "Helvetica-Bold"); pdf_add_text( pdf, NULL, "This is a really long line that will go off the edge of the screen, " "because it is so long. I like long text. The quick brown fox jumped " "over the lazy dog. The quick brown fox jumped over the lazy dog", 10, 100, 130, PDF_RGB(0, 0, 0)); pdf_set_font(pdf, "ZapfDingbats"); pdf_add_text( pdf, NULL, "This is a really long line that will go off the edge of the screen, " "because it is so long. I like long text. The quick brown fox jumped " "over the lazy dog. The quick brown fox jumped over the lazy dog", 10, 100, 150, PDF_RGB(0, 0, 0)); pdf_set_font(pdf, "Courier-Bold"); pdf_add_text(pdf, NULL, "(5.6.5) RS232 shutdown", 8, 317, 546, PDF_RGB(0, 0, 0)); pdf_add_text(pdf, NULL, "", 8, 437, 546, PDF_RGB(0, 0, 0)); pdf_add_text(pdf, NULL, "Pass", 8, 567, 556, PDF_RGB(0, 0, 0)); pdf_add_text(pdf, NULL, "(5.6.3) RS485 pins", 8, 317, 556, PDF_RGB(0, 0, 0)); bm = pdf_add_bookmark(pdf, NULL, -1, "Another Page"); bm = pdf_add_bookmark(pdf, NULL, bm, "Another Page again"); pdf_add_bookmark(pdf, NULL, bm, "A child page"); pdf_add_bookmark(pdf, NULL, -1, "Top level again"); pdf_append_page(pdf); pdf_set_font(pdf, "Times-Roman"); for (i = 0; i < 3000; i++) { int xpos = (i / 100) * 40; int ypos = (i % 100) * 10; pdf_add_text(pdf, NULL, "Text blob", 8, xpos, ypos, PDF_RGB(i, (i * 4) & 0xff, (i * 8) & 0xff)); } pdf_add_text(pdf, NULL, "", 10, (i / 100) * 100, (i % 100) * 12, PDF_RGB(0xff, 0, 0)); pdf_append_page(pdf); pdf_page_set_size(pdf, NULL, PDF_A3_HEIGHT, PDF_A3_WIDTH); pdf_add_text(pdf, NULL, "This is an A3 landscape page", 10, 20, 30, PDF_RGB(0xff, 0, 0)); pdf_save(pdf, "output.pdf"); const char *err_str = pdf_get_err(pdf, &err); if (err_str) { fprintf(stderr, "PDF Error: %d - %s\n", err, err_str); pdf_destroy(pdf); return -1; } pdf_destroy(pdf); return 0; }